Дизайн базы данных: использовать не ключ в качестве FK? - PullRequest
0 голосов
/ 01 апреля 2011

Допустим, у меня есть следующая таблица:

TABLE: widget
 - widget_id (not null, unique, auto-increment)
 - model_name (PK)
 - model_year (PK)

model_name и model_year составляют составной ключ.Есть ли проблемы с использованием widget_id в качестве FK в другой таблице?

Ответы [ 4 ]

1 голос
/ 01 апреля 2011

Ключ - это любое количество столбцов, которое можно использовать для уникальной идентификации каждой строки в таблице.

В приведенном вами примере таблица виджетов имеет два ключа:

  • model_name, model_year
  • widget_id

В стандартном SQL внешний ключ может ссылаться на любой объявленный ключ в ссылочной таблице (первичный ключ или уникальный).Мне нужно проверить соответствие MySQL.


Из справочного руководства MySQL по внешним ключам :

InnoDB позволяет внешнему ключу ссылаться на любой индексстолбец или группа столбцов.Однако в ссылочной таблице должен быть индекс, в котором указанные столбцы перечислены как первые столбцы в том же порядке.


В качестве альтернативы, если вы хотите использовать составнойключ из вашей ссылочной таблицы, у вас будет две колонки в этой таблице, которые соответствуют model_name и model_year, а затем объявите ограничение внешнего ключа как:

ALTER TABLE OtherTable ADD CONSTRAINT
     FK_OtherTable_Widgets (model_name,model_year)
     references Widgets (model_name,model_Year).

Re InnoDB против MyISAM, вдокументы для ALTER TABLE

Предложения FOREIGN KEY и REFERENCES поддерживаются механизмом хранения InnoDB, который реализует ADD [CONSTRAINT [symbol]] FOREIGN KEY (...)РЕКОМЕНДАЦИИ ... (...).См. Раздел 13.6.4.4, «Ограничения FOREIGN KEY».Для других механизмов хранения пункты разбираются, но игнорируются.Предложение CHECK анализируется, но игнорируется всеми механизмами хранения.См. Раздел 12.1.17, «Синтаксис CREATE TABLE».Причиной принятия, но игнорирования синтаксических предложений является совместимость, упрощение переноса кода с других серверов SQL и запуск приложений, создающих таблицы со ссылками.См. Раздел 1.8.5, «Отличия MySQL от стандартного SQL».

0 голосов
/ 01 апреля 2011

Допустим, у вас есть две таблицы. Первая таблица выглядит так:

TABLE: widget
 - model_name (PK)
 - model_year (PK)
 - widget_id (not null, unique, auto-increment)

Если вы хотите создать другую таблицу, которая ссылается на уникальные записи в первой таблице, она должна выглядеть примерно так:

TABLE B: sprocket
 - part_number (PK)
 - blah
 - blah
 - model_name_widget (FK to widget)
 - model_year_widget (FK to widget)
 - blah 

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

0 голосов
/ 01 апреля 2011

MySQL создаст индекс для столбца, если он не может быть использован:

InnoDB требует индексов для внешних ключей и ссылочных ключей, чтобы проверка внешних ключей могла быть быстрой и не требоватьсканирование таблицы.В ссылочной таблице должен быть индекс, в котором столбцы внешнего ключа перечислены как первые столбцы в том же порядке.Такой индекс создается в ссылочной таблице автоматически, если он не существует.(Это отличается от некоторых более старых версий, в которых индексы должны были создаваться явно, иначе создание ограничений внешнего ключа не удавалось.) Index_name, если дано, используется, как описано ранее.

http://dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html

0 голосов
/ 01 апреля 2011

У меня нет опыта, специфичного для my-sql, но с моделированием базы данных в целом

Очень важно понимать разницу между первичным и вторичным ключами.Даже если многие базы данных (я точно знаю, что это делает Oracle) разрешают указывать уникальный (простой или составной) ключ в качестве цели FK, это не считается наилучшей практикой.Вместо этого используйте PK.

FK для вторичного ключа следует использовать imo только для того, чтобы относиться к таблицам, которые не находятся под вашим контролем.

В вашем конкретном случае я бы определенно передал FK to widget_id:это потому, что widget_id должен быть вашим PK, а составная часть только сделана уникальной (и, конечно, не нулевой).Это приводит к повышению производительности в гривневых случаях, поскольку вы присоединяете только один столбец в запросах, и, как правило, считается оптимальной практикой (Google суррогатный ключ для получения дополнительной информации)

...