【问题标题】:Expressing an is-a relationship in a relational database在关系数据库中表达 is-a 关系
【发布时间】:2010-09-12 21:53:07
【问题描述】:

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

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

电影
身份证
名称
fkDirector

gameShow
身份证
名称
fkHost
fk参赛者

戏剧
身份证
姓名

在 OO 术语中,记录表看起来像这样:

记录
身份证
fk程序
开始时间
结束时间

在不违反正常形式的情况下,我能想到的唯一方法是拥有三个记录表,即 recordMovierecordGameShowrecordDrama.

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

这里有一些无效的例子来说明这个想法:

程序
身份证
fk电影
fkGameShow
韩剧

该表违反了第一范式,因为它将包含空值。对于每一行,3 个条目中只有一个不为空。

程序
身份证
fkSpecific ← fkMovie 或 fkGameShow 或 fkDrama
fkType ← 将指示要查看的表

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

我只是想节省在这里使用 3 张桌子而不是一张桌子的开销。也许这根本不适用于 RDB。

【问题讨论】:

    标签: database-design schema relational oop


    【解决方案1】:

    是的,应该是一张桌子

    Programs:
       id,
       name,
       type_id,
       length,
       etc...
    

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

    ProgramType
       type_id,
       type_name,
       etc...
    

    这样。

    【讨论】:

      【解决方案2】:

      这是许多人以前面临的一个相当标准的问题,您可能考虑的所有方法都可能在同一时间完成。

      simple Google search 对每种方法的优缺点做了一些很好的解释。

      【讨论】:

        【解决方案3】:

        我的第一个想法也是为电影、节目和戏剧使用一个节目表。然后添加一个 ProgramType 表并像父帖子一样对其使用外键。

        可以添加其他列,例如 fkDirector、fkMovie。然后添加一个约束,即当ProgramType为电影时,fkDirector不能为null;当为节目时,fkHost不能为null。

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

        谁有更好的主意?

        【讨论】:

          【解决方案4】:

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

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

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

          【讨论】:

            【解决方案5】:

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

            这就是我最终要做的。我的程序表将是:

            程序
            身份证

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

            电影
            身份证
            fk程序
            名称
            fkDirector

            记录
            身份证
            fk程序
            开始时间
            结束时间

            【讨论】:

              【解决方案6】:

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

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

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

              你应该找到很多文章。

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

              【讨论】:

              • 关键字“泛化专业化关系建模”+1
              猜你喜欢
              • 1970-01-01
              • 2020-12-04
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-11-02
              • 2016-07-09
              • 2011-07-17
              • 2010-12-20
              相关资源
              最近更新 更多