Может ли таблица базы данных быть без первичного ключа? - PullRequest
39 голосов
/ 25 марта 2010

Может кто-нибудь сказать мне, если таблица в реляционной базе данных (например, MySQL / SQL SERVER) может быть без первичного ключа?

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

Ответы [ 11 ]

30 голосов
/ 25 марта 2010

Технически, вы можете объявить такую ​​таблицу.

Но в вашем случае time следует сделать PRIMARY KEY, поскольку, вероятно, неправильно иметь разные температуры в одно и то же время и, вероятно, бесполезночтобы иметь одно и то же несколько раз.

Логически, каждая таблица должна иметь PRIMARY KEY, чтобы можно было различить две записи.

Если у вас нет ключа-кандидата в ваших данных,просто создайте суррогатное (AUTO_INCREMENT, SERIAL или все, что предлагает ваша база данных).

Единственным оправданием отсутствия PRIMARY KEY является журнал или аналогичная таблица, которая может быть подвержена значительным DML и наличие на нем индекса повлияет на производительность за пределами допустимого уровня.

25 голосов
/ 25 марта 2010

Как всегда зависит .

Таблица не имеет , чтобы иметь первичный ключ. Гораздо важнее иметь правильных индексов .От механизма базы данных зависит, как первичный ключ влияет на индексы (т. Е. Создает уникальный индекс для столбца / столбца первичного ключа).

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

Это значительно упрощает ведение этой таблицы - например, поиск и удаление записей (т.е. дублированных записей) - и поверьте мне - для каждой таблицы приходит время что-то исправить :(.

11 голосов
/ 25 марта 2010

Разве первичным ключом не будет время? Вы когда-нибудь имели бы более одной температуры в течение определенного времени?

Лучше задать вопрос: «Зачем вам когда-либо делать таблицу без первичного ключа»

5 голосов
/ 25 марта 2010

Вам не нужен ПК, но рекомендуется иметь его. Это лучший способ идентифицировать уникальные строки. Иногда вам не нужно автоматическое добавление int PK, а создание PK на чем-то другом. Например, в вашем случае, если есть только одна уникальная строка за раз, вы должны создать PK на время. Это ускоряет поиск в зависимости от времени, а также гарантирует, что они уникальны (вы можете быть уверены, что целостность данных не нарушена):

5 голосов
/ 25 марта 2010

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

1 голос
/ 25 марта 2010

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

0 голосов
/ 25 марта 2018

В соответствии с вашим ответом я бы рассмотрел три варианта:

  • поместите PK на оба col, таким образом, каждый раз может быть только один темп, и наоборот. Это решение позволяет использовать несколько строк с одинаковыми временными и временными значениями, только если бы не было двух строк с одинаковыми временными и временными значениями.
  • вообще не ставьте PK, но ставьте уникальный индекс на оба столбца. один уникальный индекс, содержащий оба столбца. это позволило бы принимать значения NULL во времени и времени, но требует больше места для поддержания индекса.

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

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

Кроме того, очень важно рассмотреть здесь количество элементов и подумать о будущих последствиях использования числа с автоинкрементом. если вы планируете делать МНОГО вставок, то риск будет заключаться даже в увеличении размера без знака bigint с автоматическим увеличением, поскольку в конечном итоге он закончится. В вашем примере, я думаю, вы будете сохранять данные ежедневно - как долго? это было бы проблематично, если бы вы сохраняли темп каждую минуту ... поэтому я возьму это как крайний пример.

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

0 голосов
/ 11 сентября 2014

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

http://lists.mysql.com/mysql/227217

Наиболее распространенной ошибкой при использовании ROW или MIXED является сбой в убедитесь, что каждая таблица, которую вы хотите скопировать, имеет ПЕРВИЧНЫЙ КЛЮЧ на Это. Это ошибка, потому что, когда событие ROW (например, один задокументировано выше) отправляется на ведомое устройство и ни на мастер-копию ни копия таблицы раба не имеет первичного ключа на столе, нет способа легко определить, какую уникальную строку вы хотите репликация для изменения.

0 голосов
/ 03 июля 2014

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

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

Я предпочитаю не иметь PK, но иметь индекс только для строки, в которой я выполняю поиск.

0 голосов
/ 25 марта 2010

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

create table capability_group
(  capability_id varchar(32),
    group_id     varchar(32));

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

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