多态层次结构数据库设计

时间:2016-01-21 22:15:58

标签: database database-design relational-database

我正在寻找一种有效的方法来构建可以处理以下场景的数据库模型: 模型需要处理未定义深度的层次结构,其中每个节点可以有0到3个(最多)子节点,其中每个子节点可以是5-7种不同类型之一。

以下是我需要支持的示例树示例,其中包括' foo'' bar'每个都将在不同的表中输入,并且该数字引用该表中的id。假设foo.1,bar.2和foo.3是顶级节点。 Base只是一个虚拟对象,我可以指向未知类型的顶级节点。

Base.1
|-foo.1
  |-foo.2
    |-qaz.1
  |-bar.1
Base.2
|-bar.2
  |-qaz.2
  |-foo.2
  |-bar.3
Base.3
|-foo.3

此外,必须保持子节点的顺序(即,在上面的层次结构中用qoo.2切换qaz.2是不行的。)

从数据访问的角度来看,大部分时间我将检索从顶级对象(Base.x)继承的整个树。

我到目前为止所认为的是定义一个具有多态关联的表,并且每个子节点类型都引用该中心表,例如:

BaseTable
---------
BaseId (PK)
ObjectId (FK)

ObjectTable
-----------
ObjectId (PK)
ObjectType
OtherTableId
BaseId (FK)   gets top level parent

FooTable
---------
FooId (PK)
Child1_ObjectId (FK)
Child2_ObjectId (FK)
Child3_ObjectID (FK)
Other data fields...

etc. for bar and qaz

我的想法是我可以在ObjectTable中使用BaseID FK来抓取整个树,但有没有一种有效的方法可以通过SQL重建整个树,或者我需要在检索后在我的代码中执行此操作?或者,是否有更好的方式以更高效的方式存储此类数据并保证关系完整性?

1 个答案:

答案 0 :(得分:0)

  

每个都将在另一个表中输入

有充分的理由吗?

单表继承是最快的,所以如果您关心性能......

这将有效:

create table foo (
  foo_id int primary key,
  type char(1) not null, 
  parent_id int null references foo(foo_id),
  display_order int not null default 0,
  foo_specific_data...,
  bar_specific_data...,
  qux_specific_data...,

  unique( parent_id, display_order )
);

然后使用recursive common table expressions进行查询(避免使用MySQL / MaridDB)。使用触发器强制执行最多3个孩子"规则/显示订单更新