在关系数据库中表达is-a关系

时间:2008-09-24 21:52:02

标签: database-design schema relational oop

我想知道是否有一种干净的方式来表示is-a关系,如下例所示:

此DB存储三种类型节目的录制时间:电影,游戏节目,戏剧。在面向对象的意义上,每个都是一个程序。这些子类中的每一个都具有不同的属性。这些是表(fk前缀表示外键):

电影
ID
命名
fkDirector

智力竞赛节目
ID
命名
fkHost
fkContestant


ID
命名

在OO术语中,记录表在某种意义上看起来像这样:

记录
ID
fkProgram
开始时间
ENDTIME

我能想到这样做而不违反正常形式的唯一方法就是有三个记录表,即 recordMovie recordGameShow recordDrama

有没有办法在不违反数据库规范化原则的情况下将这些表合并为一个?

以下是一些非工作示例来说明这个想法:

程序
ID
fkMovie
fkGameShow
fkDrama

此表违反了第一个普通表单,因为它将包含空值。对于每一行,3个条目中只有一个非空。

程序
ID
fkSpecific←fkMovie或fkGameShow或fkDrama
fkType←将指示要查看的表格

这里我将无法强制执行参照完整性,因为fkSpecific可能指向三个表中的一个。

我只是想节省在这里有3个表而不是一个表的开销。也许这根本不适用于RDB。

6 个答案:

答案 0 :(得分:2)

是的,那应该是一个像

这样的表
Programs:
   id,
   name,
   type_id,
   length,
   etc...

如果有,则提供有关程序类型的参考表 与该类型相关的其他数据位:

ProgramType
   type_id,
   type_name,
   etc...

就像那样。

答案 1 :(得分:2)

为什么要将所有数据存储在一个表中?它们显然是不同的实体。您对主记录表的想法,辅助 recordMovie recordGameShow RecordDrama

要强制辅助表和主要表之间的“is-a”关系,您需要将Record.id声明为所有这些表中的外键,并且还要为其添加约束以使其唯一 - 这会强制执行一对一的关系,将这些表转换为主表的扩展名。

您还需要在主记录表中添加一个新字段,以指示它是什么类型的记录(电影,游戏节目,戏剧,还有其他什么?)。这可以是对另一个表(RecordTypes?)的外键引用,也可以是一个字符串(在它可以接受的值上定义约束)。

答案 2 :(得分:2)

对“泛化专业化关系建模”进行谷歌搜索。

“gen-spec”模型遵循与“is-a”关系相同的模式。

例如,汽车是专用车辆。卡车是一种不同类型的专用车辆。摩托车是第三种专用车辆。

你应该找到很多文章。

有趣的是,如果您只是在“gen-spec”上进行谷歌搜索,其中一个顶部链接就是对Smalltalk中基因规范建模的描述。

答案 3 :(得分:1)

这是很多人以前面临的一个非常标准的问题,你可能考虑的所有方法都可能在某一时刻完成。

simple Google search提出了一些很好的解释,每个都有利弊。

答案 4 :(得分:0)

我的第一个想法是使用一个节目表来制作电影,节目和电视剧。戏剧的。然后添加一个ProgramType表并使用外键,就像父帖一样。

可以添加其他列,例如fkDirector,fkMovie。然后添加一个约束,当ProgramType是电影时,fkDirector不能为null或者当它是show时,fkHost不能为null。

这样可以轻松查找在开始和结束日期之间录制的所有电影/节目/ ....还要确保填写所有数据并且引用正确。

任何人都有更好的主意吗?

答案 5 :(得分:0)

这些都是关于这个主题的好文章:
http://www.ibm.com/developerworks/library/ws-mapping-to-rdb/
http://www.agiledata.org/essays/mappingObjects.html

这将是我最终要做的事情。我的节目表只是:

程序
ID

然后我将fkProgram添加到每个子类(戏剧,游戏节目和电影)。这样,Program表将成为子类之间的中间表。我可以使用Program表的外键来引用任何子类的实例。这将允许我有一个记录表,而不是违反任何正常形式。

电影
ID
fkProgram
命名
fkDirector

记录
ID
fkProgram
开始时间
ENDTIME