Подтвердить что ты не робот

В целом, должна ли каждая таблица в базе данных иметь поле идентификации для использования в качестве ПК?

Это похоже на дубликат, даже когда я его прошу, но я искал и не нашел его. Это похоже на хороший вопрос для SO - хотя я уверен, что могу найти его на многих блогах и т.д. Там. У SO будет больше дебатов, чем вы можете получить в блоге.

У меня возникла проблема с соединением: возврат слишком большого количества записей. Я думаю об этом как о "расширении". Я добавил таблицу в набор объединений и количество строк, расширенных, слишком много. Обычно, когда это происходит, я добавляю выбор всех полей идентификатора, которые участвуют в соединении. Таким образом, это довольно очевидно, когда происходит расширение, и я могу изменить ON соединения, чтобы исправить это. За исключением этого случая, таблица, которую я добавил, не имеет поля идентификатора. Для меня это проблема. Но, возможно, я ошибаюсь.

Вопрос: должна ли каждая таблица в базе данных иметь поле IDENTITY, которое используется как ПК? Существуют ли какие-либо недостатки в отношении наличия поля идентификатора в каждой таблице? Что, если вы уверены, что эта таблица никогда не будет использоваться в отношениях PK/FK?

Связанный, но не повторяющийся: Когда наличие столбца идентификации не является хорошей идеей?

По-видимому, эта дискуссия длилась . Должен знать.

Это сообщение (суррогатное и естественное) также актуально.

4b9b3361

Ответ 1

Есть два понятия, которые близки, но их не следует путать: IDENTITY и PRIMARY KEY

Каждая таблица (за исключением редких условий) должна иметь PRIMARY KEY, то есть значение или набор значений, которые однозначно идентифицируют строку.

Смотрите здесь для обсуждения.

IDENTITY - это свойство столбца в SQL Server, что означает, что столбец будет заполняться автоматически с добавочными значениями.

Из-за природы этого свойства значения этого столбца по своей сути UNIQUE.

Тем не менее, ограничение UNIQUE или индекс UNIQUE автоматически создается в столбце IDENTITY, а после выпуска SET IDENTITY_INSERT ON можно вставить повторяющиеся значения в столбец IDENTITY, если только это не было объяснением UNIQUE ограничено.

Столбец IDENTITY не обязательно должен быть PRIMARY KEY, но чаще всего он используется для заполнения суррогата PRIMARY KEY s

Это может быть или не быть полезным в каком-либо конкретном случае.

Поэтому ответ на ваш вопрос:

Вопрос: должна ли каждая таблица в базе данных иметь поле IDENTITY, которое используется как PK?

:

Нет. Бывают случаи, когда таблица базы данных НЕ должна иметь поле IDENTITY как PRIMARY KEY.

Мне приходят в голову три случая, когда не самая лучшая идея иметь IDENTITY как PRIMARY KEY:

  • Если ваш PRIMARY KEY является составным (например, во многих ссылках)
  • Если ваш PRIMARY KEY является естественным (например, код состояния)
  • Если ваш PRIMARY KEY должен быть уникальным для всех баз данных (в этом случае вы используете GUID/UUID/NEWID)

Все эти случаи означают следующее условие:

У вас не должно быть IDENTITY, когда вы будете заботиться о значениях вашего PRIMARY KEY и явно вставляете их в свою таблицу.

Update:

Таблицы ссылок "многие ко многим" должны иметь пару id к таблице, которую они связывают в качестве составного ключа.

Это естественный составной ключ, который вам уже нужно использовать (и сделать UNIQUE), поэтому нет смысла генерировать суррогатный ключ для этого.

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

В этом случае вы просто ссылаетесь на таблицу ссылок с помощью сложного ключа.

Этот запрос:

CREATE TABLE a (id, data)
CREATE TABLE b (id, data)
CREATE TABLE ab (a_id, b_id, PRIMARY KEY (a_id, b_id))
CREATE TABLE business_rule (id, a_id, b_id, FOREIGN KEY (a_id, b_id) REFERENCES ab)

SELECT  *
FROM    business_rule br
JOIN    a
ON      a.id = br.a_id

намного эффективнее, чем этот:

CREATE TABLE a (id, data)
CREATE TABLE b (id, data)
CREATE TABLE ab (id, a_id, b_id, PRIMARY KEY (id), UNIQUE KEY (a_id, b_id))
CREATE TABLE business_rule (id, ab_id, FOREIGN KEY (ab_id) REFERENCES ab)

