可分组实体的数据库/应用程序设计

时间:2016-05-25 00:28:32

标签: sql-server database database-design architecture

只想询问有关以下方案的最佳数据库/应用程序设计的输入

  1. 我有一张名为computers
  2. 的表格
  3. 每个产品可按以下方式分组:
    • vendor(例如'Sony','Apple','HP'),
    • type(例如'笔记本电脑','个人桌面','服务器')
    • size(例如'小','中','大')`
    • 随着业务需求的变化(未来可能会touchscreen
    • ,还会有更多的事情发生
  4. 这些计算机可以分组到某些repairers
    • 'PC Repairers'可修复小型personal desktopssmall laptops
    • 'Better Computers'可以修复all Sony computers
    • '免费修复'可修复all HP servers,但不能修复large
  5. 正如您所看到的那样,事情可能会重叠
    • 小型索尼笔记本电脑可以通过'PC Repairers'和'Better Computers'来修复
  6. 这种数据库设计的术语是什么?我甚至不知道如何在网上搜索

    很想听听你的回答!

    由于

1 个答案:

答案 0 :(得分:1)

我不知道你所描述的那种设计的名称。我可以称之为基于特征的关联。

如果您的规则仅要求功能子集相等,则可以使用以下模式来实现它:

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表将用于将维修人员与他们可以修复的计算机类相关联。请注意,它不处理排除项(例如“所有HP服务器但不是大型服务器”),仅包含内容(例如“小型HP服务器”和“中型HP服务器”)。

如何查询给定计算机的所有修补程序的示例:

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

请注意,这只是一个概念证明。在现实世界中,我会记录供应商密钥而不是名称,并将供应商和维修者表示为组织的子类型。我还会为每个功能而不是varchars使用枚举或查找表。

修改:您可以轻松地向模型中添加排除项。添加表格:

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