【问题标题】:Does SQLite really not preserve data integrity of foreign key constraints by default?默认情况下,SQLite 真的不保留外键约束的数据完整性吗?
【发布时间】:2013-07-09 14:52:29
【问题描述】:

较新版本的 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

【问题讨论】:

  • 我无法回答您的具体问题,但我发现 SQLite 文档在准确性和精确度方面优于平均水平(尽管经常找到您正在寻找的信息是挑战)。

标签: sqlite


【解决方案1】:

我会尽量自己回答:

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

编辑:我认为 SQLite 文档是 misleading 这里。

【讨论】:

    【解决方案2】:

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

    在这种情况下,您还可以设置 4 个其他选项。 RESTRICT、SET NULL、SET DEFAULT 和 CASCADE。简要说明他们的工作:

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

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

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

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

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

    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; 启用它

    【讨论】:

    • 感谢您的回答,但我认为这不是正确的答案。我仔细检查了我的设置,发现一个错误导致我的外键不起作用:PRAGMA foreign_keys = ON; 必须为每个新的数据库连接指定,而不仅仅是一次。更正此问题后,“NO ACTION”的行为符合预期 - 也许我误解了文档?
    • 你是对的。 PRAGMA foreign_keys = ON; 必须为每个连接指定。
    • 我已经发布了另一个问题来澄清“NO ACTION”的确切含义:stackoverflow.com/questions/17601702/…
    猜你喜欢
    • 2014-11-09
    • 1970-01-01
    • 2016-04-24
    • 1970-01-01
    • 1970-01-01
    • 2014-03-08
    • 2014-01-17
    • 1970-01-01
    相关资源
    最近更新 更多