在我的示例中,我有一个watch
,表示用户想要通知其他商品上的活动,例如group
和organization
。
我认为有两种方法可以做到这一点:
groupwatch
资源,其中包含groupwatch
表,id
,user
,group
(FK到group
组资源,表);和orgwatch
资源,orgwatch
表,id
,user
,organization
(org FK到organization
资源和表格)< / LI>
watch
表格的通用watch
资源,id
,user
,type
,typeid
。 type
是group
或organization
中的一个,typeid
是被观看的group
或organization
的ID。由于它们都是手表,因此有两个不同的表和资源来观看2个不同的对象似乎是浪费。如果我开始观看4种,5种,6种,20种,50种不同类型的资源,情况会变得更糟。
另一方面,如果我只有一个通用typeid
,则外键关系似乎不可能,这意味着我的数据库(如果是关系)和我的框架(activerecord或其他任何东西)无法正确执行它。 / p>
如何最好地为表格中的每条记录实现这种“与不同类型的记录/表格的关联”?
更新:
这是我做这件事的唯一选择:
watch
类型分隔表/资源,这使数据库能够强制执行关系完整性并进行连接watches
的单一表格,但我必须强制执行关系完整性并在应用级别进行加入? 答案 0 :(得分:1)
如果每六个月添加一种新类型的资源,您可能希望以添加新资源涉及更改数据定义的方式定义表。如果每周添加一个新资源类型,则可能需要在添加新类型时使数据定义保持不变。这两种选择都有不利之处。
如果您确实选择以表格结构中可见类型的方式定义表格,则有两种模式通常与类型/子类型(也称为类/子类)情境一起使用。
一种模式被称为&#34;单表继承&#34;。将所有类型的数据放在一个表中,并在不适用的地方留下一些NULL。
另一种模式被称为&#34;类表继承&#34;。为超类定义一个表,其中包含所有类型共有的所有数据。然后为每个子类型(子类)定义表以包含特定于类的数据。使子类型表的主键与超类型表中的主键重复,并将其声明为引用超类型表的主键的外键。在插入时,它将在应用程序中更新,以便在子类型表中复制超类型表中的主键值。
我喜欢Fowlers&#39;治疗这两种模式。
http://martinfowler.com/eaaCatalog/classTableInheritance.html http://www.martinfowler.com/eaaCatalog/singleTableInheritance.html
共享主键的问题有一些有益效果。
首先,它强制执行ISa关系的一对一性质。 其次,通过仅加入子类型表,可以很容易地找出给定条目是否属于所需的子类型。你真的不需要额外的类型字段。 第三,它加速了连接,因为在声明主键时会生成索引。
如果您想要一个可以在不更改数据定义的情况下适应新属性的结构,您可以查看E-A-V设计。但要小心。有时,这会导致数据几乎无法使用,因为逻辑结构非常模糊。出于这个原因,我通常认为E-A-V是一种反模式,尽管有些人真的很喜欢他们从中得到的结果。