【问题标题】:Database: How to distinguish "one-or-more" and "zero-or-more" relationship?数据库:如何区分“一个或多个”和“零个或多个”关系?
【发布时间】:2011-07-29 03:55:17
【问题描述】:

设计工具允许区分 "one TO zero-or-more""one TO one-or-more " 关系。我可以想象如何实现 “一个到零或多个” 关系:


CHILD_TABLE

(pk) chid_id
(fk) parent_id (必需)


PARENT_TABLE

(pk) parent_id


如何实现“one TO one-or-more”的关系?怎么说父母至少需要一个孩子?还是“one-or-more”通常实现为“zero-or-more”?

【问题讨论】:

    标签: sql database tsql database-design


    【解决方案1】:

    很明显,强制执行约束(例如您指定的约束)有时会要求客户端发出(并且 DBMS 引擎接受)可能被标记为“同时更新”的内容,即多个不同的表被在任何约束检查之前更新。

    SQL 语言(我的意思是标准)通过 CREATE ASSERTION 提供支持。唉,目前没有任何引擎支持这种说法。

    使用当前现有的 SQL 引擎可以实现这一点的唯一方法是将约束检查推迟到所有更新完成之后(当然,如果您的引擎支持这一点)。如果您的数据库是“共享的”并且也可以由其他程序更新,那么在应用程序代码或业务逻辑中强制执行此类约束最终等于根本没有约束。

    确实存在支持强制执行您的约束类型的系统,但它们不是 SQL 系统。

    aioobe 的解决方案非常新颖,但请记住,您只能通过将“多”(/child)一侧的所有列复制到“一个”(/父)一侧来做到这一点(因为否则您仍然拥有两个表之间存在同样的问题,除了“或更多”部分已经消失,但这不是问题所在)。如果你这样做,那么你将面临很大的困难:

    • 针对“多”端编写查询(您必须确保位于“单”端的另一行总是与多端联合),
    • 在“多”端强制执行键(您必须确保多端的键与“一”端的另一行具有相同的值,
    • 当被引用的表本身是你的“一个或多个”端时强制引用完整性(你应该注意它对存在于“一个”端的另一行的引用也是有效的) .

    因此,aioobe 的解决方案虽然是原创的,但可能会产生比它解决的更多的新问题。

    【讨论】:

      【解决方案2】:

      实现一对一或多的关系是通过业务逻辑完成的,或者至少使用事务。您不能同时插入两个表;你一次插入一张桌子。因此,您需要先插入父项,然后才能插入子项,并且数据库没有内置方法来强制执行所需的逻辑。

      如果你将两个 INSERT 语句包装在一个事务中,那么你保证如果子插入失败,父插入将被回滚。但是,由业务逻辑决定是否在没有子项的情况下插入父项。

      【讨论】:

        【解决方案3】:

        在 SQL Server 中,外键关系始终是“一”到“零或多个”。 “一个”到“一个或多个”的关系也会使插入初始数据变得非常困难。 (您必须先禁用外键才能在父表中插入记录)

        【讨论】:

          【解决方案4】:

          我所知道的最好的方法是通过一个存储的过程进行所有插入,该过程有一个事务,如果孩子失败,则回滚父插入。

          我见过的另一种方法(但这确实有点 hack)是使子项中的所有字段(除了自动生成的 Id 和 FK 都可以为空,然后仅使用父表上触发器中的 id 插入记录) .然后对子表进行更新以添加其他字段的详细信息。如果它们应该可以为空,或者如果您在为子表输入数据时可能没有任何数据,这是可以接受的,但如果字段不应该为空,则可能会产生数据完整性问题。

          【讨论】:

            【解决方案5】:

            您可以将其实现为“一对一”加上“一对零或更多”

            【讨论】:

            • -1 这将区分“one-to-one”中的 one 和“one”中的 more - 到零或更多”。删除这个显着行的处理会更加复杂。
            【解决方案6】:

            一般来说,SQL 语言对参照完整性和完整性约束的支持非常有限。标准 SQL(以及大多数(如果不是全部的话)流行的 SQL DBMS)不支持一对一或多约束。 SQL FOREIGN KEY 约束在关系的引用端始终是可选的。数据建模工具和语言通常支持此类约束(ORM、ERD),但 DBMS 很少允许您实现它们。

            【讨论】:

            • 投反对票时,解释原因会很有帮助。
            猜你喜欢
            • 2012-12-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-04-29
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多