为什么这种外键是可能的?

发布于 2024-07-13 10:21:49 字数 1160 浏览 4 评论 0原文

为什么 SQL 标准接受这一点? 有哪些好处?

如果有这些表:

create table prova_a (a number, b number);
alter table prova_a add primary key (a,b);
create table prova_b (a number, b number);
alter table prova_b add foreign key (a,b) references prova_a(a,b) ;
insert into prova_a  values (1,2);

您可以插入这个而不会出现错误:

insert into prova_b  values (123,null);
insert into prova_b  values (null,123);

Note1:这来自于答案

注意2:这是可以避免的,在两列上设置不为空。

备注:我不是在问避免,我感兴趣的是有哪些好处。

参考资料:

  • Oracle 文档关系模型允许外键的值与引用的主键或唯一键值匹配,或者为空。 如果复合外键的任何列为空,则该键的非空部分不必与父键的任何相应部分匹配。

  • SQL Server 文档FOREIGN KEY 约束可以包含空值; 但是,如果复合 FOREIGN KEY 约束的任何列包含空值,则将跳过对组成 FOREIGN KEY 约束的所有值的验证。

Why does the SQL Standard accept this? Which are the benefits?

If have those tables:

create table prova_a (a number, b number);
alter table prova_a add primary key (a,b);
create table prova_b (a number, b number);
alter table prova_b add foreign key (a,b) references prova_a(a,b) ;
insert into prova_a  values (1,2);

You can insert this without error:

insert into prova_b  values (123,null);
insert into prova_b  values (null,123);

Note1: This comes from this answer.

Note2: This can be avoid, setting not null on both columns.

Remarks: I'm not asking about avoid, I'm interested on which are the beneficts.

References:

  • Oracle documentation: The relational model permits the value of foreign keys to match either the referenced primary or unique key value, or be null. If any column of a composite foreign key is null, then the non-null portions of the key do not have to match any corresponding portion of a parent key.

  • SQL Server documentation: A FOREIGN KEY constraint can contain null values; however, if any column of a composite FOREIGN KEY constraint contains null values, verification of all values that make up the FOREIGN KEY constraint is skipped.

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

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

发布评论

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

评论(5

波浪屿的海角声 2024-07-20 10:21:49

我知道一些 DBMS 在涉及具有外键约束的外键时根本不强制执行引用完整性。 我想到了 SQLite。 此处对此进行了讨论。

其他 DBMS 有所不同,我知道如果您尝试类似的操作,MS SQL Server 会抱怨。

SQLite 有它的用途,但它并不适合在高并发情况下使用。 如果您在不同的 DBMS 中看到此行为,请检查他们的文档,看看他们是否做了类似的事情。 然而,大多数人应该加强诚信。

I know some DBMSs simply don't enforce referential integrity when it comes to foreign keys with foreign key constraints. SQLite comes to mind. It's talked about here.

Other DBMSs are different, I know that MS SQL Server will complain if you attempt something like that.

SQLite has its uses but it is not meant to be used in high-concurrency situations. If you are seeing this behavior in a different DBMS, check their documentation to see if they did something similar. Most should be enforcing integrity however.

寄居者 2024-07-20 10:21:49

至少让你的开发工作使用一个相当标准的 RDBMS,即使你正在使用 SQLite(这是一个优秀的数据库 - 它在你的 Ipod touch 中运行!)之类的东西来处理你的生产系统,它会清除所有这些错误 - 就像 Lint 真的一样。 如果您使用可以免费下载的 SQL Server Express 运行代码,您将收到大量错误,例如...

Msg 8111, Level 16, State 1, Line 2
Cannot define PRIMARY KEY constraint on nullable column in table 'prova_a'.
Msg 1750, Level 16, State 0, Line 2
Could not create constraint. See previous errors.

at least do your DEV work with a reasonably standard RDBMS, even if you are doing your production system with something like SQLite (which is an excellent database- it runs in your Ipod touch!) It will flush out all these mistakes- like Lint really. If you run your code with SQL Server Express, which you can download for free, you'll get plenty of errors such as...

Msg 8111, Level 16, State 1, Line 2
Cannot define PRIMARY KEY constraint on nullable column in table 'prova_a'.
Msg 1750, Level 16, State 0, Line 2
Could not create constraint. See previous errors.
神也荒唐 2024-07-20 10:21:49

Oracle 和 SQL Server 都允许 NULL 外键,并且很容易理解为什么这是必要的。
例如,考虑一棵树,其中每一行都有一个引用同一个表的主键的父键。 树中必须有一个没有父节点的根节点,并且父节点键将为空。
一个更具体的例子:想想员工和经理。 公司里有些人,如果只有CEO,就不会有经理。 如果无法将员工表上的经理 ID 设置为 NULL,则必须创建一个“无经理”员工 - 这是错误的,因为它没有现实生活中的对应关系。

现在我们知道了这一点,复合键的行为原因就很明显了。 从逻辑上讲,如果组合的一部分为 NULL,则整个键为 NULL。 如果其中一个字符串为 NULL,则字符串连接将返回 NULL。 不可能存在匹配,并且在这些情况下不强制执行约束。

Oracle and SQL Server both allow NULL foreign keys, and it is easily understandable why this is necessary.
Think of a tree, for instance, where every row has a parent key that references the primary key of the same table. There has to be a root node in the tree that does not have a parent, and the parent key will be null.
A more tangible example: think of employees and managers. Some people in the company, and if it is only the CEO, will not have a manager. Were it not possible to set the manager id on the employee table to NULL, you would have to create a "No Manager" employee - something that is just wrong, because it has no real-life correspondence.

Now that we know this, it is obvious why your composite keys behave like they do. Logically, if part of the composite is NULL, the entire key is null. A string concatenation returns NULL if one of the pieces is NULL. There cannot be a match, and the constraint is not enforced in these cases.

踏月而来 2024-07-20 10:21:49

SQL 标准不接受这一点; 您发现了一个不强制执行引用完整性的 DBMS。 如果您够聪明,请立即卸载它。 至少不要将其用于生产目的。

早期的 SQL 标准 (SQL86) 没有引用完整性,而 SQL89 级别 2 修复了这个问题。

The SQL standard doesn't accept this; you've found a DBMS that doesn't enforce referential integrity. Uninstall it now if you're smart. At a bare minimum, don't use it for production purposes.

Earlier SQL standards (SQL86) had no referential integrity and SQL89 level 2 fixed that.

巷子口的你 2024-07-20 10:21:49

尝试添加此声明:

alter table prova_b add Primary key (a,b);

这将禁止 prova_b 中的 NULL。 它还将禁止重复条目。 在Oracle和SQL Server中,它也会创建索引。 该索引将加快查找和连接速度,但代价是稍微减慢插入速度。

这是你想做的吗?

至于为什么标准 SQL 会让你做一些你认为愚蠢的事情,这是一个哲学问题。 大多数工具都允许一些愚蠢的选择。 试图禁止所有愚蠢选择的工具通常最终会无意中禁止一些真正明智的选择。

Try adding this declaration:

alter table prova_b add primary key (a,b);

This will forbid NULLS in prova_b. It will also forbid duplicate entries. In Oracle and SQL server, it will also create an index. This index will speed up lookups and joins, at the cost of slowing down inserts a tiny bit.

Is this what you want to do?

As to why standard SQL lets you do something you consider stupid, that's a philosophical question. Most tools allow some stupid choices. Tools that try to forbid all stupid choices generally end up forbidding some really smart choices unintentionally.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文