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

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

16 ответов


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

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

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

к этому моменту вы догадались, что я в основном являюсь членом команды uniqueidentifier / surrogate primary key, и даже если я ценю и понимаю аргументы, такие как представленные здесь, я все еще ищу случай, когда "естественный" ключ лучше, чем суррогат. ..

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

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

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

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

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

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

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

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

Tbl_whatever

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

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

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


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

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

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


Мне не очень нравится то, что они преподают в школе, то есть используют "естественный ключ" (например, ISBN на bookdatabase) или даже имеют первичный ключ, состоящий из 2 или более полей. Я бы никогда так не поступил. Вот мой маленький совет:--1-->

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

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

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

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


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

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


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

Кроме Того, I приходится не соглашаться с практикой присвоения каждому первичному ключу одного и того же имени, например "id". Это затрудняет, а не облегчает понимание запросов. Первичные ключи должны быть названы в честь таблицы. Например сотрудник.ид_сотрудника, филиал.affiliate_id, пользователей.ид_пользователя, и так далее.


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


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

до сих пор я использовал uniqueidentifiers (GUID) или инкрементные целые числа.

Ура Матиас!--11-->


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


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

некоторые люди любят использовать guids. ПРО есть то, что вы можете объединить несколько экземпляров базы данных без изменения любые разделы, но и то, что может повлиять на производительность.


для "естественного" ключа любой тип данных подходит для столбца(ов). Искусственные (суррогатные) ключи обычно являются целыми числами.


все зависит от того.

a) вы в порядке с уникальными последовательными числовыми номерами в качестве первичного ключа? Если да, то достаточно выбрать UniqueIdentifier в качестве первичного ключа. b) Если ваш бизнес-спрос таков, что вам нужен альфа-цифровой первичный ключ, тогда вам нужно пойти на varchar или nvarchar.

Это два варианта, которые я мог бы придумать.


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

эмпирическое правило: для высокой производительности вы должны иметь возможность хранить весь свой индекс в памяти. Идентификаторы можно легко сломать это!


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

http://www.codinghorror.com/blog/archives/000817.html


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

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

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

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


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


когда это возможно, попробуйте использовать первичный ключ, который является естественным ключом. Например, если бы у меня была таблица, где я регистрировал одну запись каждый день, logdate был бы хорошим первичным ключом. В противном случае, если нет естественного ключа, просто использовать int. Если вы думаете, что будете использовать более 2 миллиардов строк, используйте bigint. Некоторые люди любят использовать GUID, который работает хорошо, так как они уникальны, и у вас никогда не закончится пространство. Тем не менее, они бесполезно долго, и трудно ввести, если вы просто делаете adhoc запросы.