SQLite3中的REFERENCES关键字

时间:2013-10-04 16:33:37

标签: sql sqlite keyword

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

由于

2 个答案:

答案 0 :(得分:10)

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

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

答案 1 :(得分:0)

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

它为 DBMS 提供了优化空间

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

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

引用声明也可用于强制执行和警告提供。例如,假设您有两个表,AB,并且您假设 A.name 在功能上等同于 B.name,因此您尝试连接:{{1} }.如果 REFERENCE 从未用于指示这两个属性之间的功能等效性,则 DBMS 会在您进行连接时向您发出警告,这在这些属性仅碰巧具有相同名称但实际上并不代表同样的事情。

SELECT * FROM A, B WHERE A.name = B.name 并不总是创建“外键”

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

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

使用没有 REFERENCESREFERENCES 可能会创建一个“列级外键”,其操作与“外键”的流行定义相反。

以下陈述之间存在差异。

FOREIGN KEY

第一条语句假定您想引用 driver_id INT REFERENCES Drivers driver_id INT REFERENCES Drivers(id) driver_id INT, FOREIGN KEY(driver_id) REFERENCES Drivers(id) 的主键,因为没有指定属性。第三条语句要求 Driversid 的主键。两者都假设您想通过上面提供的流行定义创建外键;两者都创建一个表级外键

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

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

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