MySql外键,它实际上是如何工作的

时间:2012-01-10 19:11:56

标签: mysql foreign-keys

也许有关外键的新手问题,但我想知道答案。

假设我有两张桌子:

products
--------
product_id (int)
name (unique) (varchar)
description (text)
vendor (varchar) (foreign key: vendors.name)

vendors
--------
name (varchar)

我知道我应该使用vendor_id (int),但这只是一个帮助我提出问题的例子。

所以:如果我创建供应商:Apple,产品:1,iPhone 4,描述..,Apple那么varchar“Apple”将存储在产品和供应商中,或仅存储在供应商中(因为外键) )? 这是一个错误的数据库设计吗?

2 个答案:

答案 0 :(得分:2)

这被称为"标准化"在数据库中。在您的示例中,有几件事需要考虑:

  1. 为了使products拥有vendors的外键,vendors需要一个密钥。 name的主键是vendors吗?如果是,则外键也是varchar。在那种情况下,是的,价值" Apple"将存储在两者中。 (请注意,这不是一个好主意。)
  2. 如果向vendor_id表添加vendors整数列,并且它是该表的主键,则可以添加vendor_id(或任何其他名称)列到products表并使其成为vendors表的外键。在这种情况下,只有那个整数将存储在两个表中。这是数据标准化的地方。一个较小的,更简单的数据类型(整数)链接表,其中包含描述记录的实际数据。
  3. 只有该键值存储在两个表中。它在选择数据时用作连接表的参考。例如,为了选择给定产品及其供应商,您可以执行以下操作:

    SELECT products.name, products.description, vendors.name AS vendor
    FROM products INNER JOIN vendors ON products.vendor_id = vendors.vendor_id
    WHERE products.product_id = ?id
    

    这将"加入"将两个表分成一个表(不是真的,仅用于查询)并从中选择记录。

答案 1 :(得分:1)

它将存储在两者中。外键约束要求products.vendor中的每个值都出现在vendor.name中的某个位置。

(顺便说一句,请注意,如果存储引擎是InnoDB,MySQL只会强制执行外键约束。)