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);

注1:这来自这个答案

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

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

参考:

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

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

4

5 回答 5

4

我知道一些 DBMS 在涉及具有外键约束的外键时根本不会强制执行参照完整性。想到了 SQLite。这里谈到了。

其他 DBMS 是不同的,我知道如果你尝试这样的事情,MS SQL Server 会抱怨。

SQLite 有它的用途,但它并不意味着在高并发情况下使用。如果您在不同的 DBMS 中看到此行为,请检查他们的文档以查看他们是否做了类似的事情。然而,大多数应该强制执行完整性。

于 2009-02-06T07:42:42.450 回答
2

至少你的 DEV 使用相当标准的 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.
于 2009-02-06T08:39:39.340 回答
1

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.

于 2009-02-26T03:00:10.823 回答
0

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

早期的 SQL 标准 (SQL86) 没有参照完整性,而 SQL89 级别 2 修复了该问题。

于 2009-02-06T07:49:05.323 回答
0

尝试添加此声明:

alter table prova_b 添加主键 (a,b);

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

这是你想做的吗?

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

于 2009-02-06T10:44:54.563 回答