2015-01-12 4 views
1

Предположим, у меня есть 2 стола: foo и бар.Неудачные внешние ключи - хорошая или плохая практика?

В третьей таблице я хочу хранить различные виды данных, однако каждая строка будет иметь ссылку на любой Foo ИЛИ бар.

Правомерно ли я создать 2 NULL способные внешние ключи - foo_id и bar_id - в третьей таблице, или это againts принципы проектирования баз данных?

В принципе, я думал, что все внешние ключи должны ВСЕГДА иметь «родительский», поэтому, если я попытаюсь, например, INSERT строка без согласования первичного ключа (или в этом случае с внешним ключом, установленным на NULL), я получу ошибку. Nullable FK-s новы для меня, и они чувствуют себя немного отключенными.

Кроме того, какие альтернативы? Лучше ли создавать отдельные таблицы, хранящие одну ссылку? Разве это не создает избыточность?

Ссылки на таблицы?

Помощь.

+0

Я получаю то, о чем вы просите, но для будущей диаграммы UML сказано более 1000 слов. – Yoda

+2

Я стараюсь * избегать * nullable FK's - насколько это практически возможно. Хороший механизм базы данных (выбирайте, подходит ли MySQL в этой категории) не имеет проблем с «лишними» таблицами соединений для представления этого правила множественности. Использование другой таблицы, безусловно, * не * неявно нарушает нормализацию или «правила базы данных», но для этого требуется другой подход к запросам и структуре, хотя я рекомендую преследовать. (Что касается избыточности: для этого должны быть избыточные данные и/или функциональные зависимости, добавление «таблицы ссылок» не означает также.) – user2864740

+0

@ user2864740 Спасибо за это, очень полезно. – lesssugar

ответ

3

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

Альтернативой является две таблицы ссылок, одна для foo и одна для bar.

вещи, чтобы рассмотреть: столы

  • Link позволяют 1: N. Если вы этого не хотите, вы можете принудительно выполнить его с помощью первичного ключа в таблице ссылок. Это не обязательно для решения столбца id (они всегда 1: N).

  • Вы можете избежать столбцов с значениями NULL с использованием таблиц ссылок. В вашем случае, однако, кажется, что у вас есть NULL для половины значений. Вероятно, он не квалифицируется как «в основном». Это становится более интересным с более чем двумя родительскими таблицами.

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

+0

Спасибо. В настоящее время для этой цели я использую две таблицы ссылок, однако для этого требуется более сложный подход запроса и т. Д. Я не смог полностью получить третий элемент в вашем списке. Вы имеете в виду установку составного индекса для двух внешних ключей, чтобы убедиться, что хотя бы один из них всегда «NULL»? – lesssugar

+0

Не индекс, просто ограничение 'CHECK'. http://www.w3schools.com/sql/sql_check.asp – Thilo

+0

Я вижу, аккуратный. Прерывает ли «CHECK» ошибку или терпит неудачу, пока, например, 'INSERT'ing? – lesssugar

0

это зависит от бизнес-логики программы. если поле внешнего ключа должно иметь значение, плохо установить его с нулевым значением.

например. таблица книг имеет category_id поле, значение которого является ссылкой от bookCategory стол.

каждая запись в таблице книг должна иметь категорию. если по какой-то причине вы установите его как NULL. это вызовет некоторую запись в таблице книг с category_id.

проблема будет отображаться в отчете.следующие два запроса будет возвращать разные total_book

select count(*) as total_book from book; 

select 
    count(*) as total_book 
from 
    book 
    inner join bookCategory 
     on book.category_id = category.id 

мой совет не использовать нуль-состоянии, если вы не ожидаете стоимость и не стоимость. много сложной системы, которая когда-то имеет значение, отличное от одного отчета, и другое, как правило, является причиной этого.