使用通配符值时的 SQL 唯一性约束
请考虑下表,其中指定了一周中特定日期禁止吃的水果。 DayOfWeek
可为空,其中 NULL 表示一周中的所有天禁止食用此类水果。
Fruit DayOfWeek
----------------------
Kiwi NULL
Apples Monday
Strawberries Monday
Oranges Tuesday
Bananas Wednesday
Pineapple Thursday
是否可以在此表上实现一个约束,阻止我插入值 (Kiwi, Monday)
,因为现有 ( 已在星期一(以及每隔一天)禁止新西兰人使用Kiwi, NULL)
行。
优选地,这应该在不使用触发器的情况下实现。
Consider the following table, which specifies fruit that is forbidden on given days of the week. DayOfWeek
is nullable, where a NULL signifies that this type of fruit is forbidden on all days of the week.
Fruit DayOfWeek
----------------------
Kiwi NULL
Apples Monday
Strawberries Monday
Oranges Tuesday
Bananas Wednesday
Pineapple Thursday
Is it possible to implement a constraint on this table that prevents me from inserting the values (Kiwi, Monday)
, since Kiwis are already banned on Mondays (and every other day) by the existing (Kiwi, NULL)
row.
Preferably this should be implemented without the use of triggers.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
除非你有充分的理由,否则你不应该改变 NULL 的含义。 Null 反映了一个值是未知的,所以我将其读为“我们不知道一周中的哪一天新西兰人被禁止”。然后,您可以更改逻辑来存储 Kiwi 被禁止的一周中的每一天的记录。
如果您需要编写一个查询,要求给我周一所有的禁果,该怎么办?您需要将查询编写为
select * from BadFruit where DayOfWeek='Monday' || DayOfWeek is null
更有效且更易于理解的查询将消除 or 子句。
Unless you have a really good justification you shouldn't change the meaning of NULL. Null reflects a value is unknown so I would read this as We don't know what day of the week kiwi's are banned. You would then change your logic to store a record for each day of the week that Kiwi is banned on.
What if you need to write a query which says give me all forbidden fruit for monday. You need to write your query as
select * from BadFruit where DayOfWeek='Monday' || DayOfWeek is null
A more efficent and easier to understand query would eliminate the or clause.
我同意其他人的观点,我可能会瞄准与您展示的模型不同的模型,但如果您对它感兴趣,那么以下似乎可以满足您的要求:
不确定排除表的 PK 是什么应该是,从您所显示的内容来看并不明显,但它旨在成为您的表格。我们需要引入
Weekdays
表以使后面的视图正常工作*。现在填充它:以及您的示例数据:
现在我们创建视图来实现您的约束:
并且,如果我们尝试插入您不希望我们插入的行:
我们得到:
*我最初尝试在不引入 < 的情况下执行此操作code>Weekdays 表,并将其内联显示在视图定义中,作为文字行的子选择。但是您无法创建对此类视图强制执行我们想要的约束的索引。
I agree with others that I probably would aim for a different model than the one you've shown, but if you're sold on it, then the following seems to do what you want:
Not sure what the PK is for the Exclusions table should be, not obvious from what you've shown, but it's intended to be your table. We need to introduce the
Weekdays
table to make the later view work*. Now populate it:And your sample data:
Now we create the view to implement your constraint:
And, if we try to insert the row you don't want us to:
We get:
*I initially tried to do this without introducing the
Weekdays
table, and have it appear inline in the view definition, as a subselect of literal rows. But you can't create the index that enforces the constraint we want on such a view.我个人不喜欢 NULL 意味着全部的想法,但将其更改为在 NULL 可能超出范围时每天包含一行。
如果触发器不是一个选项,我会查看检查约束并设置一个函数来测试您试图避免的条件。
I am personally not fond of the idea of NULL mean all, but changing this to include a row for each day when NULL is probably out of scope.
If a trigger is not an option, I would look at a CHECK CONSTRAINT and setting up a function that tests the condition you are trying to avoid.
尝试此链接 http://www.java2s.com/Code/SQL/ Select-Clause/SettingaUniqueConstraint.htm
对于 MySQL,您可以设置唯一的约束。
Try this link http://www.java2s.com/Code/SQL/Select-Clause/SettingaUniqueConstraint.htm
For MySQL you can set unique contraints.