Внешний ключ MySql, как он на самом деле работает - PullRequest
1 голос
/ 10 января 2012

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

Допустим, у меня есть 2 таблицы:

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

AND

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

Я знаю, что должен использовать vendor_id (int), но это всего лишь пример, чтобы помочь мне задать мой вопрос.

Итак: если я создаю поставщика: Apple, и продукт: 1, iPhone 4, Description.., Тогда Apple, то варчар «Apple» будет храниться как в продуктах, так и в поставщиках, или просто в поставщиках (из-за внешнего ключа)?Это неправильный дизайн БД?

Ответы [ 2 ]

2 голосов
/ 10 января 2012

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

  1. Чтобы у products был внешний ключ для vendors, vendors нужен ключ. Является ли name первичным ключом для vendors? Если это так, то внешний ключ также будет varchar. В этом случае, да, значение «Apple» будет храниться в обоих. (Обратите внимание, что это не очень хорошая идея.)
  2. Если вы добавите в таблицу vendors целочисленный столбец vendor_id и это будет первичный ключ этой таблицы, то вы можете добавить столбец 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 голос
/ 10 января 2012

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...