我会说,上面所有的答案都是 1. 考虑到问题中引用的例子是正确的,并且 2. 几乎所有时间都是正确的。
时不时我都会遇到单张桌子更好的情况。它是如此罕见,以至于当它出现时,我想知道我是否需要围绕一个整体(中性)实体进行架构设计。我很快就打消了这种冲动——也许是问别人,但我没有充分说明我的情况,于是我们又按照我们一贯的方式去做了。
然后,事实证明,在游戏中太晚了,我发现我应该制作一个中性实体类型的表。
下面是我的例子:
假设有两种实体类型,一个公司和一个人。一家公司通常由一个人拥有,但有时另一家公司拥有一家公司。
坚持这个想法并补充,假设每个公司都有一个注册代理人,负责公司的合法创建。而且,为了进一步说明,注册代理人可以是个人或其他公司。
鉴于公司/孩子的所有者/父母可以是个人或公司,您可能会开始看到挑战。相比之下,如果只有人可以拥有公司,那么您的 Ownership 链接表非常传统,其中包含以下列:OwnershipID(有点不必要)、CorporationID、PersonID。
相反,您需要类似:OwnershipID、CorporationID、OwnerID、OwnerType
不知何故,您可以使这项工作发挥作用,但至少可以说不会很有趣。
继续我给出的示例,您需要为每个公司分配一个代理。通常,代理人是业主之一(一个人)。在这种情况下,您确实希望链接回该人的一条记录。您不希望将该人记录为所有者,然后再次作为代理(在代理表中)。那将是多余的。坏事会发生。 :-)
与该“问题”类似,注册代理人也可以是公司,例如律师事务所、注册会计师或 Biz Filings 公司,列举了一些典型的例子。就像代理人一样,代理人公司真的不应该有自己的记录。它需要链接回 Corporation 表中已经存在的公司存在记录。 [除了我最终说没有有一个公司表]
就像将每个公司与其任何类型、个人或公司的所有者匹配的链接表一样,您可以拥有一个代理链接表:AgentRepresentationID、CorporationID、AgentID、AgentType。 .. 但是,当您必须将相关代理聚集在一起时(一些来自 Person 表,一些来自 Corporation 表),这将是丑陋的 (IMO)。
因此,在这种情况下,您可以看到中性实体类型如何具有优势。应该是这样的:
表:EntityAll
关键列:
实体 ID,
EntityType(或 EntityTypeID,如果您坚持,请链接获取描述),
EntityName(名称和不同类型存在问题……与本帖无关)
链接表:CorporationOwnership
关键列:
OwnershipID(我再次评论说这是不必要的),
ChildEntityID(被拥有的实体;为清楚起见,命名为“Child”,我不会这样命名)
ParentEntityID(父实体)
链接表:AgentRepresentation
关键列:
AgentRepresentationID(......我不会说),
CorporationEntityID(代表的公司实体),
AgentEntityID(来自 Entity 表,相当于这里的代理记录)
虽然您可能对我的体系结构没意见,但您应该对链接表中的列命名有点困扰。这让我很烦。通常,这些表中的第二和第三列名称与每个实体各自表中的 JOIN 列的名称完全匹配(哈哈,但每个实体没有各自的表,所以你可以' t 使链接表列名与源列名匹配,因为它们是同一列)。从技术上讲,这无关紧要,但它会破坏您应该重要的命名约定,但还不足以不这样做。
如果我还没有把它开回家,下面是你如何把它拉到一起的方法。你 JOIN EntityAll 表本身来获得你需要的东西。
列出所有军团及其所有者(在 T-SQL 中):
SELECT Corp.EntityName as CorpName, Owner.EntityName as OwnerName
FROM EntityAll as Corp
JOIN CorporationOwnership as Link on (Corp.EntityID = Link.ChildEntityID)
JOIN EntityAll as Owner on (Link.ParentEntityID = Owner.EntityID)
因此,您会做同样的事情来获取代理,而不是所有者。
我意识到这不是我们训练架构事物的方式,但我非常强烈地认为我的解决方案消除了冗余数据,并且更容易编码、管理和阅读。
不过,如果你坚持认为我错了,请告诉我。建议您如何使用单独的 Corporation 和 Person 实体表来构建我的示例。干杯!