Database/Application 可分组实体的设计
Database/Application Design for Group-able Entity
只是想问一下以下场景的最佳database/application设计
- 我有一个 table 叫
computers
- 每个产品都可以按以下方式分组:
vendor
(例如'Sony'、'Apple'、'HP')、
type
(例如'laptop'、'personal desktop'、'server')
size
(例如 'small'、'medium'、'large')`
- 随着业务需求的变化(可能
touchscreen
在未来)
- 这些计算机可以分组到某些
repairers
时
- 'PC Repairers'可以修复小的
personal desktops
和small laptops
- 'Better Computers'可以修复
all Sony computers
- 'Repair for Less' 可以修复
all HP servers
但不能修复 large
- 如您所见,有些东西可能会重叠
- 'PC Repairers' 和 'Better Computers'
都可以修复小型索尼笔记本电脑
这种数据库设计的术语是什么?我什至不知道如何在线搜索它
很想听听您的回答!
谢谢
我不知道您所描述的那种设计的名称。我可以称之为基于特征的关联。
如果您的规则只要求特征子集相等,您可以使用以下架构来实现它:
computers (id PK, vendor, type, size)
repairers (id PK, name)
can_repair (id PK, repairer_id FK, vendor NULL, type NULL, size NULL)
can_repair
table 将用于将维修人员与他们可以维修的 类 台计算机相关联。请注意,它不处理排除项(例如 "all HP servers but not the large"),仅处理包含项(例如 "small HP servers" 和 "medium HP servers")。
如何查询给定计算机的所有维修人员的示例:
SELECT DISTINCTROW r.*
FROM computers c
INNER JOIN can_repair cr
ON COALESCE(cr.vendor, c.vendor) = c.vendor
AND COALESCE(cr.type, c.type) = c.type
AND COALESCE(cr.size, c.size) = c.size
INNER JOIN repairers r ON cr.repairer_id = r.id
WHERE c.id = 123
这里有一个SQL Fiddle来演示。
请注意,这只是概念验证。在现实世界中,我会记录供应商密钥而不是名称,并将供应商和维修商表示为组织的子类型。我还会为每个功能使用枚举或查找 tables 而不是 varchars。
编辑:您可以轻松地向模型添加排除项。添加一个table:
cant_repair (id PK, repairer_id FK, vendor NULL, type NULL, size NULL)
然后像这样修改查询:
SELECT DISTINCTROW r.*
FROM computers c
INNER JOIN can_repair cr
ON COALESCE(cr.vendor, c.vendor) = c.vendor
AND COALESCE(cr.type, c.type) = c.type
AND COALESCE(cr.size, c.size) = c.size
INNER JOIN repairers r ON cr.repairer_id = r.id
LEFT JOIN cant_repair xr
ON xr.repairer_id = r.id
AND COALESCE(xr.vendor, c.vendor) = c.vendor
AND COALESCE(xr.type, c.type) = c.type
AND COALESCE(xr.size, c.size) = c.size
WHERE c.id = 123 AND xr.id IS NULL
只是想问一下以下场景的最佳database/application设计
- 我有一个 table 叫
computers
- 每个产品都可以按以下方式分组:
vendor
(例如'Sony'、'Apple'、'HP')、type
(例如'laptop'、'personal desktop'、'server')size
(例如 'small'、'medium'、'large')`- 随着业务需求的变化(可能
touchscreen
在未来)
- 这些计算机可以分组到某些
repairers
时- 'PC Repairers'可以修复小的
personal desktops
和small laptops
- 'Better Computers'可以修复
all Sony computers
- 'Repair for Less' 可以修复
all HP servers
但不能修复large
- 'PC Repairers'可以修复小的
- 如您所见,有些东西可能会重叠
- 'PC Repairers' 和 'Better Computers' 都可以修复小型索尼笔记本电脑
这种数据库设计的术语是什么?我什至不知道如何在线搜索它
很想听听您的回答!
谢谢
我不知道您所描述的那种设计的名称。我可以称之为基于特征的关联。
如果您的规则只要求特征子集相等,您可以使用以下架构来实现它:
computers (id PK, vendor, type, size)
repairers (id PK, name)
can_repair (id PK, repairer_id FK, vendor NULL, type NULL, size NULL)
can_repair
table 将用于将维修人员与他们可以维修的 类 台计算机相关联。请注意,它不处理排除项(例如 "all HP servers but not the large"),仅处理包含项(例如 "small HP servers" 和 "medium HP servers")。
如何查询给定计算机的所有维修人员的示例:
SELECT DISTINCTROW r.*
FROM computers c
INNER JOIN can_repair cr
ON COALESCE(cr.vendor, c.vendor) = c.vendor
AND COALESCE(cr.type, c.type) = c.type
AND COALESCE(cr.size, c.size) = c.size
INNER JOIN repairers r ON cr.repairer_id = r.id
WHERE c.id = 123
这里有一个SQL Fiddle来演示。
请注意,这只是概念验证。在现实世界中,我会记录供应商密钥而不是名称,并将供应商和维修商表示为组织的子类型。我还会为每个功能使用枚举或查找 tables 而不是 varchars。
编辑:您可以轻松地向模型添加排除项。添加一个table:
cant_repair (id PK, repairer_id FK, vendor NULL, type NULL, size NULL)
然后像这样修改查询:
SELECT DISTINCTROW r.*
FROM computers c
INNER JOIN can_repair cr
ON COALESCE(cr.vendor, c.vendor) = c.vendor
AND COALESCE(cr.type, c.type) = c.type
AND COALESCE(cr.size, c.size) = c.size
INNER JOIN repairers r ON cr.repairer_id = r.id
LEFT JOIN cant_repair xr
ON xr.repairer_id = r.id
AND COALESCE(xr.vendor, c.vendor) = c.vendor
AND COALESCE(xr.type, c.type) = c.type
AND COALESCE(xr.size, c.size) = c.size
WHERE c.id = 123 AND xr.id IS NULL