Что следует учитывать при выборе типа данных для моего первичного ключа? - PullRequest
6 голосов
/ 23 октября 2008

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

Ответы [ 16 ]

11 голосов
/ 24 октября 2008

Извините, что сделал это, но я обнаружил, что ответы, которые я дал на связанные вопросы (вы можете проверить this и this ), могут относиться к этому. Я изменил их немного ...

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

По этому вопросу моя точка зрения очень проста: суррогатные первичные ключи ВСЕГДА работают , в то время как Естественные ключи НЕ МОГУТ работать ВСЕГДА , и это по нескольким причинам: поле слишком короткое, правила изменены и т. Д.

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

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

каждый раз, когда я создаю таблицу, теряю ли я время

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

Мой ответ - нет на все эти вопросы:

  1. У меня нет времени терять попытки определить «лучший естественный первичный ключ», когда суррогатный вариант дает мне пуленепробиваемое решение.
  2. Я не хочу вспоминать, что первичный ключ моей таблицы - это строка длиной 10 символов, когда я пишу код.
  3. Я не хочу терять время, обсуждая длину Натурального Ключа: «хорошо, если Вам нужно 10, почему бы вам не взять 12 , чтобы быть в безопасности ? ». Этот аргумент "на безопасной стороне" действительно раздражает меня: если вы хотите оставаться на безопасной стороне, это означает, что вы действительно недалеко от небезопасной стороны! Выберите суррогат: это пуленепробиваемый!

Итак, я работал в течение последних пяти лет с очень простым правилом: каждая таблица (назовем ее 'myTable') имеет свое первое поле с именем 'id_MyTable', которое имеет тип uniqueIdentifier. Даже если эта таблица поддерживает отношение «многие ко многим», где комбинация полей предлагает очень приемлемый первичный ключ, я предпочитаю создавать это поле 'id_myManyToManyTable', являющееся uniqueIdentifier, просто для того, чтобы придерживаться правила, и потому что, наконец, не больно.

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

И если вы все еще хотите, чтобы ваш "Натуральный ключ" находился где-то в вашей таблице, я советую вам создать его в соответствии со стандартной моделью, такой как

Tbl_whatever

   id_whatever, unique identifier, primary key
   code_whatever, whateverTypeYouWant(whateverLengthYouEstimateTheRightOne), indexed
   .....

Где id_ - префикс первичного ключа, а code_ используется для «естественного» индексированного поля. Некоторые утверждают, что поле code_ должно быть уникальным. Это действительно так, и им легко управлять либо с помощью DDL, либо с помощью внешнего кода. Обратите внимание, что многие «натуральные» ключи рассчитываются (номера счетов), поэтому они уже сгенерированы с помощью кода

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

7 голосов
/ 23 октября 2008

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

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

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

7 голосов
/ 23 октября 2008

Мне не очень нравится то, что они преподают в школе, то есть использование «естественного ключа» (например, ISBN в книжной базе данных) или даже наличие первичного ключа, состоящего из 2 или более полей. Я бы никогда этого не сделал. Итак, вот мой маленький совет:

  • Всегда иметь один выделенный столбец в каждой таблице для вашего первичного ключа.
  • Все они должны иметь одинаковые имена столбцов во всех таблицах, т. Е. "ID" или "GUID"
  • Используйте GUID, когда можете (если вам не нужна производительность), в противном случае увеличивайте INT

EDIT:
Ладно, думаю, мне нужно немного объяснить свой выбор.

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

  • Идентификаторы GUID и INT не имеют большого значения в большинстве случаев. Если вы не достигнете предела производительности GUID или не выполните слияния баз данных, у вас не будет серьезных проблем с тем или другим. НО есть причина, по которой я предпочитаю GUID. Глобальная уникальность идентификаторов GUID может когда-нибудь пригодиться. Может быть, вы не видите в этом необходимости сейчас, но такие вещи, как синхронизация частей базы данных с ноутбуком / сотовым телефоном или даже поиск записей данных без необходимости знать, в какой таблице они находятся, являются отличными примерами преимуществ, которые могут иметь GUID. предоставлять. Целое число идентифицирует только запись в контексте одной таблицы, тогда как GUID идентифицирует запись везде.

6 голосов
/ 23 октября 2008

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

Я (почти) никогда не использовал значимые ключи.

4 голосов
/ 24 октября 2008

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

Кроме того, я должен не согласиться с практикой именования всех первичных ключей одинаковыми, например, "Я бы". Это усложняет понимание запросов, а не упрощает их. Первичные ключи должны быть названы в честь таблицы. Например, employee.employee_id, affiliate.affiliate_id, user.user_id и т. Д.

2 голосов
/ 23 октября 2008

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

1 голос
/ 23 октября 2008

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

1 голос
/ 23 октября 2008
  • Где вы его генерируете? Увеличение числа не подходит для ключей, сгенерированных клиентом.
    • Хотите ли вы зависимый от данных или независимый ключ (иногда вы можете использовать идентификатор из бизнес-данных, не можете сказать, всегда ли это полезно или нет)?
    • Насколько хорошо этот тип может быть проиндексирован вашей БД?

До сих пор я использовал уникальные идентификаторы (GUID) или увеличивающие целые числа.

Приветствие Matthias

0 голосов
/ 24 октября 2008

Обычно я иду с первичным ключом столбца GUID для всех таблиц (rowguid в mssql). Какими могут быть естественные ключи, я делаю уникальные ограничения. Типичным примером может служить идентификационный номер продукта, который пользователь должен составить и убедиться, что он уникален. Если мне нужна последовательность, как в счете, я создаю таблицу, чтобы сохранить lastnumber и хранимую процедуру, чтобы обеспечить сериализованный доступ. Или последовательность в Oracle :-) Я ненавижу образец «номера социального страхования» для натуральных ключей, так как этот номер никогда не будет доступен в процессе регистрации. В результате возникает необходимость в схеме для создания фиктивных чисел.

0 голосов
/ 23 октября 2008

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

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

Если вы используете натуральные ключи, натуральный ключ будет определять тип данных.

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

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