Функция автоматического увеличения в базе данных - PullRequest
11 голосов
/ 02 ноября 2010

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

Лучшее решение - сделать это с помощью кода, получив максимум моего первичного ключа, тогда, если значение не существует, максимальное значение будет 1 в противном случае max + 1.

Есть предложения по этой проблеме? Могу ли я использовать функцию автоматического увеличения?

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

примечание :: этот вопрос, как правило, не является специфическим для любой СУБД, я хочу знать, верно ли это и для СУБД, таких как ORACLE, Mysql, INFORMIX, ....

Большое спасибо.

Ответы [ 5 ]

11 голосов
/ 02 ноября 2010

Вы должны использовать идентификаторы (автоинкремент) столбцы.Тип данных bigint может хранить значения до 2 ^ 63-1 (9,223,372,036,854,775,807).Я не думаю, что ваша система скоро достигнет этого значения, даже если вы вставляете и удаляете много записей.

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

8 голосов
/ 02 ноября 2010

Тип данных int в SQL Server может содержать значения от -2 147 483 648 до 2 147 483 647.

Если вы заполнили свой столбец идентичностью -2,147,483,648, например, FooId identity(-2,147,483,648, 1) тогда у вас есть более 4 миллиардов значений для игры.

Если вы действительно думаете, что этого все еще недостаточно, вы можете использовать bigint, который может содержать значения от -9,223,372,036,854,775,808 до 9,223,372,036,854,775,807, но это почти гарантировано излишним. Даже при больших объемах данных и / или большом количестве транзакций вы, вероятно, либо исчерпаете место на диске, либо исчерпаете время жизни своего приложения, прежде чем исчерпаете значения идентификаторов при использовании int и почти наверняка при использовании bigint.

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

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

3 голосов
/ 02 ноября 2010

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

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

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

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

Теперь есть веские причины НЕ использовать поле идентификации, но это не одна из них.

3 голосов
/ 02 ноября 2010

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

1 голос
/ 02 ноября 2010

Я бы посоветовал ПРОТИВ использовать Identity / Auto-increment, потому что:

  • Его реализация нарушена в SQL Server 2005/2008. Подробнее

  • Это не очень хорошо, если вы собираетесь использовать ORM для сопоставления вашей базы данных с объектами. Подробнее

Я бы посоветовал вам использовать генератор Hi / Lo, если вы обычно обращаетесь к своей базе данных через программу и не зависите от отправки операторов вставки вручнуюв БД.Подробнее об этом вы можете прочитать во второй ссылке.

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