Как предотвратить автоматическое увеличение от пропуска идентификаторов в базе данных MySQL? - PullRequest
4 голосов
/ 13 апреля 2011

Хорошо, допустим, у меня есть таблица базы данных mysql с двумя столбцами, один для идентификатора, а другой для пароля.Если у меня есть три строки данных и значения идентификатора меняются от 1 до 3, и я удаляю строку 3, а затем создаю еще одну строку данных, я буду видеть id = 4 вместо id = 3 во вновь созданной строке.Я знаю, что это связано со значением автоинкремента, но мне было интересно, могу ли я добавить некоторый код в php-файл, который автоматически сбросит все номера идентификаторов, так что вы начинаете с id = 1 и переходите к последнему номеру вс шагом 1 после удаления строки?

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

Обновление.установка случайного числа от 1 до 4 для переменной, чтобы файл php извлекал случайное объявление с id = 1 до id = 4, используя переменную случайного числа.Если случайное число окажется равным 3, а id = 3 не существует, в строке баннерной рекламы будет пробел.Если есть способ обойти большие пробелы в этой ситуации, пожалуйста, сообщите мне.заранее спасибо

Ответы [ 5 ]

4 голосов
/ 13 апреля 2011

Просто выполните следующий запрос SQL:

ALTER TABLE `tbl_name` AUTO_INCREMENT = 1;

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

3 голосов
/ 13 апреля 2011

Вы можете использовать только

ALTER TABLE 'tbl' AUTO_INCREMENT=#

, чтобы сбросить число выше максимального значения.Если у вас есть 1, 2, 3 и вы удаляете 2, вы не можете использовать это для заполнения 2. Если вы удалите 3, вы можете использовать это для повторного использования 3 (при условии, что вы не поместили ничего выше).Это лучшее, что вы можете сделать.

1 голос
/ 13 апреля 2011
ALTER TABLE 'table' AUTO_INCREMENT = 1;

Однако запуск этого кода - не лучшая идея. Что-то не так с вашим приложением, если вы зависите от пробелов в столбце. Вы пытаетесь подсчитать количество пользователей? если так, то используйте COUNT (id)? Вы пытаетесь разобраться с другими столами? Если это так, используйте внешний ключ.

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

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

0 голосов
/ 13 апреля 2011

Ну, на самом деле вы можете просто указать номер идентификатора, который вы хотите, чтобы запись была в составе вашего оператора вставки, например:

INSERT INTO person VALUES(1,'John','Smith','jsmith@devnull.fake','+19995559999');

И если нет столкновения первичного ключа (нет записи в базе данных с id = 1), MySQL с радостью выполнит его.

ALTER TABLE 'tbl' AUTO_INCREMENT=# также работает, и означает, что вам не нужно отслеживать счетчик.

Хотя, пока вы думаете об этом, вам, возможно, захочется прочитать некоторые обсуждения Natural vs Surrogate Key Идея о том, чтобы ваш идентификатор был особенно важен, немного необычна и может быть признаком проблемного дизайна.

0 голосов
/ 13 апреля 2011

Вы можете сделать это следующим образом:

  1. Изобретая механизм, который предоставляет следующий доступный идентификатор, когда вы хотите вставить (например, транзакцию, включающую чтение и приращение где-то целочисленного столбца - обратите особое внимание науровень изоляции транзакции!)
  2. Использование UPDATE для уменьшения всех идентификаторов больше, чем тот, который вы только что удалили (опять же, для транзакции - не забывайте, что внешние ключи должны быть ON UPDATE CASCADE!)

Но возникает вопрос: зачем вам это?это будет стоить неприятностей?

Почти наверняка вы можете достичь любой своей цели без такого колдовства.

Обновление (для ответа на комментарий):

Чтобы выбрать случайное количество строк, вы можете, например, в MySQL

SELECT id FROM banners ORDER BY RAND() LIMIT 5

выбрать 5 случайных, гарантированных существующих идентификаторов баннеров.

Предостережение: есть довольно много людей, которые считают ORDER BY RAND() плохой фигурой.Тем не менее, ИМХО не совсем правильно ставить все дела в одну корзину.Если количество строк в таблице является управляемым (я бы посчитал, что все, что меньше 10 КБ, не так уж много), тогда ORDER BY RAND() дает очень хорошее и лаконичное решение.Кроме того, документация сама предлагает такой подход:

Однако вы можете извлекать строки в случайном порядке, например:

mysql> SELECT * FROM tbl_name ORDER BY RAND();

ORDER BY RAND () в сочетании с LIMIT полезен для выбора случайной выборки из набора строк:

mysql> SELECT * FROM table1, table2 WHERE a = b И c ORDER BY RAND () LIMIT 1000;

RAND () не должен быть идеальным генератором случайных чисел.Это быстрый способ генерирования случайных чисел по требованию, переносимый между платформами для одной и той же версии MySQL.

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