【问题标题】:How should I set up database tables for this order situation我应该如何为这种订单情况设置数据库表
【发布时间】:2012-03-24 09:37:08
【问题描述】:

我正在为一家印刷公司构建一个 Web 应用程序,并试图为我的数据库确定最佳设计。

我有一个orders 表。每个order 都有很多证明。但是,有两种不同的证明:电子证明和物理证明。此外,如果是电子证明,我需要存储图像源,如果是物理证明,我需要存储跟踪号。

每个证明都有许多与之关联的 cmets。

如果我只有一张proofs 表和一张comments 表就好了,但是根据证明类型跟踪图像来源和跟踪号的最佳方法是什么?

我考虑过为electronic_proofsphysical_proofs 创建单独的表,但这需要单独创建electronic_proof_comments 表和physical_proof_comments 表。

另一种选择是拥有一个proofs 表,在这种情况下,我可以拥有一个comments 表。但是,在我看来,这需要三个支持表,proof_typesimage_sourcestracking_numbers

对解决此问题的最佳方法或更好的方法有什么想法吗?

【问题讨论】:

  • 引用:“我考虑过为electronic_proofs 和physical_proofs 创建单独的表,但这需要单独的electronic_proof_cmets 表和physical_proof_cmets 表。”为什么不这样做?似乎是最简单的解决方案 imo。
  • @Msonic:你可以使用polymorphic association
  • @Msonic 似乎有更好的方法可以解决这个问题。我觉得这样做会因为需要大量表而变得过于混乱

标签: sql ruby-on-rails database database-design database-schema


【解决方案1】:

正如另一个答案中提到的,您只需要一个表格,并且只需将其中一个字段留空,具体取决于类型。但是,我的答案的不同之处在于将订单详细信息与证明相关联,而不是将证明与订单详细信息(或他们的示例中的订单项目)相关联。这样做可以让您为每个订单详细信息提供多个证明。

如果我是你,我会这样设置:

订单

  • 订单 ID (PK)
  • 客户 ID (FK)
  • 等等……

订单详情

  • OrderDetailsID (PK)
  • 订单 ID (FK)
  • 产品ID? (FK)
  • 等等……

证明

  • ProofID (PK)
  • OrderDetailsID (FK)
  • 证明类型
  • ImagePath(只是路径,不是图像)
  • 跟踪编号
  • 等等……

评论

  • 评论 ID (PK)
  • ProofID (FK)
  • 评论
  • 等等……

将 ProofType 分解到它自己的表中可能也是明智的,但没有它也可以工作。如果您要这样做,您需要创建一个 ProofType 表并将“Proofs”表中的“ProofType”字段更改为引用新“ProofType”表中“ProofTypeID”字段的外键。

希望这会有所帮助!祝你好运!

【讨论】:

  • 如果您在“订单详细信息”表中包含证明 ID,则您已经拥有多对多关系。无需在证明表中包含订单详细信息 ID。
  • 但正如我在回答的评论中所说,如果真正的关系是 3 级(订单 > 行 > 证明),那么这将是一个更好的解决方案。
  • 据我了解,这将是 3 级,这对于印刷公司来说很常见。订单表将保存一般订单信息。订单详细信息将包含不同的项目(名片、传单、明信片)及其属性。然后每个人都可以有多个证明。
  • 它是 3 级的,这看起来是一个不错的解决方案。感谢您的输入。我们将使用此架构。
【解决方案2】:

我同意@Ricketts (+1)。棘手的部分是是否在 Proof 表中包含列 ImagePathTrackingNumber,或者将它们规范化到单独的表中。 (归一化,因为它们不依赖于主键,它们依赖于主键 + 证明类型列。)如果只有这两列是特定于证明类型的列,那么您可能是 可以将它们存储在单个表中......但是 ImagePath 让我感到紧张,特别是如果它不是图像而是实际相当大的二进制数据块。出于多种原因,将这些数据单独存储在自己的表中可能是有意义的,但也不能将 TrackingNumber 移出。

其他注意事项:证明类型之间的比例是多少?性能如何发挥作用(尤其是在您的数据请求中涉及 BLOB 的情况下?)在做出最终决定之前,您必须权衡并可能测试这些考虑因素。

【讨论】:

  • 在我的示例中,我建议他不要将二进制数据存储在数据库本身中。我拥有一家印刷设计和网络开发(显然)公司,我们与很多打印机打交道。我见过的每台打印机都提供 PDF 或 JPG 格式的校样。我对他的建议是,证明文档存储在服务器的文件系统中,并且该文档的路径存储在 ImagePath 中(可能会更好地命名为 DocPath)。然后在他们的应用程序中,他们只需引用证明的路径,而不是解析二进制数据本身。
  • 我可不想靠近那个——在 SO 上肯定有几十个关于这个主题的问题,而且很少有非黑即白的答案。 (基本问题:如果数据库有一个文件路径,但无论出于何种原因,在那里找不到文件,那会怎样?)或者,您是否曾经使用过 Filestream 数据类型?我还没有。
  • 我们确实实现了@Ricketts 解决方案,但我们也决定将TrackingNumberImagePath 规范化到单独的表中。我们也只存储图像路径。感谢您的意见 (+1)。
【解决方案3】:

我希望证明类型只是商品的一个属性,跟踪号和图片来源也是如此,对吗?

这类似于某些项目可能有大小,但有些没有 - 您只是不填充与该特定类型的项目无关的属性。

另外,请注意,使用两个不同的“证明”表,您的订单行项目表现在必须处理两个不同的实体。

这样的东西对于基本用途应该是可行的......

ORDERS
 Order ID (PK)

ORDER ITEM
 Order Item ID (PK)
 Order ID (FK)
 Proof ID (FK)

PROOF
 Proof ID (PK)
 Proof Name
 Proof Type
 Tracking Number
 Image Source

COMMENTS
 Comment ID (PK)
 Proof ID (FK)
 Comment Text

如有必要,您可以为证明类型、跟踪号和图像来源创建查找表。这真的取决于你想在多大程度上将现实与关系理论相匹配。

【讨论】:

  • 这不允许订单商品有很多证明,我需要能够这样做
  • 是的。您的 ORDER ITEM 表是 ORDERS 表和 PROOF 表之间的多对多关系。
  • 除非您实际上具有 3 级关系 - 每个订单都有许多订单项目(或“订购的产品”等),那么每个“订购的产品”都由多个证明组成。您的问题意味着每个 order 都有多个证明,而不是每个订单项。
  • 我明白了。我应该更具描述性。很抱歉问题的混淆,但我确实有一个 3 级的关系,就像你刚才描述的情况
猜你喜欢
  • 2013-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-18
  • 1970-01-01
  • 2021-07-18
  • 2012-02-17
相关资源
最近更新 更多