2012-01-10 1 views
1

Может быть, вопрос новичков о внешних ключах, но я хочу знать ответ.Внешний ключ MySql, как это работает

Скажем, у меня есть 2 таблицы:

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, то варчар «Apple» будет храниться как в продуктах, так и в вендорах, или только у поставщиков (из-за иностранных ключ)? Это неправильный дизайн db?

ответ

2

Это называется «нормализация» в базе данных. В вашем примере, есть пара вещей, чтобы рассмотреть следующие вопросы:

  1. Для того, чтобы products иметь внешний ключ vendors, vendors нужен ключ. Действительно найден name первичный ключ для vendors? Если это так, то внешний ключ также будет varchar. В этом случае да, значение «Apple» будет сохранено в обоих случаях. (Обратите внимание, что это не очень хорошая идея.)
  2. Если вы добавите целочисленный столбец vendor_id в таблицу vendors, и это первичный ключ для этой таблицы, вы можете добавить vendor_id (или любое другое имя) столбец в таблицу products и сделать его внешним ключом для таблицы vendors. В этом случае только одно целое будет храниться в обеих таблицах. Здесь данные нормализуются. Небольшой, более простой тип данных (целое) связывает таблицы, содержащие фактические данные, которые описывают записи.

Только это значение ключа хранится в обеих таблицах. Он используется в качестве ссылки для объединения таблиц при выборе данных. Например, для того, чтобы выбрать данный продукт и его поставщика, вы могли бы сделать что-то вроде этого:

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

Он будет сохранен в обоих случаях. Ограничение внешнего ключа требует, чтобы каждое значение в products.vendor отображалось где-то в vendor.name.

(Кстати, обратите внимание, что MySQL только навязывает ограничения внешнего ключа, если двигатель хранения InnoDB.)