如果我可以使用WHERE,为什么需要使用外键?

shi*_*hin 36 mysql foreign-keys

关于MySQL中外键的初学者问题.

w3school它说,

一个表中的FOREIGN KEY指向另一个表中的PRIMARY KEY.

而且还有WHERE,

WHERE id = page_id
Run Code Online (Sandbox Code Playgroud)

因此,如果我可以使用WHERE来链接表,那么拥有外键的主要目的是什么?

cle*_*tus 40

查询并不严格要求,这是真的.它的存在有几个原因:

  1. 作为对表的约束,阻止你插入一些不指向任何东西的东西;
  2. 作为优化器的线索; 和
  3. 由于历史原因,更需要.

(1)可能是三者中最重要的一个.这称为参照完整性.这意味着如果外键中有值,则会有一个相应的记录,该值作为父表中的主键.

话虽这么说,并非所有数据库都支持参照完整性(例如MySQL/MyISAM表)和那些不一定强制执行它的数据库(出于性能原因).


Adr*_*der 7

外国人用于参照完整性.

请参阅MySQL中的外键和参照完整性简介


Qua*_*noi 5

因此,如果我可以使用WHERE来链接表,那么拥有外键的主要目的是什么?

因为WHERE子句不限于外键上的等值连接.

比如,如果您有一个描述价格范围和折扣的表,则使用此复杂条件来连接表:

SELECT  *
FROM    Goods
JOIN    PriceRange
ON      PriceRange.Price =
        (
        SELECT  MAX(Price)
        FROM    PriceRange
        WHERE   PriceRange.Price <= Goods.Price
        )
Run Code Online (Sandbox Code Playgroud)

您无法将这些表与外键关系链接,但您可以轻松加入它们.

有关详细信息,请参阅我的博客中的此条目:

然而,pk-to-pk绑定仍然很重要.A FOREIGN KEY可以向您保证,您链接的权利由关系模型描述.

使用FOREIGN KEY-backed设计,您无法声明与PRIMARY KEY描述该实体的表中不存在的实体的关系.

SQL Server 甚至可以将这一事实考虑在内并优化某些类型的查询.

说,这个查询:

SELECT  f.*
FROM    t_foreign f
WHERE   f.pid IN
        (
        SELECT  id
        FROM    t_primary p
        )
Run Code Online (Sandbox Code Playgroud)

甚至不会考虑t_primary如果FOREIGN KEY关系之间定义t_foreignt_primary.

有关详细信息,请参阅此文章: