【问题标题】:Database design - single subtype in a separate table vs common table [closed]数据库设计 - 单独表中的单个子类型与公用表 [关闭]
【发布时间】:2021-12-24 17:03:15
【问题描述】:

在一个送餐应用中,我有一个 USERS 表,其中包含有关用户数据的信息,例如名字、姓氏、电子邮件、密码等。

一小部分用户(约占所有用户的 1%)将分配有派送员角色。这意味着会有一些送货人特定的数据,例如驾驶执照 ID、average_rating 等等。

我不确定哪个更好:拥有一个包含所有数据的 USERS 表(这意味着对于大多数用户而言,送货员特定列将为空)或具有子类型表(@ 987654325@) 将保存这些列和USERS 表的外键?

选项#1

用户:

  • id(PK)
  • 电子邮件
  • 密码
  • 名称 ...
  • driver_license_id(所有普通用户为空)
  • avg_rating(所有普通用户为空)
  • 更多送货人特定列

选项#2

用户:

  • id(PK)
  • 电子邮件
  • 密码
  • 姓名

DELIVERY_PERSON

  • id(PK、FK 到 USERS.id)
  • driver_license_id
  • avg_rating
  • 更多送货人特定列

我在 SO 上看到了几个类似的问题,但在所有这些问题中都有多个子类型,例如 Vehicle -> Car/Airplane/Boat 等。

在我的场景中,只有一种基本类型(用户)和一种可能的扩展子类型(送货员)。我想知道是否只有一种可能的子类型会以某种方式影响选择哪个选项。

【问题讨论】:

  • 这可能被认为主要是基于意见的,但在你的情况下,我可能会使用一个单独的表,因为你可能希望将某些对用户的引用仅限于送货司机,这是附加表会方便。例如在您想要存储送货司机 ID 的订单上,您希望将其作为 DELIVERY_PERSON 而不是 USERS 的 FK,因为只有送货员才能交付订单
  • 子类型的另一个好处是它可以更直接地执行所需的数据。即如果送货司机必须有驾驶执照号码,那么您可以在子表中使该列不可为空,如果您只使用一个表您必须使用检查约束,这不是世界末日,但我认为非空列更透明
  • 顺便说一句,列包含 99% 的空值并没有真正的问题,只需将它们定义为 Sparse Columns,所以这不应该是决定的重要因素,所以如果您提出单表解决方案的所有其他原因(正如我所说,在这种情况下不太可能,但在其他情况下可能),那么拥有 99% 的空值并不一定会将您推向子表方法

标签: sql sql-server database-design


【解决方案1】:

在我看来,子类型的“干净”实现是为每个子类型创建一个单独的表,为超类型创建一个公共表。 这避免了复杂的完整性条件并减少了空值的数量。

为了说明复杂的完整性条件是如何产生的,假设您有一个超类型和一个子类型,其中包含 10 个额外的强制属性(“列”)和几个可选属性。 现在,如果单个可选属性不为空,那么 10 个额外的强制属性也必须为非空。 如果您想象自己有 12 种亚型而不是只有一种,情况会变得更糟。

另一方面,如果您将所有内容存储在一个表中,则不必执行连接。如果您经常需要额外的列,这是一个性能优势。 当然,这只是部分正确。如果您有许多子类型,则行会很长。这会降低数据缓存的有效性。

如果您的应用程序不经常需要附加信息,最好为附加列保留一个单独的表。如果它一直需要所有信息,那么最好使用一个包含所有内容的表。

简而言之:您的问题没有通用答案。 最好的方法是根据您的应用程序和我的考虑进行猜测。然后你实现它并测试你的实现的性能是否满足你的要求。如果是这样,您有一个有效的实现。如果没有,请尝试其他策略。

【讨论】:

  • 关于强制/可选列的可能问题的段落最吸引我。我也不太担心性能问题,因为我预计数据库不会增长太多。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-19
  • 1970-01-01
  • 2010-11-13
  • 2015-02-15
  • 2011-02-15
  • 1970-01-01
相关资源
最近更新 更多