2011-08-04 108 views
16

我试图设置一个SQLite3数据库foo s和bar s和他们之间的多对多关系。这是我到目前为止:SQLite多对多的关系?

CREATE TABLE foo(
    id INTEGER PRIMARY KEY NOT NULL, 
    foo_col INTEGER NOT NULL 
); 
CREATE TABLE bar(
    id INTEGER PRIMARY KEY NOT NULL, 
    bar_col TEXT NOT NULL 
); 
CREATE TABLE foobar(
    foo_id INTEGER, 
    bar_id INTEGER, 
    FOREIGN KEY(foo_id) REFERENCES foo(id) ON DELETE CASCADE, 
    FOREIGN KEY(bar_id) REFERENCES bar(id) ON DELETE CASCADE 
); 
CREATE INDEX fooindex ON foobar(foo_id); 
CREATE INDEX tagindex ON foobar(tag_id); 

...但它似乎并没有工作。我可以从foo删除一行,但不会影响foobar。我究竟做错了什么?

回答

13

来自这个网站,http://www.sqlite.org/foreignkeys.html

假设库已启用外键约束编译,它仍然必须由应用程序在运行时使用PRAGMA foreign_keys命令启用。例如:

sqlite> PRAGMA foreign_keys = ON; 

外键约束默认(向后兼容)禁用,所以必须分别对每个数据库连接单独启用。 (但是,请注意,未来的SQLite版本可能会更改,以便默认情况下启用外键约束。仔细的开发人员不会假定是否默认启用外键,而是根据需要启用或禁用它们。)应用程序也可以使用PRAGMA foreign_keys语句来确定当前是否启用了外键。下面的命令行会话演示此:

sqlite> PRAGMA foreign_keys; 
0 
sqlite> PRAGMA foreign_keys = ON; 
sqlite> PRAGMA foreign_keys; 
1 
sqlite> PRAGMA foreign_keys = OFF; 
sqlite> PRAGMA foreign_keys; 
0 

提示:如果命令“PRAGMA foreign_keys”没有返回数据而不是包含“0”或“1”的单个行的,然后SQLite的版本使用的是不支持外键(或者是因为它早于3.6.19,或者是因为它是使用SQLITE_OMIT_FOREIGN_KEY或SQLITE_OMIT_TRIGGER定义的)编译的。

无法在多语句事务中启用或禁用外键约束(当SQLite未处于自动提交模式时)。试图这样做不会返回错误;它根本没有效果。

+0

表foobar也可能需要(foo_id,bar_id)上的主键约束。但这是一个不同的问题。 –

+0

@Catcall:随时评论我的帖子。 – wes

+0

ace的答案,直接来自SQLite文档,是准确和完整的。但正如我所说,表foobar也需要'PRIMARY KEY(foo_id,bar_id)'。 –