【问题标题】:Database design issue - trying to avoid circular reference数据库设计问题 - 试图避免循环引用
【发布时间】:2011-06-15 16:44:05
【问题描述】:

我已经研究了一天又一天,试图找出如何为我正在为拥有面包店的朋友开发的应用程序最好地为数据库 (MySQL) 建模。假设如下:

  • 许多(外部)Bakers 产生许多 Products
  • BakersProducts 由某些员工每两周更新一次,他们要么打电话给面包师询问他们的产品价格,要么面包师自己传真通过他们的价目表,然后工作人员通过前端 UI 更新。
  • 经理应该能够根据她预期拥有的产品生成订单。

因此,前端 UI 必须能够让经理在订单中纯粹选择她想要的产品,然后向她提供一份面包师列表,供她为订单中的每种产品进行选择。

换句话说,Orders_has_Products 还应该包含对BakersProducts.bpID 的引用。我敢肯定,如果我这样做,那么我会创建一个循环引用(排序)Products

我确定我的做法是错误的,并且非常感谢任何人对我如何重组我的设计以适应所选产品价格的建议 - 即。包括BakersProducts.bpID

谢谢!

【问题讨论】:

  • 这里的循环引用不太清楚。

标签: mysql database-design circular-reference


【解决方案1】:

解决此问题的一种方法是简单地删除 Products 表,并将 productName 移动到 BakersProducts 表中。

这基本上只有在您不希望面包师携带相同产品的情况下才有效,如果产品是面包师独有的。

如果您确实希望面包师携带相同的产品,那么您可能希望保留单独的 Products 表,但我会将其更改为 Order_has_Products.bpID,而不是 Order_has_Products.Products_productID。如果/当您需要访问 productName(或该表中可能包含的其他与产品相关的元数据)时,您可以在 BakersProducts 和 Products 之间进行连接。

【讨论】:

    【解决方案2】:

    这不是循环引用,因为

    • Order_has_products 参考产品
    • Order_has_products 参考 BakersProducts
    • BakersProducts 参考产品

    循环引用将是,例如,

    • Order_has_products 参考产品
    • 产品参考 BakersProducts
    • BakersProducts 参考 Order_has_products

    除此之外,循环引用在数据库中是相对正常的(即带有经理字段的员工表,其中经理是她自己,员工是一个表循环引用)

    您的设计有一个简单的冗余,因为一个产品在 Order_has_products 表中被引用了两次 - 一次直接来自 Products 表,一次通过相关的 BakersProducts 记录。不同步是有可能的,但是,既然你说业务规则是在面包师之前选择产品,那完全没关系。

    即使是相反的方式,我也会包含 productID,因为在加快查询速度时,一点点非规范化可能会有很长的路要走,因为否则您将不得不扫描 BakersProducts 表,即使是对于简单的问题,例如,星期三我们有百吉饼吗?'

    【讨论】:

    • 好的,感谢您澄清“循环引用”问题。我只是把这个场景想象成一个循环引用,因为一个产品会采用不止一个路由到订单。我认为尽管杰弗里的上述回答有助于尝试将订单请求与实际订单分开。
    【解决方案3】:

    我认为这种混淆是从业务流程的角度来看的:您将请购单订单混在一起。

    请购单包含所需产品的列表,而不必指定每个产品的供应商,而订单针对特定的供应商,具有特定的价格查询代码(bpID 似乎代表的内容)。如果一个请购单被多个供应商拆分,它可能会产生多个订单,甚至一个产品的订单也可能被多个供应商拆分,这可能是由于供应商数量限制或交货地点。

    您可能希望提供一个申请的视图,以显示从每个申请行项目生成的订单行项目,但这是用户界面问题。

    【讨论】:

    • thanx Jeffrey,你是正确的!我错误地尝试将 requisitionorder 合并。所以理想情况下,我应该有一个中介Requisition 表来显示“所需”产品,然后(基于此)有我的Orders 表参考BakersProducts.bpID
    • @magz:现在我想起来了,BakersProducts 行实际上更像是一个项目报价,而不是 PLU 或 SKU,当然也不仅仅是一个交叉-面包师和产品之间的桌子。它的真正主键应该是(bakerId, productId, bpDate),而bpID 是代理键。从订单订单项(而不是订单本身)引用bpID 将是指示订单项所基于的报价的好方法。或者,删除 bpID 并在从您的订单中引用时使用整个 3 字段复合键,以便快速链接到 Baker 和 Product。
    • @Jeffrey:谢谢!是的,bpID 是代理项,因为我无法在另一个表中引用复合键 (bakerID,productID,bpDate)。你介意我在 DBDesigner 中快速敲出它来看看这对我有什么影响吗?如果你不介意的话,我可能还有一个基于此的问题?
    • @Jeffrey:您对 BakersProducts 的设想是正确的。
    • @Jeffrey:看看这个修正案 [i.imgur.com/jeCHu.png]。我决定包含一个Requisitions 表,因为它提供了一个很好的平台来生成比较视图(在 UI 端),以允许经理根据最佳“交易”生成订单。您预见到这种设计有什么问题吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多