Примечание. Я новичок в базах данных и PHP.
У меня есть столбец order
который настроен на auto increment
и unique
.
http://img.ruphp.com/php/Image 2013-07-22 at 7.00.15 PM.png
В моем PHP-скрипте я использую AJAX для получения новых данных, но проблема заключается в том, что order
пропускает числа и существенно выше, что заставляет меня вручную обновлять числа при вставке данных. В этом случае я бы в итоге изменил 782
на 38
.
http://img.ruphp.com/php/Image 2013-07-22 at 6.49.20 PM.png
$SQL = "INSERT IGNORE INTO `read`(`title`,`url`) VALUES\n ".implode( "\n,",array_reverse( $sql_values ) );
Как я могу заставить его увеличивать +1?
По умолчанию поведение auto_increment в MySQL 5.1 и более поздних версиях будет «потерять» значения автоматического увеличения, если INSERT завершится с ошибкой. То есть, он увеличивается каждый раз на 1, но не отменяет приращение, если INSERT терпит неудачу. Это редкость потерять ~ 750 значений, но не невозможно (я консультировался на сайте, который пропускал 1500 для каждого INSERT, который преуспел).
Вы можете изменить innodb_autoinc_lock_mode=0
чтобы использовать поведение MySQL 5.0 и в некоторых случаях избегать потери значений. Подробнее см. http://dev.mysql.com/doc/refman/5.1/en/innodb-auto-increment-handling.html .
Еще одна вещь, которую нужно проверить, – это значение переменной конфигурации auto_increment_increment
. По умолчанию это 1, но вы, возможно, изменили это. Опять же, очень редко, чтобы установить его на что-то выше 1 или 2, но возможно.
Я согласен с другими комментаторами, столбцы autinc предназначены для того, чтобы быть уникальными, но не обязательно последовательными. Вы, вероятно, не должны беспокоиться об этом так сильно, если вы не повышаете значение autoinc настолько быстро, что можете выбежать из диапазона INT (это случилось со мной).
Как именно вы исправили его, пропустив 1500 навсегда?
Причиной сбоя INSERT было то, что на нем был еще один столбец с ограничением UNIQUE, и INSERT пытался вставить повторяющиеся значения в этот столбец. Прочтите страницу руководства, на которую я связан, для получения подробной информации о том, почему это имеет значение.
Исправление заключалось в том, чтобы сначала выполнить SELECT, чтобы проверить наличие значения, прежде чем пытаться ВСТАВИТЬ его. Это противоречит общей мудрости, которая заключается в том, чтобы просто попробовать INSERT и обработать любое дублирующее ключевое исключение. Но в этом случае побочный эффект неудавшегося INSERT привел к потере значения auto-inc. Выполнение SELECT сначала устранило почти все такие исключения.
Но вам также необходимо обработать возможное исключение, даже если вы сначала выберите SELECT. У вас все еще есть состояние гонки.
Ты прав! innodb_autoinc_lock_mode = 0 работал как шарм.
В вашем случае я хотел бы знать, почему так много вставок терпят неудачу. Я подозреваю, что, как и многие разработчики SQL, вы не проверяете статус успеха после того, как выполняете свои INSERT в обработчике AJAX, поэтому никогда не знаете, что многие из них терпят неудачу.
Вероятно, они все еще терпят неудачу, вы просто не теряете auto-inc id как побочный эффект. Вы должны действительно диагностировать, почему так много неудач. Вы могли бы генерировать неполные данные или выполнять гораздо больше транзакций, чем это необходимо.
После изменения 782 в 38 вы можете сбросить автоинкремент с помощью ALTER TABLE mytable AUTO_INCREMENT = 39
. Таким образом, вы продолжаете 39.
Однако вы должны проверить, почему ваш разрыв настолько высок и соответствующим образом меняет ваш дизайн. Изменение состояния автоинформации не должно быть «по умолчанию».
Я знаю, что на вопрос уже был дан ответ. Но если вы удалили строки в таблице до этого, mysql запомнит используемый идентификатор / номер, потому что обычно ваш Auto increment является уникальным .. Поэтому поэтому не будет создавать повторяющиеся приращения. Чтобы переиндексировать и приращение от текущего максимального ID / целого числа, которое вы могли бы выполнить:
ALTER TABLE TableName AUTO_INCREMENT=(SELECT max(order) + 1 FROM tablename)
auto increment не заботится, если вы удаляете несколько строк – каждый раз, когда вы вставляете строку, значение увеличивается.
Если вы хотите нумерацию без пробелов, не используйте автоматическое увеличение и сделайте это самостоятельно. Вы можете использовать что-то подобное, чтобы добиться этого для вставки
INSERT INTO tablename SET `order` = (SELECT max(`order`) + 1 FROM (SELECT * from tablename) t), ...
и если вы удалите строку, вам необходимо вручную изменить порядок столбца