Внешние ключи SQL с несколькими таблицами

Если у меня есть три таблицы:

music_genres
-----------
music_type_id
genres
[other unique fields]

minerals
--------
mineral_id
mineral
[other unique fields]

verbs
-----
verb_id
verbs
[other unique fields]

и они заполнены:

rock
jazz
funk
punk

rock
boulder
stone
shale

rock
wobble
shake
vibrate

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

pages
-----
page_id
page_url
template_url
foreign_key_id

с такими данными, как:

/page/music-genres/rock/
/music-genres-template.html
1

/page/verbs/rock/
/verb-template.html
1

/page/minerals/rock/
/mineral-template.html
1

/page/minerals/rock/images/
/mineral-images-template.html
1

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

  • Эмуляция каскадных удалений с помощью триггеров
  • Сохранение типа элемента в каждой строке таблиц music_types, минералов и глаголов и использование этого дополнительного внешнего ключа
  • Сохранение соответствующего имени таблицы в таблице страниц
  • Поддержание целостности базы данных с помощью PHP и т. Д.

Я думаю, что должен быть лучший способ хранения моих данных или поддержания целостности базы данных. Есть предположения?


person jetboy    schedule 26.09.2009    source источник
comment
Итак, у вас есть некоторые, которые вы не показываете, которые генерируют первичный ключ, к которому относятся эти внешние ключи? Значит, во всех трех таблицах используется один и тот же ключ для слова «рок»?   -  person James Black    schedule 26.09.2009
comment
Точно. В этом случае столбец автоинкремента MySQL. Сценарий, очевидно, гипотетический, но он показывает, что я не могу полагаться на то, что другой столбец будет уникальным для всех трех таблиц, которые можно использовать для создания составного ключа.   -  person jetboy    schedule 26.09.2009


Ответы (1)


Я думаю, что твоя проблема здесь

Шаблоны будут знать, что внешний ключ относится к конкретной связанной таблице,

Это знание, которое нигде не хранится в базе данных.

Я вижу два выхода из этого:

  1. Учитывая, что вы фактически создаете отдельные таблицы для каждого типа «вещи», у вас должен быть отдельный столбец для каждого типа вещей, ссылающийся на соответствующую таблицу в вашей таблице страниц, установив для всех столбцов значение NULL, кроме одного (это может быть принудительно выполнено с помощью ограничение)

  2. Имейте таблицу «основных вещей» с уникальным идентификатором, на который затем страницы могут ссылаться, имея как столбец для определения типа, так и столбец, указывающий на остальные уникальные данные, которые будут храниться в другой таблице.

person Vinko Vrsalovic    schedule 26.09.2009
comment
Спасибо Винко. Да вот в чем проблема. 1. Потенциально много потраченного впустую места. Звучит нормально для 3-х столов, но беспорядочно для 30 или даже 300! 2. Не могли бы вы дать мне представление о том, как этого можно достичь? - person jetboy; 26.09.2009
comment
создавать табличные вещи (id int, type int); создать скалы таблицы (id int ссылается на вещи (id) при каскаде удаления, имя varchar, ...); создавать страницы таблиц (id int ссылается на вещи (id) при каскаде удаления, ...); - person Vinko Vrsalovic; 27.09.2009
comment
Я могу ошибаться здесь, потому что мне трудно это представить, но таким образом, если я удалю «вещь», она, в свою очередь, будет каскадно удалять связанные минералы и страницы? Это не то, что мне нужно. Я хочу удалить минерал и, в свою очередь, удалить связанные вещи и страницы. Я могу перемещать внешние ключи, чтобы разрешить это, но я не вижу, как я могу заставить эту работу работать с глаголами и таблицами типов музыки, добавленными в микс. - person jetboy; 27.09.2009
comment
Нет, не обращай на меня внимания, я думаю, что понял. Никакие строки в минералах, глаголах или музыкальных типах не могут иметь одинаковый идентификатор, потому что их идентификаторы создаются с помощью things.id? Итак, чтобы вставить новый минерал, мне нужно было бы вставить новую «вещь», взять LAST_INSERT_ID, а затем вставить расширенные данные в таблицу минералов с этим LAST_INSERT_ID в качестве первичного ключа? - person jetboy; 27.09.2009