【问题标题】:What would it mean If I change the identifying relationship from this part of a database design to a non-identifying relationship?如果我将识别关系从数据库设计的这一部分更改为非识别关系,这意味着什么?
【发布时间】:2010-09-05 21:03:04
【问题描述】:

我对此数据库设计有疑问。我有点不确定数据库中识别和非识别关系之间的区别,这让我陷入了一些困惑。

我有这样的数据库设计:(有点像电影租赁店。“朋友”是借电影的人。“工作室”是合作制作电影的制作工作室。)

我有点理解它是如何工作的。但是,我想知道如果我在贷款表中创建一个 loan_id,并使用 movie_idfriend_id 作为普通外键会怎样?

我的一些问题是: 后一种方法的优点或缺点是什么? 初始模型或以后模型更好的情况? 初始模型是否允许朋友多次借用电影?

任何详尽的解释将不胜感激。

【问题讨论】:

    标签: sql database database-design data-modeling


    【解决方案1】:

    拥有所有多对多表(表协作、贷款、角色)的方式称为复合主键:其中两个(或更多)列形成一个唯一值。

    当您有一个复合 pk 时,许多数据库设计人员更喜欢创建一个代理主键(例如您建议的 loan_id)。我就是其中之一。这篇文章很好地解决了为什么或为什么不的论点:Composite primary keys versus unique object ID field

    我的相对简单的原因是复合键趋于增长:使用借阅示例,如果电影不止一次借阅会发生什么?使用复合方法,您必须将loan_date 添加到复合键。

    如果您想跟踪某种类型的再贷款怎么办?然后,您必须有一个第二个表,其中包含贷款表中的所有复合 pk 字段(original_loan_movie_id、original_loan_friend_id、original_loan_date)只是为了引用原始贷款......

    【讨论】:

    • 因此,由于业务分析和/或设计不佳,您建议使用单列键来隔离参考完整性?
    • 你假设需求不会改变,我假设它们会。我也不会称其为糟糕的分析,我会很明显地指出,假设您的业务需求不会改变是幼稚的。至于其他原因:身份 PK 的插入(假设聚集索引在 PK 上)比自然键 PK 执行得更好,尽管这不适用于此处。 ORM 软件在代理方面做得更好。
    【解决方案2】:

    LOAN 表中,您需要保证以下列是唯一的:

    • movie_id(替换为copy_id,假设电影有多个副本)
    • friend_id
    • 贷款日期

    ...因为我或其他任何人都应该能够多次租借同一部电影。这些也是最有可能被搜索到的列...

    考虑到这一点,将名为loan_id 的列定义为表的主键的想法是多余的。 ORM 一直强制使用非复合主键来简化查询...

    但它使查询更容易......

    乍一看,它使删除或更新特定贷款/等变得更加容易 - 直到您意识到您需要知道适用的 id 值首先。如果您必须根据电影、用户/朋友和日期来搜索该 id 值,那么您最好直接使用该条件。

    但是复合键很复杂...

    在此示例中,主键约束将确保三列——movie_id、friend_id 和 loan_date——将是唯一的并被索引(如果聚集索引尚不存在,大多数数据库会自动索引主键)使用表的最佳索引。

    单独的主键方法意味着loan_id 使用表的最佳索引进行索引(SQL Server 和 MySQL 将它们称为聚集索引,对于 Oracle,它们都只是索引),并且需要额外的复合唯一约束/指数。一些数据库可能需要超出唯一约束的额外索引......所以这使得数据模型更加复杂/复杂,并且没有任何好处:

    • 某些数据库(如 MySQL)对可用于索引的空间量进行了限制。
    • 主键得到了最理想的索引,但值与表中的数据无关,因此很少使用与主键相关的索引。

    结论

    我还没有看到单列主键优于复合主键的合理理由。

    【讨论】:

    • 一个可能的原因是主键的部分是(或可能变得)可变的。然后,所有引用外键也需要更新。在此处的示例中,如果系统用于安排贷款,并且有人打错了他想要看电影的日期怎么办?
    • @meriton:假设您拥有必要的权限,数据库的每一列都是可变的。这就是为什么数据库设计/数据建模不适合迭代开发的原因——不断变化的模型意味着糟糕的需求收集和/或数据库设计/数据建模。真正的问题是 - 您是否看到业务(在这种情况下是房地产贷款/租赁视频)在不久的将来发生重大变化?
    • 索引参数是错误的,至少对于 Sql Server 而言。聚集索引不必是主键。此外,通常身份(代理键)列是不可变的。
    • @Shlomo:IDENTITY 只是一个顺序值;它是强制列中唯一性的约束(主键或唯一性)。正如我之前所说 - 如果您有足够的权限,您可以更改该值。它可能需要禁用约束和/或使用IDENTITY_INSERT,但不会出现数据库包含无法更改的数据的情况。
    • @Shlomo:虽然 SQL Server 支持在除主键之外的列上创建聚集索引,但它仍然过于复杂,并且与定义复合主键相比没有任何好处。此外,CASCADE ON DELETECASCADE ON UPDATE 允许外键引用而不删除或延迟约束...
    猜你喜欢
    • 2010-10-20
    • 2012-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-18
    • 2016-04-23
    相关资源
    最近更新 更多