14

我希望有人可以向我解释 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 是否只是为了提高查询速度?它的真正目的是什么?

谢谢

4

2 回答 2

14

它创建另一个表的外键。这可以带来性能优势,但外键主要与数据完整性有关。这意味着(在您的情况下)wizard_id字段的powers值必须存在于表的id字段中wizards。换句话说,权力必须是指一个有效的巫师。许多数据库还使用此信息来传播删除或其他更改,因此表保持同步。

才注意到这一点。您能够绕过键约束的一个原因可能是未启用外键。请参阅SQLite3 文档中的启用外键

于 2013-10-04T16:42:19.190 回答
0

从我收集到的信息来看,使用 有两个主要好处REFERENCES,并且在使用和不使用它之间有一个重要的区别FOREIGN KEY

它为 DBMS 提供了优化空间

如果不使用 REFERENCES,SQLite 将不知道属性id和属性wizard_id在功能上是等效的。您可以为数据库管理系统(在本例中为 SQLite)定义的已知约束越多,它在优化其在后台处理数据的方式方面的自由度就越大。

它可以强制或鼓励良好做法

参考声明也可用于执行和警告规定。例如,假设您有两个表AB,并且您假设它A.name在功能上等同于B.name,因此您尝试连接:SELECT * FROM A, B WHERE A.name = B.name。如果 REFERENCE 从未用于指示这两个属性之间的功能等效性,则 DBMS 可能会在您进行连接时向您发出警告,这在这些属性恰好具有相同名称但实际上并不代表一样。

REFERENCES并不总是创建“外键”

与已经建议的相反,引用和外键不是一回事。引用声明属性之间的功能等效性。外键是指另一个表的主键。

编辑:@IanMcLaird 纠正了我:使用REFERENCES确实总是创建某种外键,尽管这与外键的流行定义相冲突,即“表中引用另一个表的主键的一组属性” (维基百科)。

使用REFERENCESwithoutFOREIGN 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。两者都假设您想按照上面提供的流行定义创建外键;两者都创建表级外键

第二个说法很棘手。如果指定一个属性是 的主键Drivers,DBMS 可能会选择创建一个表级外键。但指定的属性不必的主键Drivers,如果不是,DBMS 将创建列级外键。对于那些第一次接触数据库并学习不太灵活、流行的“外键”定义的人来说,这有点不直观。

有些人可能会使用这三个语句,就好像它们是相同的,并且在许多一般用例中它们可能在功能上相同,但它们并不相同。

说了这么多,这只是我的理解。我不是这方面的专家,非常感谢补充、更正和肯定。

于 2021-04-30T01:01:48.853 回答