强制执行此数据完整性约束的最佳方法是什么?

发布于 2024-09-26 12:05:08 字数 840 浏览 4 评论 0原文

我有 3 个表(我们称它们为 Foo、Bar 和 Baz。

表:

Foo

  • FooId

Bar

  • BarId
  • FooId

Baz

  • BazId
  • BarId
  • AnotherValue

显然,外键使得每个 Baz 与 Bar 关联,因此与 Foo 关联。 现在我想确保对于具有相同“AnotherValue”的每组 Baz,所有关联的 Foo 都是唯一的

例如,如果我有

Foos (1, 2, 3)
Bars ((10, 1), (11, 1), (12, 1), (13, 2))
Bazs ((100, 10, "a"), (101, 10, "b"), (102, 13, "a"), (104, 11, "b"))

这个应该被阻止,因为 Baz 104 和 baz 101 都有 AnotherValue“b”和 Foo 1。


< strong>我想到的选项(按照我当前偏好的顺序)

索引视图

我可以在这三个表上创建一个视图,并在两列上放置唯一

索引 计算列

将 FooId 作为计算列添加到 Baz。然后在 AnotherValue 和 FooId 上添加索引。

检查约束

我很确定这可以添加并且可以工作。我没有太多使用检查约束,并且我不确定这是否是执行此操作的最佳方法。

触发器

这对我来说看起来很丑。

I have 3 tables (lets call them Foo, Bar and Baz.

Tables:

Foo

  • FooId

Bar

  • BarId
  • FooId

Baz

  • BazId
  • BarId
  • AnotherValue

Obviously the foreign keys make it so that each Baz is associated with a Bar, and hence, associated with a Foo.
Now I want to ensure that for each set of Baz with the same "AnotherValue" all the associated Foo's are unique

For instance, if I had

Foos (1, 2, 3)
Bars ((10, 1), (11, 1), (12, 1), (13, 2))
Bazs ((100, 10, "a"), (101, 10, "b"), (102, 13, "a"), (104, 11, "b"))

this should be blocked because Baz 104 and baz 101 both have AnotherValue "b" and Foo 1.


Options I have thought of (in order of my current preference)

Indexed View

I could create a view over these three tables and put a unique index on the two columns

Computed Column

Add FooId as a computed column to Baz. Then add an index on AnotherValue and FooId.

Check Constraints

I'm pretty sure this can be added and will work. I haven't used check constraints much, and I'm not sure if it is the best way to do this.

Trigger

This just seems ugly to me.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

淤浪 2024-10-03 12:05:08

我不确定我完全理解这个问题,但似乎您想将 FooId 带到 Baz 表并在 FooId,AnotherValue 上添加备用键(唯一约束)。

Baz
•BazId
•BarId
•FooId
•AnotherValue

I'm not sure I completely understand the question, but it seems like you want to carry the FooId down to the Baz table and add an Alternate Key (Unique contraint) on FooId,AnotherValue.

Baz
•BazId
•BarId
•FooId
•AnotherValue
安穩 2024-10-03 12:05:08

只是使用不同的名称重述:

Parent (ParentID) 
       (1, 2)
Child (ChildID, ParentID) 
       ((10, 1), (11, 1), (13, 2))
GrandChild (GCID, ChildID, GCAndParentVal) 
       ((100, 10, "a"), (101, 10, "b"), (102, 13, "a"), (104, 11, "b"))

是否可以将该字段放在另一个具有 ParentID 和 baz.anotherValue 的表中,而不是将其包含在具有 childID 的表中?

像这样:

Parent (ParentID) 
       (1, 2)
Child (ChildID, ParentID) 
       ((10, 1), (11, 1), (13, 2))
GrandChild (GCID, ChildID, ...) 
       ((100, 10, ...), (101, 10, ...), (102, 13, ...), (104, 11, ...))
AnotherChildValue (ParentID, AnotherVal)
       ((1, "a"), (1, "b"), (2, "a"), (1, "b"))

Just restating using different names:

Parent (ParentID) 
       (1, 2)
Child (ChildID, ParentID) 
       ((10, 1), (11, 1), (13, 2))
GrandChild (GCID, ChildID, GCAndParentVal) 
       ((100, 10, "a"), (101, 10, "b"), (102, 13, "a"), (104, 11, "b"))

Could you have that field in another table with the parentID and baz.anotherValue instead of including it in the table with the childID?

like this:

Parent (ParentID) 
       (1, 2)
Child (ChildID, ParentID) 
       ((10, 1), (11, 1), (13, 2))
GrandChild (GCID, ChildID, ...) 
       ((100, 10, ...), (101, 10, ...), (102, 13, ...), (104, 11, ...))
AnotherChildValue (ParentID, AnotherVal)
       ((1, "a"), (1, "b"), (2, "a"), (1, "b"))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文