2015-01-08 3 views
1

У меня есть соединение m: n между таблицей «Билл» и таблицами «Общие статьи», «Вычисляемые статьи» и «Дополнительные записи».Ограничение внешнего ключа в зависимости от категории

Эти таблицы являются прямолинейными. Каждый из них имеет свой собственный идентификатор (назовем их B_ID, а для других - GA_ID, CA_ID и AR_ID) и некоторые дополнительные поля. Вопрос в том, как настроить одну таблицу m: n-connection между Биллом и этими тремя таблицами, гарантирующими ссылочную целостность?

Моя первая идея состояла в том, чтобы просто создать:

CREATE TABLE Bill_Articles(
[B_ID] [int] NOT NULL FOREIGN KEY REFERENCES Bill (B_ID) , 
[A_ID] [int] NOT NULL , 
Category [int] NOT NULL 
CONSTRAINT [PK_Bill_Articles] PRIMARY KEY CLUSTERED 
      (
      [B_ID] ASC, 
      [A_ID] ASC, 
      [Category] ASC 
      )) 

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

Другим решением было бы создать вид, который содержит эту категорию-ID и идентификатор записи:

Create View Articles 
AS 
Select 1 Category, 
     GA_ID A_ID FROM GeneralArticles 
UNION 
SELECT 2 Category, 
     CA_ID A_ID FROM CalculatedArticles 
UNION 
SELECT 3 Category, 
     AR_ID A_ID 
     FROM AdditionalRecords 

К сожалению, при настройке таблицы Bill_Articles я получаю ошибку:

Foreign key 'FK__Bill_Ar_A_ID__7526B52E' references object 'Articles' which is not a user table.

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

Кто-нибудь знает подходящее решение для такого рода проблем? Спасибо

+0

В чем разница между таблицами статей, можете ли вы показать свою схему? –

+0

Мы имеем дело с взрослой системой, к сожалению, которая создает огромные таблицы на немецком языке ... Но в двух словах я пытаюсь объяснить: _GeneralArticles_ - это только что выбранные статьи из базы данных статей с выбранными ценами и датой. _CalculatedArticles_ практически то же самое, но относится и к другим таблицам, которые содержат конкретные количества, необходимые для использования этих статей, а также предоставляет информацию о группах статей. _AdditionalRecords_ - это статьи, которые не существуют в системе и могут быть добавлены администратором. (Некоторые статьи заказываются только один или два раза в год). – Qohelet

ответ

1

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

Вы должны создать несколько таблиц.

Один стол для связи счетов и общих статей. Вторая таблица для ссылок на счета и расчетные статьи. Третья таблица для ссылок на счета и дополнительные записи.

Для первого звена может выглядеть следующим образом (я не проверял синтаксис):

CREATE TABLE BillsGeneralArticlesAssosiations(
[B_ID] [int] NOT NULL FOREIGN KEY REFERENCES Bill (B_ID) , 
[GA_ID] [int] NOT NULL FOREIGN KEY REFERENCES GeneralArticles (GA_ID) 
CONSTRAINT [PK_BillsGeneralArticlesAssosiations] PRIMARY KEY CLUSTERED 
(
    [B_ID] ASC, 
    [GA_ID] ASC 
)) 

Иногда я добавляю IDENTITY колонку ID в эту таблицу в качестве первичного ключа. Особенно, если в этой таблице ссылок есть другие поля.

+0

Я получаю эту идею, но пока не думал об этом. Мне нравится идея с колонкой 'IDENTITY', но в этом случае я не думаю, что это будет необходимо. Я, вероятно, добавлю 'ON DELETE CASCADE' – Qohelet

+0

Я бы назвал этот дизайн ссылок таблицами« правильным решением ». Кроме того, я лично использую 'ON DELETE CASCADE' очень редко. Он установлен только на 16 таблицах из 343 в нашей системе. Я предпочитаю удалять связанные данные явно, если это необходимо. Мне не нравится риск уничтожения записей в десятках связанных таблицах при попытке удалить неправильную строку по ошибке. –