Проектирование базы данных - Как применить ограничение внешнего ключа для таблицы с суррогатным ключом - PullRequest
0 голосов
/ 30 сентября 2010

Моя схема таблицы выглядит примерно так

1. Мастер стол: клаус

Колонны

  1. ClauseID = суррогатный ПК (личность)
  2. ClauseCode = nvarchar указанное пользователем значение
  3. Class = nvarchar FK к таблице мастер-классов
  4. и т.д ...

ClauseCode + Class = ключ-кандидат для этой таблицы

2. Основной стол: GroupClause

Столбцы

  1. GroupClauseID = суррогатный ПК (личность)
  2. GroupClauseCode = nvarchar указанное пользователем значение
  3. Class = nvarchar FK к таблице мастер-классов и т.д ...

GroupClauseCode + Class = ключ-кандидат для этой таблицы

3. Таблица транзакций / сопоставлений :: GroupClause_Clause_Mapping : эта таблица отображает каждое предложение группы в несколько отдельных предложений

Столбцы

  1. GroupClauseID = FK для GroupClause PK
  2. ClauseID = FK для пункта PK
  3. и т.д ...

Требование: Каждое предложение группы может быть сопоставлено только с предложениями того же класса, что и он сам

Проблема : Приведенная выше схема таблицы не обеспечивает выполнение этого требования на уровне БД.

Одно из возможных решений: Таблица * GroupClause_Clause_Mapping * имеет столбцы

  1. ClauseCode
  2. GroupClauseCode
  3. Класс

где я могу создать ClauseCode + Class как FK для таблицы предложений, а также GroupClauseCode + Класс от FK до таблицы GroupClause.

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

Есть ли проблема с моим дизайном, использующим суррогатные ключи?

Есть ли какие-либо предложения относительно того, как я могу использовать суррогатные ключи и по-прежнему применять мое ограничение на уровне БД?

Ответы [ 2 ]

1 голос
/ 30 сентября 2010

Если сами коды являются большими / громоздкими, то вы все равно можете использовать суррогаты там, где они доступны.

Так как вы хотите только обеспечить соответствие классов, тогда ваша таблица сопоставления может быть

ClauseID,
GroupClauseID,
Class (or possibly ClassID)

Для ваших основных таблиц у вас все еще будет PK (ClauseID) и уникальное ограничение (ClauseID, Class).Затем вы можете решить, следует ли просто FK (ClauseID, Class) или иметь два FK между таблицей сопоставления и каждой главной таблицей (фактически, вы бы тогда сказали, что один FK является ссылкой на внешний ключ, а другой предназначен дляприменять ваши правила).

У меня есть похожая настройка в одной из моих баз данных (например, система опроса):

CREATE TABLE [dbo].[DataItems](
    [DataItemID] [uniqueidentifier] ROWGUIDCOL  NOT NULL,
    [TypeRequired] [varchar](10) NOT NULL,
    [Name] [varchar](50) NOT NULL,
    /* Other Columns */
 CONSTRAINT [PK_DataItems] PRIMARY KEY NONCLUSTERED 
(
    [DataItemID] ASC
),
 CONSTRAINT [UX_DataItems_ClientAnswerFKTarget] UNIQUE CLUSTERED 
(
    [DataItemID] ASC,
    [TypeRequired] ASC
),
 CONSTRAINT [UX_DataItems_Name] UNIQUE NONCLUSTERED 
(
    [Name] ASC
)
)

CREATE TABLE [dbo].[ClientAnswers](
    [ClientAnswersID] [uniqueidentifier] ROWGUIDCOL  NOT NULL,
    [ClientID] [uniqueidentifier] NOT NULL,
    [DataItemID] [uniqueidentifier] NOT NULL,
    [TypeRequired] [varchar](10) NOT NULL,
    [BoolValue] [bit] NULL,
    [IntValue] [int] NULL,
    [CharValue] [varchar](6500) NULL,
    [CurrencyValue] [int] NULL,
    [DateValue] [datetime] NULL,
    /* Other Columns */
 CONSTRAINT [PK_ClientAnswers] PRIMARY KEY CLUSTERED 
(
    [ClientID] ASC,
    [DataItemID] ASC
)
)
GO
ALTER TABLE [dbo].[ClientAnswers] ADD  CONSTRAINT [FK_ClientAnswers_DataItems] FOREIGN KEY([DataItemID],)
REFERENCES [dbo].[DataItems] ([DataItemID])
ON UPDATE CASCADE
GO
ALTER TABLE [dbo].[ClientAnswers] ADD  CONSTRAINT [FK_ClientAnswers_DataItems_TypesMatch] FOREIGN KEY([DataItemID],TypeRequired)
REFERENCES [dbo].[DataItems] ([DataItemID],TypeRequired)
GO

А потом я иду дальше и имею больше ограничений, гарантирующихстолбец типа соответствует ненулевому значению * Столбец значения

0 голосов
/ 30 сентября 2010

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...