数据库设计 - 不同类型交易的一张表

Jos*_*ana 5 database-design relational-theory

以采购系统为例。为以下内容使用一个表格是否有意义:报价、订单、发票和贷记凭证?

会有一些不同的细节。例如,每个列表将有其 5 个特殊字段,但另一个说 50 个字段将完全相同。在这种情况下将所有表连接到一个表中是否有意义。并且某些字段未用于某些类型。

我可以看到 Navision 系统在其数据库中执行了类似的操作。它使用一张表,但一旦发布项目,就会拆分为单独的表。我认为这可能是出于性能原因,因为发布的项目往往会变得非常大。& 拆分为单独的表将加快查询速度。但这只是我的想法。

所以我的主要困境是......在这种情况下推荐的方法是什么:1张桌子还是单独的桌子?各自的优缺点是什么?需要考虑哪些业务因素?

谢谢你的帮助!

Kev*_*sel 8

基本上有三个选项(通过三个选项的组合可能会变得复杂):

  1. 将每张桌子分开
  2. 将所有表放在一起作为一个主表
  3. 使用关联关系:具有公共列的基表和用于非公共列的单独表

以下是一些需要考虑的因素:

  • 这些真的代表同一个实体吗?如果是这样,那个实体是什么?根据您的示例(报价单、订单、发票和贷记凭证),这些对我来说是独立的实体。它们是“相关的”,但不是主实体的相同或子类型(例如具有 Employee 表以及具有根本不同属性的 ExemptEmployee 和 NonExemptEmployee 子表)。这倾向于将桌子分开。
  • 您需要查询 Quote UNION Order UNION Invoice 吗?请注意,这不同于将报价加入订单(以获得成功销售的百分比)。如果您确实需要经常执行这些类型的查询,则支持单个表。如果您正在查看“订单的生命周期”,我可以看到这样做。另一方面,即使拆分成多个表,这仍然是一个简单的查询,因此这是一个次要的考虑。
  • 是否存在所有类型不通用的列?您提到每种类型都有几个特殊字段。这意味着您可能无论如何都不想使用选项 #2,因为选项 #3 重新引入了相对简单的完整性约束。假设,在您的大表中,如果您正在执行订单,您需要三列,否则应该为 NULL。使用关联表执行此操作是微不足道的,但需要使用大表方法检查约束。如果订单的 X 列需要是数字,而发票需要是文本,那只会使验证方式更加困难。
  • 你有没有改变类型?不仅仅是将报价数据复制到订单中,而且实际上将报价本身更改为订单。如果是这样,那就是支持一张大桌子的论据。但我认为这不是一个现实的业务流程。
  • 你通常接到多少订单?您获得的订单越多,您就越想拆分这些表。对 X 页的扫描仍然比对 4X 页的扫描更好,并且由于对索引的细粒度控制,单独的表增加了您能够进行搜索而不是扫描的可能性。

基于这些考虑,我个人会将表分开。尽管它们可能具有相似的属性,但它们是根本不同的实体。

然而,我会尝试做的是查看这些公共属性集,看看它们是否真的属于报价单/订单/发票/信用凭证,或者将它们规范化到他们自己的表中是否会更好。例如,如果您有客户名字、客户姓氏、客户街道 1 等,将其拆分为客户键(或客户和地址键,视情况而定)可以减少每个中的列总数四大实体,减少重复并获得正常化的其他好处。

您可能已经最大限度地标准化了所有内容,并且这些实体中的每一个实际上都合法地具有 50 个共同的属性。在那种情况下,我仍然会保留单独的表格,因为您正在谈论恰好彼此相关的根本不同的事物。