SQLite是否真的不保留默认的外键约束的数据完整性?

时间:2013-07-09 14:52:30

标签: sqlite

较新版本的SQLite support foreign key constraints。可以定义

CREATE TABLE MASTER (_ID INTEGER PRIMARY KEY, ...);
CREATE TABLE SERVANT (_ID INTEGER PRIMARY KEY, MASTERID INTEGER, 
  FOREIGN KEY(MASTERID) REFERENCES MASTER(_ID);

根据默认情况下的文档,“NO ACTION”用于ON DELETE和ON UPDATE。但与其他DBS“NO ACTION”相反,似乎并不意味着,不执行删除或更新。这似乎意味着没有采取任何措施来保持诚信,至少根据我的测试(*)并且如果我理解documentation权利:

  

配置“NO ACTION”意味着:修改父键时   或从数据库中删除,不采取任何特殊行动。

因此

INSERT INTO MASTER (_ID) VALUES (1);
INSERT INTO SERVANT (_ID, MASTERID) VALUES (1,1);
DELETE FROM MASTER;

给了我一个空的MASTER表和一个指向无处的外键的SERVANT表。

任何人都可以确认这种行为并解释为什么以这种方式实施?或者我必须配置一些东西来使外键支持工作? 我是SQLite开发的新手,所以请原谅我,如果这是一个愚蠢的问题。

编辑:(*)我的测试存在缺陷,请参阅my answer below

2 个答案:

答案 0 :(得分:2)

我会尽力给自己一个答案:

不,如果配置正确,SQLite会在这种情况下保持数据完整性。默认情况下使用“NO ACTION”,如果仍存在来自引用表的引用键(使用3.7.x测试),则禁止删除或更新主密钥。 我的错是我不知道必须为每个新数据库连接配置PRAGMA foreign_keys = ON;

修改:我认为SQLite文档在这里misleading

答案 1 :(得分:0)

你是对的。 “NO ACTION”意味着没有做任何事情来保持外键约束的完整性。有关您可以设置的选项的详细信息,请参阅the documentation

您可以在此方案中设置其他4个选项。 RESTRICT,SET NULL,SET DEFAULT和CASCADE。它们的作用简要说明:

RESTRICT - 只有在SERVANT表中没有任何行引用MASTER表中的行时,才能删除该行。

SET NULL - 删除MASTER表中的行将导致SERVANT表中的任何FK设置为​​NULL。

SET DEFAULT - 与set NULL类似,只是FK设置为​​默认值而不是NULL。

CASCADE - 删除MASTER表中的行将导致SERVANT表中引用已删除的MASTER行的任何行也被删除。

要更改这些选项,您必须修改create语句以指定更新和删除操作。

CREATE TABLE MASTER (
  _ID INTEGER PRIMARY KEY, 
  ...
);
CREATE TABLE SERVANT (
  _ID INTEGER PRIMARY KEY, 
  MASTERID INTEGER, 
  FOREIGN KEY(MASTERID) REFERENCES MASTER(_ID) ON UPDATE CASCADE ON DELETE SET NULL
);

修改: 不要忘记确保您的SQLite版本是使用外键支持编译的,并且您已通过指定PRAGMA foreign_keys = ON;

来启用它