【问题标题】:How do I properly design a database schema for this scenario如何为这种情况正确设计数据库架构
【发布时间】:2013-06-03 19:07:23
【问题描述】:

假设我拥有一家销售汽车和摩托车的公司。我想跟踪每个数据。我公司为每辆车提供免费保修,但我们甚至不为摩托车提供保修。最初,我以为我应该有两张表格——一张“车辆”表格和一张“保修”表格,就像这样

Vehicles                                                     Warranties

VehicleID, SalePrice, VehicleType, WarrantyID                WarrantyID, EffDate, ExpDate

其中 VehicleType 是“汽车”或“摩托车”。我的缺点是,在 Vehicles 表中,每辆摩托车的“WarrantyID”都有一个空值。这会被认为是不好的做法吗?

我考虑过的另一种方法是使用三个表格,例如

Cars                                                         Motorcycles

VehicleID, SalePrice, WarrantyID                             Vehicle ID, SalePrice


Warranties

WarrantyID, EffDate, ExpDate

我的缺点是我将摩托车和汽车分成两张几乎相同的桌子。 (实际上,他们会有更多的字段,如购买成本、里程等)。唯一的区别是所有汽车都有保修,没有摩托车有保修。

(注意:我还假设 2 或 3 辆车可以共享一个保修。)

建立这个数据库的正确方法是什么?

【问题讨论】:

  • 我认为第一种方法很好。如果车辆没有,只需将warrantyid 留空即可。您没有违反任何规范化规则。
  • 你为什么要假设不止一辆汽车可以有相同的保修?
  • 您说:“我还假设 2 或 3 辆车可以共享一个保修。”。反之亦然吗?一辆车可以有多个保修吗?
  • 我真的在为工人补偿提供者设计一个数据库。我们有一个复杂的免赔额和保证成本政策系统。这很难解释,所以我试图提出一个更有意义的类比。
  • 一辆车不能有多个保修。

标签: sql database database-design


【解决方案1】:

将摩托车和汽车存放在同一张桌子上。

当属性与给定行中的数据类型不相关时,允许列为 NULL 是完全正常的。 NULL 表示“未知、缺失或不适用的数据”。

【讨论】:

    【解决方案2】:

    听起来你可以考虑一个连接表。

    Vehicle              VehicleWarranty          Warranty
    ---------            ---------------          ----------
    VehicleId            VehicleId                WarrantyId
    SalePrice            WarrantyId               EffectiveDate
    

    这样,您的 Vehicle 表中没有保修 ID,因此您不必处理空值。如果您对车辆有保修,则保修表(和 VehicleWarranty 表)中只有一个条目。此外,连接表允许您将相同的保修附加到多辆车,或将同一辆车附加到多个保修。

    【讨论】:

    • “连接表允许您将相同的保修附加到多辆汽车,或将同一辆车附加到多个保修。”由于这似乎违反了要求,因此实际上是这种方法的一个弱点。
    • 来自 OP:“(注意:我还假设 2 或 3 辆车可以共享一个保修。)”所以这实际上是一个要求。
    • 没错,不用一车多保。
    • 您可能还想要一个车辆类型表。这将给出第三个正常值。
    • @BenGorman 如果您想支持多对多关系,即多辆车对 1 个保修,或 1 辆车有多个保修,您应该采用这种方法。如果您从不希望一辆车有多个保修,但多辆车可以共享一份保修,那么正确的解决方案是比尔的。并添加一个车辆类型表(vehicetypeid in 车辆表)。这将帮助您符合 3NF,有助于提高数据质量并减少磁盘空间。
    【解决方案3】:

    没有合适的方法,两种方法都有效。这取决于业务的全部内容。

    它是关于车辆的吗,即应用程序中的很多东西都处理车辆,而不关心它是汽车还是摩托车,那么你可能想要一张桌子。

    但如果大多数业务只处理一个或另一个而不是两者,则完全有可能有单独的表,可能有一个将两者结合起来的视图。

    【讨论】:

      【解决方案4】:

      这取决于您在桌子上的用途。

      如果您要查询混合车辆列表,那么您应该选择第一个模型。

      但如果你不打算混合它们,你可以使用第二个。

      我会选择第一个,因为它可以让您在未来为自行车提供保修。

      【讨论】:

        【解决方案5】:

        如果某些车辆的保修是可选的,并且您的假设不是必需的,您可以将 FK 放在保修表中。以下还假设车辆和保修(如果存在)之间存在一对一的关系。

        Vehicle              Warranty
        ---------            ---------------
        VehicleId            VehicleId
        SalePrice            EffectiveDate
        

        缺点是您必须支付外部连接或查询保修的费用才能确定车辆是否配备。

        如果不了解您的查询模式,很难判断什么是最好的。

        【讨论】:

          猜你喜欢
          • 2013-03-14
          • 2011-05-18
          • 1970-01-01
          • 2016-05-23
          • 2012-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多