数据库:如何区分"一个或多个"和"零或多个"关系?

jin*_*ing 12 sql t-sql database database-design

设计工具允许区分"一个零或多个 ""一个一个或多个 "关系.我可以想象如何实现"一个零或多个"关系:


CHILD_TABLE

(pk)chid_id
(fk)parent_id (必填)


PARENT_TABLE

(pk)parent_id


如何实现"一对一或多"关系?怎么说父母需要至少一个孩子?或者" 一个或多个 "通常实现为" 零或多 "?

Erw*_*out 8

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

SQL 语言(我的意思是标准)通过CREATE ASSERTION为它提供支持.唉,目前没有引擎支持此声明.

使用当前现有的SQL引擎可以实现的唯一方法是推迟约束检查,直到所有更新完成后(当然,如果您的引擎支持此操作).如果您的数据库是"共享的"并且也可以由其他程序更新,那么在应用程序代码或业务逻辑中实施此类约束最终将完全不具有约束.

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

aioobe的解决方案非常原创,但请记住,您只能通过将"many"(/ child)侧的所有列复制到"one"(/ parent)侧来实现此目的(因为否则您仍然会遇到相同的问题)两个表,除了"或更多"部分已经消失,但这不是问题所在.)如果你这样做,那么你在以下情况下将遇到很大的困难:

  • 针对"很多"方面编写查询(您必须确保位于"一"侧的另一行将始终与多方进行UNIONed),
  • 在"许多"方面强制执行密钥(您必须确保许多方面的密钥与位于"一"方的另一条密钥的值不同,
  • 当引用表本身就是你的"一个或多个"时,强制执行引用完整性(你应该看到它对于存在于"one"一侧的另一行的引用也是有效的).

所以aioobe的解决方案,尽管是原创的,可能会产生比它解决的更多新问题.


DCN*_*YAM 6

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

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