单表查询是互联网业务中常用的手段.引入单表查询后,数据库负责简单读取数据,应用需要解决如何将查询落到核心表上!
现有三张表:
品牌表t_brand(brand_name,brand_code),
类目表t_category(cat_name,cat_code),
产品表为t_product(product_name,product_code,brand_code,cat_code)
需要实现接口需求为:支持通过 品牌名称,类目名称和产品编号进行查询产品。
按照传统的解决方式:
select p.product_name,product_code from t_product p
join t_brand b on p.brand_code=b.brand_code
join t_catgory c on p.cat_code = c.cat_code
where b. brand_name like '%${品牌名称}%'
and c.cat_name like '%${类目名称}%'
and p.product_code = '${产品编号}'
这种方式的优点;开发效率高,迅速支撑业务。但是随着业务的发展,数据库的数据量增加大,join的代价越来越大,数据库的缓存使用率底下。为了解决这些问题,通常引入单表查询的方式来解决问题.
sql变成了:
select brand_code from t_brand where brand_name like '%${品牌名称}%';
select cat_code from t_brand where cat_name like '%${类目名称}%';
select product_name,product_code from t_product
where brand_code in ('${brandCode}')
and cat_code in ('${catCode}')
and product_code = '${产品编号}';
业务是不断发展的,为了解决产品表的单维度的查询,决定引入tag表,帮助运营进行多维度的检索.tag表t_tag(tag_code,tag_name),t_tag_product(id,tag_code,product_code)
需要实现接口需求为:支持通过品牌名称,类目名称,产品编号和标签编号 进行查询产品信息
sql又变成:
select brand_code from t_brand where brand_name like '%${品牌名称}%';
select cat_code from t_brand where cat_name like '%${类目名称}%';
select product_code from t_tag_product where tag_code = '${标签编号}';
select product_name,product_code from t_product where brand_code in ('${brandCode}') and cat_code in ('${catCode}') and product_code = '${产品编号}' and product_code in('${通过tagCode找到productCode}')
但是sql查询时时有问题,比如:
1.如果产品编号与${通过tagCode找到productCode} 没有交集,就不用浪费一次sql查询,直接在应用层拦截返回。
2.如果再增加一张新表sku(sku_code,product_code),同时更新接口的需求为:
支持通过品牌名称,类目名称,产品编号,标签编号,sku编号查询产品信息。其sql也会越来越复杂。
select product_name,product_code from t_product
where brand_code in ('${brandCode}')
and cat_code in ('${catCode}')
and product_code = '${产品编号}'
and product_code in('${通过tagCode找到productCode}')
and product_code in('${通过skuCode找到productCode}')
很明显,需要一个在应用层对productCode进行合并,并过滤无效的productCode的工具。
这样的工具,需要解决几个问题:
1.将t_product设为主表,因为最终接口返回的产品信息,其他表设置为辅助表,用于辅助查询。
2.判断用户传递的辅助字段,这些条件能否查询到productCode,并将合并为supportProductCodes。
3.处理masterProductCode与supportProductCodes的关系,判断什么时候应该拦截sql,什么时候应该合并。
有了这个工具后,sql再次得到简化
select brand_code from t_brand where brand_name like '%xx%';
select cat_code from t_brand where cat_name like '%xx%';
select product_code from t_tag_product where tag_code = 'power';
select product_code from t_sku where sku_code = '{sku编号}'
select product_name,product_code from t_product where brand_code in ('brandcode') and cat_code in ('cat_code') and and product_code in('{合并后的productCode}')