2009-05-06 8 views
16

Должен ли я всегда иметь первичный ключ в моих таблицах базы данных?Если таблица базы данных всегда имеет первичные ключи?

Давайте проведем отметку SO. Вы можете увидеть тег в любой редакции, скорее всего, в таблице tag_rev с номером postID и номером ревизии. Мне нужен ПК для этого?

Кроме того, поскольку он находится в таблице rev и в настоящее время не используется, теги должны быть блобом tagID вместо нескольких записей из нескольких папок post_id tagid?

+16

Надеюсь, вы осознали, что последнее предложение было признано непонятным более чем одним человеком. – kch

+0

Возможный дубликат [Если у каждой таблицы есть первичный ключ?] (Https://stackoverflow.com/questions/840162/should-each-and-every-table-have-a-primary-key) –

ответ

9

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

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

Что касается вашего второго пункта, хотя разумно спорить в пользу агрегации значений в архивных таблицах, это противоречит принципу, что каждое пересечение строк/столбцов в таблице должно содержать одно единственное значение. Хотя это может немного упростить разработку, нет причин, по которым вы не можете придерживаться нормализованной таблицы с версиями метаданных, даже для того, что тривиально, как теги.

10

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

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

+0

В унаследованное приложение, которое я поддерживаю, есть несколько таблиц, которые имеют только по одной строке, по дизайну. И некоторые таблицы, которые будут содержать не более десяти строк (поиски того или иного вида). В такой ситуации совершенно нет смысла иметь первичный ключ. По крайней мере, по-моему, во всяком случае. – Cyberherbalist

+2

@Cyberherbalist: Даже в этом случае, если вы используете эту таблицу программно, вам может понадобиться способ идентифицировать каждую строку отдельно. Также обратите внимание, что наличие первичного ключа не означает наличия * отдельного * первичного ключа * столбца *. У вас может быть комбинация столбцов в качестве первичного ключа. BTW, совершенно верно пропустить шаблоны и правила, если вы считаете, что они не имеют смысла в вашей конкретной ситуации, но в подавляющем большинстве случаев, не имея первичного ключа. –

+0

Точно. Я думал, что WTF, когда я читаю наш (Британский) буклет «Базы данных» средней школы, для MS Access. Ответить - «Если Access попросит вас определить первичный ключ, нажмите« Нет ». –

4

См. Этот родственный вопрос о том, требуется ли первичный ключ . Один из ответов использует мечения в качестве примера:

Are there any good reasons to have a database table without an integer primary key

Для более детального обсуждения мечения и клавишах см этот вопрос:

Id for tags in tag systems

+0

Однако это не вопрос. @acidzombie не спрашивает о нецелочисленном PK, но общий случай наличия или отсутствия первичного ключа любого типа (т. е. строки). – Cyberherbalist

+0

Спасибо, я отредактировал, чтобы уточнить, как связаны вопросы. –

-1

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

В любом случае, таблицы с большим количеством строк должны иметь первичные ключи; таблицы с несколькими строками не нужны, обязательно, хотя они не болят. Это зависит от использования и размера таблицы. Пуристы ставят первичные ключи в каждом столе. Это не так. и ни один из них не пропускает ПК в маленьких таблицах.

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

Cyberherbalist's Blog Post on Primary Keys

+0

Для таблицы с одной строкой не требуется первичный ключ, все остальное должно быть определено для избежания дубликатов. – jmoreno

+1

Да, как правило, но бизнес-правила определяют, должны ли дубликаты быть разрешены - не исключено, что дублирующиеся записи в таблице могут быть не только допустимыми, но и ожидаемыми. Это зависит от того, что хранится, и от чего оно делается. Кстати, спасибо за ответный удар - этот ответ на самом деле не противоречит принятому ответу. Ваш абсолютизм отмечен. – Cyberherbalist

+0

Если вы храните точные дубликаты, вы храните неправильную вещь. Что касается репутации, удалите шлем у людей, которые думают, что каждая таблица должна иметь ПК, и я удалю ее. – jmoreno

0

Если нет ПК, как вы будете обновлять или удалять одну строку? Это было бы невозможно! Честно говоря, я использовал несколько таблиц без ПК, например, для хранения журналов активности, но даже в этом случае желательно иметь один, поскольку временные метки не могут быть достаточно гранулярными. Еще один пример - временные таблицы. Но в соответствии с реляционной теорией ПК является обязательным.

+1

Невозможно? Неа. Строки в маленькой таблице могут быть идентифицированы однозначно без ПК.Если это небольшая таблица поиска (где я вижу больше всего использование таблиц без PK), всегда есть одно значение, которое может быть ключом, но, во всяком случае, служит способом однозначной идентификации строки даже без PK (или вы можете отредактировать строку, открыв таблицу с помощью SSMS). Но было бы более эффективно использовать ключ primay и команду Sql. – Cyberherbalist

+0

@Lluis, вы используете DELETE ... LIMIT 1 или UPDATE ... LIMIT 1. @Cyberherbalist, строки не всегда могут быть идентифицированы однозначно, так как нет ничего, что останавливало бы все значения столбцов одинаковыми, но вы можете ограничить число, на которое влияет запрос. – Draemon

0

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

0

Поскольку я использую Subsonic, я всегда создаю первичный ключ для всех моих таблиц. Для многих библиотек абстракции БД необходим первичный ключ.

Примечание: это не отвечает тон «Великой единой теории» вашего вопроса, но я просто говорю, что на практике иногда вы ДОЛЖНЫ сделать первичный ключ для каждой таблицы.

1

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

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

4

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

  1. Если у вас есть таблица, которая связывает ключи с другими ключами. Например, чтобы связать user_id с answer_id, этой таблице не нужен первичный ключ.
  2. Стол для журналов, единственной целью которого является создание контрольного журнала.

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

+1

В точке 1 вы должны иметь составной первичный ключ (user_id, answer_id). В точке 2 я ожидал бы столбец timestamp, но если бы было возможно иметь две идентичные строки (идентичные метки времени и сообщения), я определенно хотел бы знать, что что-то произошло дважды и иметь возможность обрабатывать эти события отдельно. «13: 15-удвоенный овердрафт» сильно отличается от «533-13: 15-удвоенный овердрафт, например, 534-13: 15-удвоенный овердрафт». – Draemon

+1

@Draemon - Если у вас есть два столбца в таблице, наличие сложного ключа overkill, IMO, поскольку вы действительно не получаете никакой пользы. Если вы можете одновременно совершать два события, тогда у вас возникают большие проблемы, если вы не ожидаете одновременного обновления двух версий одной и той же записи. –

0

Если это таблица соединений, я бы не сказал, что вам нужен первичный ключ. Предположим, например, что у вас есть таблицы PERSONS, SICKPEOPLE и ILLNESSES. Таблица ILLNESSES имеет такие вещи, как грипп, холод и т. Д., Каждый с первичным ключом. У ПЕРСОНА есть обычный материал о людях, каждый из которых также имеет первичный ключ. В таблице SICKPEOPLE есть только люди, которые болеют, и у него есть два столбца: PERSONID и ILLNESSID, внешние ключи обратно в соответствующие таблицы и первичный ключ. Таблицы PERSONS и ILLNESSES содержат сущности и сущности, которые получают первичные ключи. Записи в таблице SICKPEOPLE не являются сущностями и не получают первичные ключи.

+0

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

+0

Хорошая точка. Как вы говорите, вы могли бы избежать проблемы с дублирующимися вставками, добавив уникальное ограничение или индекс в комбинации PERSONID и ILLNESSID в таблице SICKPEOPLE. В момент я склоняюсь к тому, чтобы не добавлять первичные ключи к таблицам, как это, потому что это помогает понять, что это не сущность. – lumpynose

3

С MySQL 5.5 Справочное руководство секции 13.1.17:

Если вы не имеете PRIMARY KEY и приложение запрашивает первичный ключ таблиц, MySQL возвращает первый уникальный индекс, который не имеет NULL столбцы ПЕРВИЧНЫЙ КЛЮЧ.

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

+0

То, что никто не упоминал, было первичным ключом, может быть несколько столбцов, что я и делаю сейчас. – 2014-04-15 23:22:31

+1

Роб упомянул об этом. Возможно, вы должны отметить [его ответ] (http://stackoverflow.com/a/831884/2430274) как принято? – emisilva

+0

Эй, он сделал ... может быть, я хотел подождать, пока не попробовал, и забыл это принять. Вот вверху – 2014-04-17 05:22:19