SQL - два внешних ключа, между которыми есть зависимость - PullRequest
1 голос
/ 02 июня 2010

Текущая структура выглядит следующим образом:

Table RowType:    RowTypeID

Table RowSubType: RowSubTypeID
                  FK_RowTypeID

Table ColumnDef:  FK_RowTypeID
                  FK_RowSubTypeID (nullable)

Короче говоря, я сопоставляю определения столбцов со строками. В некоторых случаях эти строки имеют подтип (ы), которые будут иметь определенные для них определения столбцов. В качестве альтернативы, я мог бы повесить определения столбцов, которые относятся к подтипам, из их собственной таблицы, или я мог бы объединить данные в RowType и RowSubType в одну таблицу и работать с одним идентификатором, но я не уверен, что это лучшее решение во всяком случае, я бы склонялся к последнему, так как мы в основном вытаскиваем ColumnDefs для данного RowType / RowSubType).

Является ли текущий дизайн SQL богохульством?

Если я сохраню текущую структуру, как мне сохранить, что если RowSubTypeID указан в ColumnDef, он должен соответствовать RowType, указанному в RowTypeID? Должен ли я попытаться применить это с помощью триггера, или я упустил простой редизайн, который решил бы проблему?

1 Ответ

4 голосов
/ 02 июня 2010

У вас проблемы с Четвертая нормальная форма .

Вот решение:

Table RowSubType:       RowSubTypeID
                        FK_RowTypeID
                        UNIQUE(FK_RowTypeID, RowSubTypeID) 

Table ColumnDef:        ColumnDefID
                        FK_RowTypeID
                        UNIQUE(ColumnDefID, FK_RowTypeID) 

Table ColumnDefSubType: FK_ColumnDefID   } compound foreign key to ColumnDef
                        FK_RowTypeID     }   } 
                        FK_RowSubTypeID      } compound foreign key to RowSubType

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

Но что бы это ни стоило, я согласен с комментарием @ Сета о возможном чрезмерном проектировании. Я не уверен, что понимаю, как вы используете эти определения столбцов и типы строк, но он пахнет как анти-паттерн Inner-Platform Effect . В SQL просто используйте метаданные для определения метаданных. Не пытайтесь использовать данные для создания динамической схемы.

Смотрите также эту превосходную историю: Bad CaRMa .


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

См. Также мой ответ на Таблица продуктов, многие виды продуктов, каждый продукт имеет много параметров или мои слайды презентации Практические объектно-ориентированные модели в SQL .

...