Подтвердить что ты не робот

Несколько внешних ключей для одного столбца

Я определяю базу данных для системы клиент/заказ, где есть два очень разных типа клиентов. Поскольку они настолько различны, что одна таблица клиентов будет очень уродливой (она будет заполнена нулевыми столбцами, поскольку они бессмысленны для одного типа).

Их заказы, хотя и в одном формате. Возможно ли иметь столбец CustomerId в моей таблице заказов, который имеет внешний ключ для обоих типов клиентов? Я настроил его на SQL-сервере, и мне не было никаких проблем с созданием отношений, но я еще не пытался вставлять какие-либо данные.

Кроме того, я планирую использовать nHibernate как ORM, могут ли быть какие-либо проблемы, возникающие при выполнении таких отношений?

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

CustomerA <---- CustomerA_Orders ----> Order
CustomerB <---- CustomerB_Orders ----> Order

Таким образом, у заказа нет даже внешнего ключа; желательно ли это, хотя...

Ответ 3

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

Лучше всего иметь таблицу CustomerType с возможными столбцами - CustomerTypeID, CustomerID, где CustomerID является PK, а затем ссылаться на вашу таблицу OrderID на CustomerID.

Раджа

Ответ 4

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

Он использовал столбец GUID (тип "uniqueidentifier" ), чтобы избежать проблемы двусмысленности, и он отключил проверку ограничений внешних ключей, так как он гарантировал, что будет соответствовать только один. Но я могу думать о многих причинах, которых вам не следует, и я не думал о каких-либо причинах, по которым вам следует.

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

Ответ 5

Два разных типа клиентов - классический случай типов и подтипов или, если хотите, классов и подклассов. Здесь - ответ от другого вопроса.

По сути, метод наследования класса-таблицы похож на ответ Арнанда. Использование метода shared-primary-key - это то, что позволяет обойти проблемы, создаваемые двумя типами внешнего ключа в одном столбце. Внешний ключ будет идентификатором клиента. Это определит одну строку в таблице клиентов, а также одну строку в соответствующей таблице типов клиентов, в зависимости от ситуации.

Ответ 6

Как уже отмечалось, если ключ, скажем, 12345, как вы узнаете, в какой таблице его искать? Вы могли бы, я полагаю, сделать что-то, чтобы гарантировать, что ключевые значения для двух таблиц никогда не перекрываются, но это слишком уродливо и мучительно созерцать. У вас может быть второе поле, в котором указывается тип клиента. Но если у вас будет два поля, почему бы не указать одно поле для идентификатора клиента 1 и другое для идентификатора клиента 2.

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

Ответ 7

  • Создать "клиентскую" таблицу включают все столбцы, которые имеют одинаковые данные для обоих типов клиентов.
  • Затем создайте таблицу "customer_a" и "customer_b"
  • Используйте "customer_id" из таблицы "consumer" в качестве внешнего ключа в "customer_a" и "customer_b"

                    customer
                        |
         ---------------------------------
         |                               |
    cusomter_a                      customer_b