【问题标题】:SQL table design with contigent constraints具有条件约束的 SQL 表设计
【发布时间】:2011-08-23 04:23:07
【问题描述】:

我有一个表格设计问题,我需要一个巧妙的解决方案。

假设我有两个表,有关系:

Contract 1---N Payment

现在,假设我有需要进入这些表的遗留数据。但问题是,许多遗留的支付条目是跨多个合约聚合的

所以我们实际上可以将其视为:

新:

SomethingAboveContract 1---N Contract 1---N Payment

旧版:

SomethingAboveContract 1---N Payment

现在,我可以通过在 Contract 和 Payment 之间创建 M-N 关系来解决这个问题。

Contract 1---N ContractPayment N---1 Payment

(我可以识别与聚合付款相关的所有合同)

这对于遗留数据来说很好,但我确实希望在未来强制执行合同和付款之间的 1-N 关系。所以,用我很不方便的涂鸦来说明,我想这样做:

即如果付款是聚合的,ContractID 将为 NULL,否则不应为 null。换句话说,我需要找到一种方法来在 Payment 表上强制执行以下或有事项:

  1. 如果 PaymentID 出现在 ContractPayment 中,则 ContractID 可为空
  2. 如果 PaymentID 未出现在 ContractPayment 中,则 ContractID 不能为空

不过我不知道该怎么做。

即使这是可能的,它看起来确实有点难看(遗留数据转换总是如此)。因此,如果有人有更优雅的解决方案,那就太好了。否则,任何可行的方法!

谢谢
卡尔

【问题讨论】:

  • 由于您不能编写影响多个表的 DML 语句,因此这里存在先有鸡还是先有蛋的问题 - 在 @ 中存在一行之前,您无法插入 ContractPayment 987654328@,但您无法在 Payment 中插入所需的行,因为它有一个空 ContractID,并且在 ContractPayment 中没有行
  • @Damien_The_Unbeliever:我猜你在“DML”的定义中很方便地省略了SELECT :)
  • @onedaywhen - 因为SELECT(没有INTO)不操纵数据,不,我不包括SELECT在D M L. 即使我们确实包含了它,您是否知道有任何方法可以让SELECT 语句影响任何表(更不用说多个表了)
  • 我不知道有什么方法可以指定条件可空性,除了可能在触发器中强制执行这种关系,我不建议这样做。 ( 触发器中的业务逻辑,也称为“如何射中自己的脚,让你的同事讨厌你!”)。鉴于您有合同和付款之间的连接表,我不明白合同和付款之间直接联系的价值。连接表、Contract 和 Payment 之间的外键与直接链接的作用相同,只是它们 A) 间接且 B) 更灵活。 YMMV。
  • @Damien_The_Unbeliever:我不认为 DML 是正式定义的,例如不是 SQL 标准的一部分。尽管您无疑会发现许多诸如您自己的排除SELECT(没有INTO),但我认为大多数都包含它,例如Wikipedia's。没什么大不了的,当然:)

标签: sql sql-server-2008 many-to-many database-design


【解决方案1】:

使用两(组)表,一张用于“旧版”,一张用于后续。您应该能够简单地定义业务规则并且不需要可空列(SQL 的三值逻辑是一场灾难)。可以撤销“旧”表上的特权,以帮助确保它们不再被使用。

【讨论】:

  • +1 我的第一个想法。两组表。还要添加至少一个视图以获取组合两个表的合同的付款。
  • +1 表示两组表格。在最一般的情况下,不可能让遗留数据适应新的约束。不仅如此,您还经常需要将遗留数据与更当前的数据区分开来。当它们在不同的表中时,这非常简单。
猜你喜欢
  • 2019-12-03
  • 2013-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-03
  • 2021-07-22
  • 1970-01-01
相关资源
最近更新 更多