Jon*_*eir 2 database database-design database-schema data-structures
我想为电子商务搜索功能添加搜索后过滤。目前数据存在如下:
Products(带有 BrandID) Brands(产品表中 BrandID 的外键) ProductDietType(产品和饮食类型的联结表) DietTypes(各种产品饮食类型) ProductDepartment(产品和部门的联结表) 部门
我想添加搜索后过滤器,用户可以选择多个品牌、部门、饮食类型来缩小结果集。
我能想到的就是这样编码:
如果(无)...如果(品牌)...如果(部门)...如果(饮食类型)...如果(品牌和部门)...如果(品牌和饮食类型)...如果(部门和饮食类型) ... 如果(品牌和部门和饮食类型) ...
我知道这是错误的。因为它的可扩展性不太好:每次添加新的过滤器时,代码分支的数量都会增加一倍。
您将如何进行整齐且可扩展的编码 - 因此,如果我想添加另一个过滤器 - 例如原籍国 - 我可以相对轻松地做到这一点。
我使用 C# 进行编码并使用 SQL Server 2008。
非常感谢任何帮助。
乔恩
您可以对产品属性使用通用方法。所有可能的过滤条件称为属性(例如“Department #1”),并按属性类型(例如“Departments”)分组。
这种模式有优点也有缺点。例如:当品牌只是这些属性之一时,如何保证产品完全属于一个品牌?这是该模型的消极方面。最积极的方面是:无论你谈论产品的品牌、饮食类型、部门还是其他什么,它们都只是你可以过滤的产品属性。添加更多属性很容易,而无需更改过滤器代码。
表属性类型
编号 | 文本 1 | '品牌' 2 | “饮食类型” 3 | '部门'
表属性
编号 | id_attribute_type | id_attribute_type | 文本 1 | 1 | “沙拉制造商” 2 | 1 | “美味的食物” 3 | 1 | “美味佳肴” 4 | 2 | “没有脂肪” 5 | 2 | '低碳水化合物' 6 | 2 | “不含乳糖” 7 | 3 | '部门 1' 8 | 4 | “2部”
表product_attribute
id_产品 | id_属性 1 | 1 1 | 4 1 | 5 1 | 7 2 | 2 2 | 4 2 | 6 2 | 7
假设您选择标题中带有绿色一词的所有产品:
select * from products where upper(name) like '%GREEN%';
Run Code Online (Sandbox Code Playgroud)
此外,您还需要与所选产品关联的所有过滤器:
select at.id as at_id, at.text as at_text, a.id as a_id, a.text as a_text
from product_attribute pa
join attribute a on a.id = pa.id_attribute
join attribute_type at on at.id = a.id_attribute_type
where pa.id_product in (select id from products where upper(name) like '%GREEN%');
Run Code Online (Sandbox Code Playgroud)
如果“绿色”产品恰好是产品 1 和 2,那么您将得到:
现在,用户选择品牌=“沙拉制造商”和“饮食类型”=“无脂肪”或“无乳糖”。这使得:
select *
from products
where upper(name) like '%GREEN%'
and id in
(
select id_product
from product_attribute
group by id_product
having sum(case when id_attribute in (1) then 1 end) > 0 criteria for Brand
and sum(case when id_attribute in (4,6) then 1 end) > 0 -- criteria for Diet type
);
Run Code Online (Sandbox Code Playgroud)
您只需为每个使用的属性类型(此处为 1 个品牌和 2 个饮食类型)添加一个条件行以及包含所选属性的 IN 子句即可创建此类查询。
这样的模型可以变得更加复杂。例如,您可能会将某些过滤器与 OR(品牌 x或y 的所有产品)相关联,而其他过滤器则与 AND(所有甜酸产品)相关联。
反正你懂这个意思。我不知道您是否认为这适合您正在做的事情。这只是一个想法。正如所说,它有优点,但也有缺点。
您还可以决定采用混合概念(例如:品牌等主要属性保留真实列,而其他属性则转到属性表)。