如何构建用于搜索后过滤的数据库架构

Jon*_*eir 2 database database-design database-schema data-structures

我想为电子商务搜索功能添加搜索后过滤。目前数据存在如下:

Products(带有 BrandID) Brands(产品表中 BrandID 的外键) ProductDietType(产品和饮食类型的联结表) DietTypes(各种产品饮食类型) ProductDepartment(产品和部门的联结表) 部门

我想添加搜索后过滤器,用户可以选择多个品牌、部门、饮食类型来缩小结果集。

我能想到的就是这样编码:

如果(无)...如果(品牌)...如果(部门)...如果(饮食类型)...如果(品牌和部门)...如果(品牌和饮食类型)...如果(部门和饮食类型) ... 如果(品牌和部门和饮食类型) ...

我知道这是错误的。因为它的可扩展性不太好:每次添加新的过滤器时,代码分支的数量都会增加一倍。

您将如何进行整齐且可扩展的编码 - 因此,如果我想添加另一个过滤器 - 例如原籍国 - 我可以相对轻松地做到这一点。

我使用 C# 进行编码并使用 SQL Server 2008。

非常感谢任何帮助。

乔恩

Tho*_*ner 5

您可以对产品属性使用通用方法。所有可能的过滤条件称为属性(例如“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,那么您将得到:

  • “品牌”(1)
    • “沙拉制作者”(1)
    • “美味佳肴”(2)
  • “饮食类型”(2)
    • “无脂肪”(4)
    • “低碳酸盐”(5)
    • “不含乳糖”(6)
  • “部门”(3)
    • “第一部门”(7)

现在,用户选择品牌=“沙拉制造商”和“饮食类型”=“无脂肪”或“无乳糖”。这使得:

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(品牌 xy 的所有产品)相关联,而其他过滤器则与 AND(所有甜酸产品相关联。

反正你懂这个意思。我不知道您是否认为这适合您正在做的事情。这只是一个想法。正如所说,它有优点,但也有缺点。

您还可以决定采用混合概念(例如:品牌等主要属性保留真实列,而其他属性则转到属性表)。