【问题标题】:Techniques for database inheritance?数据库继承技术?
【发布时间】:2008-12-22 16:22:37
【问题描述】:

当您需要将具有继承的类持久化到不支持继承的关系数据库时,有哪些技巧/技术?

假设我有这个经典的例子:

Person -> Employee -> Manager
                   -> Team lead
                   -> Developer
       -> Customer -> PrivilegedCustomer
                   -> EnterpriseCustomer

设计数据库的可用技术有哪些?各有优劣?

附言我已经搜索并发现了几个关于数据库继承的问题,但大多数都是关于更改为原生支持它的数据库引擎。但是假设我被 SQL Server 2005 困住了……我有什么选择?

【问题讨论】:

标签: database database-design class-table-inheritance


【解决方案1】:

三种常用策略:

  1. 为层次结构中的每个类创建一个表,其中包含为每个类定义的属性和返回*超类表的外键。所以你可能有一个vehicle 表和其他表,如carairplane,它们有一个vehicle_id 列。这里的缺点是您可能需要执行大量连接才能获得一种类类型。

  2. 为层次结构中的每个类创建一个包含所有属性的表。这可能会变得很棘手,因为在所有表中维护一个公共 ID 并不容易,除非您使用的是序列之类的东西。查询超类类型需要针对所有相关表进行联合。

  3. 为整个类层次结构创建一个表。这消除了连接和联合,但要求所有类属性的所有列都在一个表中。您可能需要将大多数列保留为空,因为某些列不适用于不同类型的记录。例如,vehicle 表可能包含名为wingspan 的列,对应于Airplane 类型。如果将此列设为 NOT NULL,则插入表中的任何 Car 实例都将需要 wingspan 的值,即使 NULL 的值可能更有意义。如果您将列保留为空,您可能可以使用检查约束来解决此问题,但它可能会变得丑陋。 (Single Table Inheritance)

【讨论】:

  • 查询的复杂性是我所关心的。在 DAL 部分可能需要一些技巧才能使其正确。
  • 查询复杂度 #3 听起来最好。此外,在某些 DBMS(如 Postgres)中,您可以通过检查约束强制每个特定子类型的非空性,即使列都可以为空。
  • 我不知道这是否是一个选项,但您不使用 1。并使用视图访问数据,这样您只能在一个位置获得连接?
【解决方案2】:

在某些情况下要小心数据库继承 - 我们在应用程序中为我们的审计策略实现了它,但我们最终遇到了性能瓶颈/噩梦。

问题是我们使用的基表只是插入并且快速变化,所以我们最终得到的是死锁all。我们目前正计划将这些拆分成各自的表,因为在 15 个不同的表中拥有相同的列而不是性能噩梦的头痛是值得的。实体框架不一定有效地处理继承这一事实也加剧了这种情况(这是 Microsoft 的一个已知问题)。

无论如何,我只是想我会分享一些知识,因为我们已经在这个问题上经历了痛苦。

【讨论】:

  • 所以你在做#1并且正在移动(已经移动)到#2? (cliff.meyers 解决方案)
【解决方案3】:

第 8 章。以下链接中的继承映射也讨论了这一点。 http://nhibernate.info/doc/nh/en/index.html#inheritance

它是 NHibernate 文档。

【讨论】: