ERD 行动可以或应该涉及 2 个以上的实体吗?

Can or Should an ERD Action involve more than 2 Entities?

这是我的一门课程中关于绘制ERD的问题:

A local startup is contemplating launching Jungle, a new one stop online eCommerce site.

As they have very little experience designing and implementing databases, they have asked you to help them design a database for tracking their operations.

Jungle will sell a range of products, and they will need to track information such as the name and price for each. In order to sell as many products as possible, Jungle would like to display short reviews alongside item listings. To conserve space, Jungle will only keep track of the three most recent reviews for each product. Of course, if an item is new (or just unpopular), it may have less than three reviews stored.

Each time a customer buys something on Jungle, their details will be stored for future access. Details collected by Jungle include customer’s names, addresses, and phone numbers. Should a customer buy multiple items on Jungle, their details can then be reused in future transactions.

For maximum convenience, Jungle would also like to record credit card information for its users. Details stored include the account and BSB numbers. When a customer buys something on Jungle, the credit card used is then linked to the transaction. Each customer may be linked to one or more credit cards. However, as some users do not wish to have their credit card details recorded, a customer may also be linked to no credit cards. For such transactions, only the customer and product will be recorded.

这是解决方案:

问题是购买操作与其他 3 个实体相关联:产品、客户和卡片。我发现这很难阅读和理解。

涉及两个以上实体的动作在生产中是否常见?如果是,我应该如何理解和使用它?或者,如果不是,那么针对此问题的更好设计方法是什么?

虽然实践中的大部分关系是二元关系,但三元和更高的关系是实体关系模型的正常元素。一些示例是 supplies (supplier_id, product_id, region_id)enrolled (student_id, course_id, semester_id)。但是,由于不喜欢复合键或与仅支持定向二元关系的网络数据模型混淆,它们经常通过引入代理标识符转换为实体集。

阅读非二元关系的基数指标是一个常见的混淆来源。有关我如何处理此问题的更多信息,请参阅我对 的回答。

您的解决方案存在一些问题。首先,Buys 被表示为关联实体,但被用作具有可选角色的三元关系。我认为两者都不正确。有关 ER 模型中关联实体的解释,请参阅我对 的回答。

将购买交易建模为关系通常是错误的,因为关系是由它们相关的实体(键)标识的。如果(CustomerID, ProductID)是身份识别,那么一个客户只能购买一次产品,并且每次交易只能购买一个产品。在关系的键中添加 date/time 更好,但仍然存在问题。添加代理标识符并将其变成常规实体集几乎肯定是最好的做法。

其次,鱼尾纹基数指标不明确。看起来客户和产品在 Buys 关系中是可选的,甚至好像多个客户可能参与同一笔交易。这里涉及三个不同的概念——可选性、参与性和基数——最好用不同的方式来表示。有关该主题的更多信息,请参阅我对 的回答。

  • 对于购买交易,卡是可选的。从描述来看,卡似乎可以完全参与,这意味着我们不会存储有关卡的信息,除非它用于交易。此外,每笔交易只能关联一张卡。

  • 购买交易需要客户,听起来客户可能会完全参与,这意味着我们不会存储有关客户的信息,除非他们购买了东西。每笔交易只能关联一个客户。

  • 购买交易需要产品,并且由于我们会在购买前提供产品,因此产品将部分参与交易。但是,每笔交易可以关联多个产品。

我会用类似以下结构的东西表示这个问题的交易:

我并不是说将三元或更高关系转换为实体集总是正确的做法,但在这种情况下是正确的。

从物理上讲,这需要两个 table 来表示(不包括客户、产品、卡或 ProductReview),因为我们可以将 TransactionCustomer 和 TransactionCard 非规范化为 Transaction,但 TransactionProduct 是多对多关系并且需要它自己的 table(三元关系和更高关系也是如此)。

Transaction (TransactionID PK, TransactionDateTime, CustomerID, CardID nullable)
TransactionProduct (TransactionID PK, ProductID PK, Quantity, Price)