Есть ли причина не использовать auto_increment в индексе для таблицы базы данных? - PullRequest
7 голосов
/ 24 ноября 2010

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

Каждая вставка базы данных (добавлениетовар в корзину и т. д.) начинается с функции grab_new_id, которая СЧИТЫВАЕТ количество строк в таблице, а затем, начиная с этого числа, запрашивает базу данных, чтобы найти неиспользуемый индексный номер.В дополнение к ужасной производительности (уже более 40 000 строк и индексы регулярно удаляются, поэтому иногда для поиска нового идентификатора требуется несколько секунд), это происходит регулярно, когда две операции выполняются одновременно, так как добавляются две записис дублирующимися идентификационными номерами.

Это кажется мне идиотским - почему бы просто не использовать автоинкремент в поле индекса?Я проверил это обоими способами, и добавление строк в таблицу без указания идентификатора индекса (очевидно) во много раз быстрее.Мой вопрос: может ли кто-нибудь придумать причину, по которой это мог сделать оригинальный программист?Есть ли какая-то школа мысли, где auto_increment почему-то считается дурным тоном?Существуют ли базы данных, которые не имеют возможности автоинкремента?

Ответы [ 8 ]

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

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

Некоторые люди применяют подход «по-своему» ко всему, часто потому, что они не удосужились посмотреть, доступна ли эта функция или кто-то ужепридумать это.Вы часто будете видеть сумасшедшие обходные пути или неэффективный / хрупкий код от этих людей.Наследовать плохую базу данных совсем не весело, удачи!

5 голосов
/ 24 ноября 2010

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

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

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

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

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

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

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

Две вещи, на которые нужно обратить внимание:

1. Ваша СУБД интеллектуально устанавливает значение автоинкремента при перезапуске. Наши инженеры катили свой собственный ключ автоинкремента, чтобы обойти поле автоинкремента, прыгая порядка 100000 с при каждом перезапуске сервера. Однако в какой-то момент Sybase добавил опцию для установки размера автоинкремента.

2. Другое место, где автоинкремент может стать неприятным, - это если вы реплицируете базы данных и используете конфигурацию мастер-мастер. Если вы пишете в обе базы данных (НЕ ПРЕДУСМОТРЕНО), вы можете столкнуться с идентификационной коллизией.

Я сомневаюсь, что это имело место, но нужно знать об этом.

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

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

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

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

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

0 голосов
/ 24 ноября 2010

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

...