2013-05-30 4 views
-1

У меня есть база данных SQL Server 2012 Express со следующей ситуацией. У меня есть Sales, a Purchase и таблица Movement. Оба Sales и Purchase приведены в таблице Movement.Внешний ключ SQL Server для разных таблиц

Но я хотел бы контролировать, откуда берутся данные. В основном:

MOVEMENT_ID  TABLE_ID  RECORD_ID  PROD  QTY 
1    PURCHASE  1    PENCIL 10 
2    PURCHASE  2    ERASER 5 
3    SALES  1    PENCIL 1 
4    PURCHASE  3    MARKER 10 

Не беспокойтесь о нормализации части, я просто хочу, чтобы выяснить, могу ли я иметь внешний ключ на Record_ID колонке, что ссылки на запись таблицы, указанной в Table_ID колонки. Итак ...

  • на MovementID=1, я хочу, первая запись Purchase таблицы
  • на MovementID=3, я хочу, чтобы первая запись Sales таблицы

Является ли это вообще возможно? Если да, то как?

+5

* «Не беспокойтесь о части нормализации» *, как говорится, не волнуйтесь об этой плоской шине на вашем автомобиле, она отлично справится. – Kermit

+2

Я думаю, вам будет лучше с тремя столбцами 'Purchase_Id, Sales_Id, Source_Table' –

+1

мой вопрос более теоретический. я не хочу, чтобы какой-нибудь евангельский db, такой как вы, чтобы получить все праведные о чем-то, что я буду делать в любом случае. – CogentP

ответ

0

Похоже, что движение действительно является обобщением покупки или продажи. Если да, рассмотрите возможность использования .

Это устраняет проблему смешивания различных типов FK в одном столбце. PK в таблице Movement будет ссылаться на PK в таблице покупки или продажи, в зависимости от ситуации. Меньше столбцов, а также меньше путаницы.

+0

спасибо walter, вот что я искал! Я могу сделать исследование здесь! – CogentP

0

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

;WITH SalesMovement AS 
(
    SELECT * FROM Movement 
    WHERE TableName = 'Sales' 
) 
SELECT PROD, SUM(QTY) FROM SalesMovement 
GROUP BY PROD 

 

;WITH PurchaseMovement AS 
(
    SELECT * FROM Movement 
    WHERE TableName = 'Purchase' 
) 
SELECT * FROM Purchase p 
INNER JOIN PurchaseMovement pm ON pm.Record_Id = p.Id 

 

;WITH PurchaseMovement AS 
(
    SELECT * FROM Movement 
    WHERE TableName = 'Purchase' 
) 
, SalesMovement AS 
(
    SELECT * FROM Movement 
    WHERE TableName = 'Sales' 
) 
SELECT * FROM Purchase p, 
INNER JOIN Sales s ON s.SaleDate = p.PurchaseDate 
INNER JOIN PurchaseMovement pm ON pm.Record_Id = p.Id 
INNER JOIN SalesMovement sm ON sm.Record_Id = s.Id 

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

Еще одна вещь, которую следует учитывать, - это что-то вроде SUM(Qty) = SUM(ProductsSold) + SUM(ProductsSales) имеет смысл, вам нужно быть осторожным в таком «неправильном использовании» данных в таблице.

1

Возможно ли это?

Непосредственно, и я бы тепло рекомендовал отдельные поля с отдельными FK (как уже указывали другие).

Однако, так как вы используете MS SQL Server, вы можете сделать это косвенно, как это:

  1. Создать сохранялось вычисляемый столбец SALE_ID, который:
    • равно RECORD_ID, когда TABLE_ID = 'SALES'
    • и NULL в противном случае.
  2. Создать сохраненное вычисленное PURCHASE_ID столбец, который:
    • равна record_id при table_id = 'ПРИОБРЕТЕНИЕ'
    • и NULL, в противном случае.
  3. Создайте FK из SALE_ID в таблицу продаж и отдельный FK из таблицы PURCHASE_ID в таблицу Purchase.

Например:

ALTER TABLE Movement 
    ADD SALE_ID AS IIF(TABLE_ID = 'SALES', RECORD_ID, NULL) PERSISTED 
    REFERENCES Sales (SALE_ID); 

ALTER TABLE Movement 
    ADD PURCHASE_ID AS IIF(TABLE_ID = 'PURCHASE', RECORD_ID, NULL) PERSISTED 
    REFERENCES Purchase (PURCHASE_ID); 

[SQL Fiddle]


SQL Server запрещает создание FOREIGN KEY на не сохранялось вычисляемые столбцы.

+0

спасибо Бранко, я дал вам + один за помощь. Я собираюсь попробовать walter как его близкий к моей оригинальной идее. если становится явно трудно поддерживать, то я поеду с отдельным столбцом для каждого fk. – CogentP

Смежные вопросы