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

时间:2009-12-15 13:07:16

标签: mysql foreign-keys

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

w3school中说,

  

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

还有WHERE,

WHERE id = page_id

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

10 个答案:

答案 0 :(得分:38)

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

  1. 作为对表的约束,阻止你插入一些不指向任何东西的东西;
  2. 作为优化器的线索;和
  3. 由于历史原因,更需要更多。
  4. (1)可能是三者中最重要的一个。这称为referential integrity。这意味着如果外键中有一个值,则会有一个相应的记录,该值作为父表中的主键。

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

答案 1 :(得分:7)

外国人用于参照完整性。

请参阅An introduction to foreign keys and referential integrity in MySQL

答案 2 :(得分:5)

  

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

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

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

SELECT  *
FROM    Goods
JOIN    PriceRange
ON      PriceRange.Price =
        (
        SELECT  MAX(Price)
        FROM    PriceRange
        WHERE   PriceRange.Price <= Goods.Price
        )

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

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

但是,pk-to-pk绑定仍然很重要。 FOREIGN KEY可以确保您链接的权限由关系模型描述。

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

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

说,这个查询:

SELECT  f.*
FROM    t_foreign f
WHERE   f.pid IN
        (
        SELECT  id
        FROM    t_primary p
        )
如果在t_primaryFOREIGN KEY之间定义t_foreign关系,

甚至不会查看t_primary

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

答案 3 :(得分:2)

维护referential integrity并编制索引。

答案 4 :(得分:1)

WHERE子句的主要用途是限制查询返回的行。请参阅SELECT Syntax

主键/外键关系维护参照完整性,并通过适当的索引提高查询性能。 (参见Pete OHanlon的上述解释和JOIN Types

答案 5 :(得分:1)

RESTRICT运算符(WHERE)与引用约束无关!

引自C. J. Date的Relational Database Dictionary

外键 R1 R2 成为relvars,不一定是不同的,让 K 成为关键对于 R1 。设 FK R2 标题的子集,以便存在可能为空的属性重命名序列,将 K 映射到 K '(比如),其中 K' FK 包含完全相同的属性。然后 FK 是外键

参照完整性松散地,如果相应的引用元组不存在,则不允许存在引用元组的规则。更确切地说,让 FK 成为某些引用relvar R2 的外键;让 K 成为相应引用的relvar R1 中的对应键,让 K' K 派生为在外键下描述。然后,参照完整性规则要求 R2 F 值中的 FK 值永远不会是 K'值的时间对于当时 R1 中的某些(必然是唯一的)元组。 R1 R2 这里分别是引用的relvar和引用的relvar,它们之间的约束是一个引用约束。

示例:在relvar SP中,{S#}{P#}是对应于relvars S和P中的键{S#}{P#}的外键, 分别。请注意,引用的relvar中与给定外键对应的键不需要特别是主键。

答案 6 :(得分:1)

我有另一个很好的理由将关键关系添加到数据库中。有各种代码生成器使用此信息从数据库生成对象模型。常用的一个值得注意的模式是ActiveRecord模式。如果没有关键关系,ActiveRecord模式将不知道您的数据库实体如何相关,因此它将生成一个不太有用的对象模型。

代码生成并不适用于每个软件项目。但是,它对大量项目很有帮助。如果你不使用代码生成,你至少应该自己去看它。

答案 7 :(得分:0)

外键用于维护引用完整性,而WHERE子句用于在SQL操作(如select)中将表连接在一起。 where子句可以跨多个表操作,但它纯粹是作为过滤器。

严格地说,你可以在没有参照完整性的情况下逃脱,但这不是一个好主意。如果没有引用完整性,您最终会依赖于您的客户端应用程序,而不会错误地删除或更新关系链一端会对数据产生影响的内容,例如:将键值更改为指向不存在的值。

参照完整性是确保以一致方式保存相关数据的好方法。

答案 8 :(得分:0)

FOREIGN KEY约束用于防止会破坏表之间链接的操作。

FOREIGN KEY约束还可以防止将无效数据插入到外键列中,因为它必须是它指向的表中包含的值之一。

答案 9 :(得分:-1)

首先。好问题!!

MySql是一个RDBMS - 关系型DBMS,因此所有实体(表)都是按列相关的。

EMPLOYEE - EMPID EMPNAME DEPTID

DEPARTMENT - DEPTID DEPTNAME

DEPTID是EMPLOYEE表中的foriegn键和DEPARTMENT表中的主键。

这种关系是对象的虚构关系,只是一种考虑或类型的设计,用于构建数据,以便于将来检索。不是物理关系(因为它是一种编程语言)

为了检索这些数据,我们需要很少的语法,并由SQL的创建者描述。

来自EMPLOYEE的SELECT *

SELECT * FROM DEPARTMENT

SELECT * FROM EMPLOYEE WHERE DEPTID = 5

这里我们已经考虑了两个想象中的表格,但是对于所需的结果,我们使用了这个语法WHERE DEPTID = 5.