Поле уникального идентификатора не включено в первичный ключ при наличии составного ключа - PullRequest
0 голосов
/ 03 марта 2012

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

Вопрос, с которым я сталкиваюсь, заключается в том, как лучше всего справиться с ограничениями PRIMARY KEY и UNIQUE и ссылочным ключом внешнего ключа.Индексирование находится в центре этого, так как я ожидаю, что вложенная таблица (мы назовем ее CategoryTypes) со временем станет достаточно большой и должна будет иметь возможность эффективно разрешать чтение из данных на основе родительской таблицы (* 1006).*).Есть ли какие-либо проблемы, которые мне нужно было бы ожидать, если бы таблицы были расположены следующим образом?

Меня беспокоит, что столбец IDENTITY в таблице CategoryTypes должен поддерживать уникальный счетчик.Причина, по которой я включил это поле, заключается в том, что при передаче данных между уровнями в приложении допускается более простая ссылка.Передавая Integer против пары Integer / String.Данные в этих таблицах будут сохраняться на каждом уровне базы данных для экономии пропускной способности.С точки зрения базы данных, создает ли приведенная ниже схема какие-либо серьезные проблемы после развертывания?

Для упрощения, существует ли проблема с использованием поля уникального идентификатора (IDENTITY), которое не включается в первичный ключ присоставной ключ присутствует?См. Таблицу ниже:

Родительская таблица:

CREATE TABLE schema.Categories
(
  Id TINYINT PRIMARY KEY NOT NULL,
  Name VARCHAR(100) NOT NULL,
)

Подтаблица (данные, введенные пользователем с течением времени):

CREATE TABLE schema.CategoryTypes
(
   Id INT IDENTITY(1,1) NOT NULL,
   CategoryId TINYINT REFERENCES schema.Categories(Id) NOT NULL,
   Name VARCHAR(100) NOT NULL,
   CONSTRAINT PRIMARY KEY CLUSTERED(CategoryId, Name)
   CONSTRAINT UC_CategoryTypesId UNIQUE NONCLUSTERED(Id)
)

1 Ответ

0 голосов
/ 03 марта 2012

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

Если это так, то это должно работать нормально, и я не понимаю, почему вы не устанавливаете CategoryType.Id в качестве первичного ключа?Если это не ваш ПК и не упоминается как FK в другом месте, то я не вижу в этом смысла.Лично я не думаю, что вы получаете достаточную экономию пропускной способности, и, вероятно, стоит просто запросить данные по CategoryId и Name.На самом деле, ни один PK не является тем, как представлены структуры наследования ( Как вы можете представлять наследование в базе данных? ).

Если вы должны сохранить его так, как вы его настроили,Я лично предлагаю установить Id в качестве PK и просто установить уникальное ограничение для CategoryId / Name.

Это всего лишь два моих цента.

Category
----
Id|Name
1 |Food
2 |Drink

CategoryType
----
Id|CategoryId|Name
1 |2         |Water
2 |2         |Orange Juice

ОБНОВЛЕННЫЙ ОТВЕТ (для непосредственного решения проблем производительности)

Во-первых, я бы посоветовал не беспокоиться об этом тоже.много, если это не проблема.Это общая проблема, которую многие из нас создают, усложняя то, что ей не нужно.Это подпадает под принцип ПОЦЕЛУЯ в моей книге

Однако, если вы устали от попыток выяснить это заранее, как вы объяснили, то вот мои дополнительные мысли:

  • Создайте PK как Id, но сделайте его НЕКЛАСТЕРНЫМ
  • Создайте кластеризованный индекс для CategoryId и рассмотрите возможность использования ключевого слова INCLUDE в вышеупомянутом некластеризованном индексе.
  • Делайте это только в том случае, если вы чаще будете использовать CategoryId для запросов, чем CategoryType.Id
  • Хотя при создании ваших ключей следует учитывать (даже взято из статьи INCLUDE)
Index maintenance may increase the time that it takes to perform modifications
, inserts, updates, or deletes, to the underlying table or indexed view.

В конечном счете, я думаю, что все, что вы делаете, будет в порядке, однако ПК не нужно кластеризовать, поэтому я определенно перенесу ПК в поле Id,Это ваш выбор, если вы хотите сделать кластер на CategoryId или CategoryId / Name, или если вы хотите попробовать использовать INCLUDE, как я предлагал.Это действительно будет зависеть от того, как используются таблицы, поэтому здесь может помочь сравнение планов выполнения.

Надеюсь, это поможет:)

...