SELECT  *
FROM    business_rule br
JOIN    a_to_b ab
ON      br.ab_id = ab.id
JOIN    a
ON      a.id = ab.a_id

по понятным причинам.

Ответ 2

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

Единственное, что я могу вспомнить в верхней части головы, где я не был, - это узкоспециализированная база данных, которая больше использовалась в качестве хранилища данных, чем реляционная база данных, где СУБД использовалась почти для каждой функции, кроме значительных реляционных моделирование. (Это был большой объем, большой буферный буфер данных.)

Ответ 3

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

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

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

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

Ответ 4

Каждая таблица должна иметь некоторый набор полей, которые однозначно идентифицируют ее. Независимо от того, существует ли поле числового идентификатора отдельно от полей данных, будет зависеть от домена, который вы пытаетесь моделировать. Не все данные легко попадают в парадигму "одиночного числового идентификатора", и поэтому нецелесообразно ее принуждать. Учитывая, что многие данные легко вписываются в эту парадигму и как таковые будут требовать такого идентификатора. Нет никакого ответа, чтобы всегда делать X в любой среде программирования, и это еще один пример.

Ответ 5

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

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

Ответ 6

Если вы смоделировали, спроектировали, нормализовались и т.д., то у вас не будет столбцов идентификаторов.

У вас будут идентифицированы натуральные и кандидатные ключи для ваших таблиц.

Вы можете выбрать суррогатный ключ из-за физической архитектуры (например, узкий, числовой, строго монотонно возрастающий), скажем, потому что использование столбца nvarchar (100) не является хорошей идеей (по-прежнему требуется уникальное ограничение).

Или из-за идеологии: они обращаются к разработчикам OO, которые я нашел.

Хорошо, предположим столбцы идентификаторов. По мере того, как ваш db становится более сложным, скажите несколько уровней, как вы можете напрямую использовать родительские и грандиозные .child таблицы. Вы не можете: вам всегда нужны промежуточные таблицы и хорошо индексированные столбцы PK-FL. С помощью сложного ключа все это для вас...

Не поймите меня неправильно: я использую их. Но я знаю, почему я их использую...

Edit:

Мне было бы интересно сопоставить "всегда ID" + "no stored procs", с одной стороны, с "использовать сохраненные procs" + "IDs, когда они приносят пользу" на другой...

Ответ 7

Да, в подавляющем большинстве случаев.

Края или исключения могут быть такими, как:

  • двухсторонние таблицы соединений для моделирования отношений m: n
  • временные таблицы, используемые для массового ввода огромных объемов данных

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

Марк

Ответ 8

Признать различие между полем Identity и ключом... Каждая таблица должна иметь ключ, чтобы исключить повреждение данных, непреднамеренно вводя несколько строк, которые представляют один и тот же "объект". Если единственным ключом таблицы является бессмысленный суррогатный ключ, то эта функция фактически отсутствует.

otoh, таблица не нуждается в идентичности, и, конечно, не каждая таблица выигрывает от одного... Примеры: таблица с коротким и функциональным ключом, таблица, в которой нет другой таблицы, ссылающейся на нее через иностранную Ключ или таблица, которая находится в соотношении от одного до нуля или другого с другой таблицей... Никому из них не требуется Identity

Ответ 9

Я бы сказал, если вы можете найти простой, естественный ключ в своей таблице (т.е. один столбец), используйте это как ключ вместо столбца идентификации.

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

Лично я избегаю IDENTITY (увеличивая столбцы идентификаторов, например 1, 2, 3, 4), такие как чума. Они вызывают много хлопот, особенно если вы удаляете строки из этой таблицы. Вместо этого я использую сгенерированные уникальные идентификаторы, если в таблице нет натурального ключа.

Во всяком случае, не знаю, является ли это принятой практикой, просто кажется мне правдой. YMMV.

Ответ 10

Я не могу придумать никакого недостатка в том, что у меня есть поле идентификатора в каждой таблице. Предоставление вашего типа поля идентификатора предоставляет достаточно места для роста вашей таблицы.

Однако для обеспечения идентичности ваших строк вам необязательно требуется одно поле. Так что нет, поле single ID не является обязательным.

Первичные и внешние ключи могут состоять не только из одного поля, но и из нескольких полей. Это типично для таблиц, реализующих отношения N-N.

Вы можете отлично иметь PRIMARY KEY (fa, fb) в своей таблице:

CREATE TABLE t(fa INT , fb INT);
ALTER TABLE t ADD PRIMARY KEY(fa , fb);