我希望有人可以向我解释SQL关键字REFERENCES
的目的CREATE TABLE wizards(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,
age INTEGER
, color TEXT);
CREATE TABLE powers(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name STRING,
damage INTEGER,
wizard_id INTEGER REFERENCES wizards(id)
);
我花了很多时间试图查看这个,我最初认为它会限制你可以输入到powers表中的数据类型(根据是否为wizard_id)但是,我仍然可以插入数据进入两列而没有任何我注意到的约束。
那么,关键字REFERENCES是否只是为了提高查询速度?它的真正目的是什么?
由于
答案 0 :(得分:10)
它为另一个表创建Foreign Key。这可以带来性能优势,但外键主要是关于数据完整性。这意味着(在您的情况下)wizard_id
的{{1}}字段必须具有powers
表的id
字段中存在的值。换句话说,权力必须指向有效的向导。许多数据库也使用此信息来传播删除或其他更改,因此表保持同步。
注意到这一点。您能够绕过键约束的原因可能是未启用外键。请参阅SQLite3文档中的Enabling foreign keys。
答案 1 :(得分:0)
从我收集到的信息来看,使用 REFERENCES
有两个主要好处,并且在使用和不使用 FOREIGN KEY
之间有一个重要区别。
如果不使用 REFERENCES,SQLite 不会知道属性 id
和属性 wizard_id
在功能上是等效的。您可以为数据库管理系统(在本例中为 SQLite)定义的已知约束越多,它就越有自由来优化它在后台处理数据的方式。
引用声明也可用于强制执行和警告提供。例如,假设您有两个表,A
和 B
,并且您假设 A.name
在功能上等同于 B.name
,因此您尝试连接:{{1} }.如果 REFERENCE 从未用于指示这两个属性之间的功能等效性,则 DBMS 会在您进行连接时向您发出警告,这在这些属性仅碰巧具有相同名称但实际上并不代表同样的事情。
SELECT * FROM A, B WHERE A.name = B.name
并不总是创建“外键”与已经建议的相反,引用和外键不是一回事。 引用 声明属性之间的功能等效。 外键是指另一个表的主键。
编辑:@IanMcLaird 纠正了我:REFERENCES
的使用确实总是会创建某种外键,尽管这与外键的流行定义冲突,即“表中引用的一组属性到另一个表的主键”(Wikipedia)。
使用没有 REFERENCES
的 REFERENCES
可能会创建一个“列级外键”,其操作与“外键”的流行定义相反。
以下陈述之间存在差异。
FOREIGN KEY
第一条语句假定您想引用 driver_id INT REFERENCES Drivers
driver_id INT REFERENCES Drivers(id)
driver_id INT,
FOREIGN KEY(driver_id) REFERENCES Drivers(id)
的主键,因为没有指定属性。第三条语句要求 Drivers
是 id
的主键。两者都假设您想通过上面提供的流行定义创建外键;两者都创建一个表级外键。
第二个语句很棘手。如果指定作为 Drivers
主键的属性,DBMS 可以选择创建表级外键。但是指定的属性必须是Drivers
的主键,如果不是,DBMS会创建一个列级外键 .对于那些第一次接触数据库并了解不太灵活、流行的“外键”定义的人来说,这有点不直观。
有些人可能会像使用这三个语句一样使用它们,并且在许多一般用例中它们在功能上可能相同,但它们并不相同。
说了这么多,这只是我的理解。我不是这方面的专家,非常感谢补充、更正和肯定。