【问题标题】:Do these database design styles (or anti-pattern) have names?这些数据库设计风格(或反模式)有名称吗?
【发布时间】:2009-06-05 09:20:32
【问题描述】:

考虑一个包含表 Products 和Employees 的数据库。对当前的产品经理进行建模有一项新要求,即作为负责产品的唯一员工,并指出有些产品足够简单或成熟,不需要产品经理。也就是说,每个产品可以有零个或一个产品经理。

方法 1:更改表 Product 以添加一个新的 NULLable 列 product_manager_employee_ID,这样没有产品经理的产品将由 NULL 值建模。

方法 2:创建一个新表ProductManagers,其中包含非NULLable 列product_IDemployee_ID,对product_ID 具有唯一约束,因此没有产品经理的产品由此表中没有一行。

还有其他方法,但这是我最常遇到的两种。

假设这些都是合法的设计选择(我倾向于相信)并且仅仅代表不同的风格,他们有名字吗?我更喜欢方法 2,并且发现很难在不使用实际示例的情况下向喜欢方法 1 的人传达风格上的差异(就像我在这里所做的那样!)如果我可以说,“我更喜欢inclination-towards-6NF(或其他)风格。”

假设其中一种方法实际上是一种反模式(我只是怀疑方法 1 的情况可能是通过将两个实体之间的关系建模为其中一个实体的属性)这种反模式是否具有名字?

【问题讨论】:

    标签: sql design-patterns database-design anti-patterns


    【解决方案1】:

    第一个只不过是一对多的关系(一个员工对多个产品)。这有时被称为 O:M 关系(零对多),因为它是可选的(并非每个产品都有产品经理)。也不是每个员工都是产品经理,所以另一方面也是可选的。

    第二个是连接表,通常用于多对多关系。但由于一侧只是一对一的(每个产品只在表中出现一次),它实际上只是一个复杂的一对多关系。

    我个人更喜欢第一个,但都没有错(或不好)。

    我想到第二个原因有两个。

    1. 您设想一种产品可能有多个经理;或
    2. 您想要跟踪产品经理的历史记录。您可以使用设置为“Y”(或类似)的 current_flag 列来执行此操作,其中一次只能有一个是当前的。这实际上是以数据库为中心的应用程序中非常常见的模式。

    【讨论】:

      【解决方案2】:

      在我看来,这两个模型的行为不同。在第一个示例中,您可以为每个产品配备一名产品经理,一名员工可以担任多个产品的产品经理(一对多)。第二种似乎允许每个产品有多个产品经理(多对多)。这表明这两种解决方案在不同情况下同样有效,您使用哪一种取决于业务规则。

      【讨论】:

      • 公平点,但我不希望它看起来那样。我现在已经厌倦了编辑以澄清我的意图,即每个产品将有零个或一个产品经理(我认为,对于方法 2,这仅需要对产品经理 ID 进行唯一约束)。
      【解决方案3】:

      第一种方法存在缺陷。想象一下,业务需求发生了变化,现在您需要能够为产品设置 2 个产品经理。你会怎么做?将另一列添加到表产品?呸。那么这显然违反了 1NF。

      第二种方法提供的另一个选项是能够为某个产品经理 产品关系存储一些属性。就像,如果您有两个产品经理,那么您可以将其中一个设置为主要... 或者,例如,员工可以有一个电话号码,但作为产品经理,他/她可以有另一个电话号码……这也将进入特殊表。

      【讨论】:

      • 我隐含地应用了 YAGNI 原则 (en.wikipedia.org/wiki/You_Ain%27t_Gonna_Need_It)。虽然我同意考虑未来的维护并没有什么坏处,但我认为这两种方法都满足当前的要求,因此是可以接受的(并且不会说其中一种是“有缺陷的”)。
      • 当然,就解决这个特殊问题而言,它们是“可以接受的”。但是第一个看起来更像是一种快速破解,而不是“设计模式”。 YAGNI 原则也不是“黄金法则”,我会说“需求变更”规则是需要考虑的更多因素。
      • 我认为为 1:M 关系引入关系表会混淆系统的实际用途。在一般情况下,外键(NOT 关系表)是 1:M 关系的公认最佳实践解决方案。在这种情况下,这似乎是一种快速破解,因为某些产品可能有多个经理是非常合理的。
      【解决方案4】:

      方法 1)

      1. 减慢使用带有附加产品经理字段的产品表(可能不是针对所有数据库,而是针对某些数据库)。
      2. 从 Product 表链接到 Employee 表很简单。

      方法 2)

      1. 使用 Product 表的现有查询不受影响。
      2. 增加数据库的大小。您现在已将 Product ID 列复制到另一个表,并为该表添加了唯一约束和索引。
      3. 从 Product 表链接到 Employee 表更加麻烦和昂贵,因为您必须先对中间表进行墨迹。

      您必须多久在两个表之间链接一次?

      还有多少其他查询使用 Product 表?

      Product 表中有多少条记录?

      【讨论】:

      • “增加数据库的大小。您现在已将 Product ID 列复制到另一个表,并为该表添加了唯一约束和索引”——这是您的另一个应该被限定的与“也许不是针对所有数据库,而是针对某些数据库”。这是一个设计问题,而不是实现:我当然计划将整个事情非规范化为一个巨大的电子表格 :) 但感谢您对这两种方法的思考。
      【解决方案5】:

      在您给出的特定情况下,我认为两个表的主要动机是避免丢失数据的空值,这就是我将描述这两种方法的方式。

      有一个利弊的讨论on wikipedia

      我很确定,鉴于 c date 不喜欢这一点,他定义了关系理论,因此只有多表解决方案是“有效的”。例如,您可以将单表方法称为“类型不佳”(因为 null 的类型是 unclear - 请参阅 p4 上的引用)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-09-09
        • 1970-01-01
        • 2021-06-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多