【问题标题】:DB design: Is a root entity a good approach to link to two or more related entities?数据库设计:根实体是链接到两个或更多相关实体的好方法吗?
【发布时间】:2011-04-22 13:50:25
【问题描述】:

我的应用程序 - 基于关系数据库 - 必须处理两种客户实体,(自然)人和组织。它们具有不同的属性,因此每个组都存在于自己的表中。

现在我有了其他数据对象,例如地址、标签或备忘录。每条记录都属于一个人或一个组织。

我想知道如何表示这种联系。链接到个人或组织时,我不希望目标表中有另一个字段。

我正在考虑在个人和组织之上创建一种超级实体。我在 Highrise 或 Capsule CRM 等 CRM 应用程序中看到了这一点——他们称之为“聚会”。每个人和每个组织在聚会表中都有相应的条目。其他表格现在链接到聚会表格,而不是直接链接到个人或组织。

派对:

  id | person_id | org_id
   1 |         1 |
   2 |           |      1

在上面的例子中,派对记录 #1 链接到人 #1,派对记录 #2 链接到组织 #1。

这真的是一种可行的方法还是我只是有点盲目寻求更简单的解决方案?

【问题讨论】:

    标签: database-design


    【解决方案1】:

    我已经多次在 SO 上回答过类似的问题。我提供的两个信息最丰富的答案是herehere。这两个答案在不同的上下文中都使用了相似的结构;我认为第二个的 cmets 特别有用。

    【讨论】:

    • 我喜欢使用派对表的 PK 作为派对和子类型条目的公共 ID。这避免了在派对表中存储(不同的)子类型 ID。
    • 不错的答案。我特别喜欢您解决问题的方式,即如何确保使用检查约束引用正确的类型。但是作为基表中主键一部分的类型列不是更可靠吗?
    • 在 SQL 级别 在此上下文中,a) 主键是否为 id 并且唯一约束是否在 id 和类型的组合上并不重要, 或 b) 主键是 id 和 type 的组合,并且唯一约束在 id 上。外键约束可以针对 PK 或唯一约束,无论它们是如何定义的。重要的是,为了安全性和灵活性,您需要这两个约束。
    • 哦,我不能把解决这个问题归功于我。几年前,我通过 Usenet 新闻组学到了这些东西。 (嗯。也许是几十年前。)我不记得我是从谁那里学来的,但如果我能弄清楚是谁,我会很高兴地相信他。
    【解决方案2】:

    我会使用“超级”表的方法,但将参考转过来。 personorganizations 将引用 party 表,而不是相反。

    如果 DBMS 不直接支持关系数据库中的“继承”(例如 PostgreSQL),这是在关系数据库中建模“继承”的常用设计模式(例如 PostgreSQL)

     party (id, customer_number, [other common attributes] )
     person (person_id, party_id, ... )
     organizations (org_id, party_id, ... )
     address (address_id, party_id, ...) 
    

    为方便起见,您可以创建加入派对/个人和派对/组织的视图,以便您可以轻松访问基本属性以及专用类型。

    【讨论】:

    • 这是一个非常简单的解决方案。作为副作用,它将两个实体的“主”表向下移动到相同的级别,例如地址等,并使头部数据只是一方的另一个方面。你会在聚会表中创建一个类型字段(P/O)吗?
    • 不,有了两个单独的“类型表”,就不需要类型列。唯一可能的用途是您可以快速计算您拥有多少人和组织(无需对子表进行两次单独的计数)。除此之外,我看不到类型列的任何优势。
    【解决方案3】:

    拥有像“Party”这样的元表是一种选择,尽管我会让解决方案更具可扩展性。这个怎么样

    PartyType
    - id
    - name
    
    Party
    - id
    - partyTypeId
    - typeSpecificId
    

    在 PartyType 表中,您将定义“Person”和“Organization”类型。然后,您创建的每一方都会有一个与之关联的 PartyType。这样您将来可以添加更多类型,并且您的表更密集,没有那么多空列。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多