Делимся секретами создания сайтов

Обновление ID в MySQL

например таблица:
id|code

id - примари кей, автоинкр чотоам забыл какпишеца.... ну короче +1 с каждым insert...

значения вносятся в базу, через сутка удаляются...
можно как-то что-бы id при инсерте вместо +1 (auto_...) назначался номер из освобожденных (по прошествии суток)...

т.е. например седня зарегано:
id|code|
1|fdhrt45|
2|fdhrt45|
3|fdhrt45|
4|fdhrt45|
5|fdhrt45|
6|fdhrt45|

завтра уже удалены:
1|fdhrt45|
2|fdhrt45|
3|fdhrt45|
4|fdhrt45|

в базе остались:
5|fdhrt45|
6|fdhrt45|

и чтобы при insert добавился не id=7, а id=1 и т.д., т.е.

1|fdhrt45|
2|fdhrt45|
3|fdhrt45|
4|fdhrt45|
7|fdhrt45|
...

Ответы: 19 → “Обновление ID в MySQL”

  1. Денис Панкратов Ответить

    Средствами мускула – нет.
    Но если я правильно понимаю, то ид у вас ни есть уникальный ключ…
    Тогда 2 вопроса
    Тогда зачем вам ид в таком виде вообще.. ?
    Почему нельзя чтобы ид продолжали увеличиваться – какую цель приследуете этой задачей?

  2. Сергей Екимов Ответить

    если это автоинкремент, то обнулить счетчик можно с помощью sql 'TRANCATE table_name', но при этом похерятся все данные в таблице.

    не зваморачивайся, пускай остается как есть

  3. Евгений Неверов Ответить

    Автоинкрементные поля не предназначены для считания "по порядку", они нужны просто для уникальности значений. Используйте другие средства.

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

  4. Axel Foly Ответить

    можно замутить 3-мя запросами:
    1. выбираешь из таблицы строки, которые должны остаться, запомниаешь их (в массив какой-нить);
    2. "TRUNCАTЕ `table_name`;" – как и было предложено ранее (вместо удаления данных вручную). заодно значение автоинкремента сбрасывается в 1;
    3. вставляешь запомненные строки.

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

  5. Евгений Неверов Ответить

    Это не решение, а создание проблем. А если в таблице пара миллионов записей, вы где оперативную память под всё это достанете? Или будете на винт скидывать?

    Бред, в общем.

  6. Михаил Полянин Ответить

    Согласен с Евгением Неверовом, что вся эта затея полный бред. Автор как я понял хочет такое реализовать для упорядочности… но делать это средствами мускла совсем не есть гуд

  7. Евгений Неверов Ответить

    В конце-концов, всегда можно написать инкремент в том цикле, где вы выбираете данные из базы.

  8. Алеша Душевнобольной Ответить

    мне нужно создание кода, и возможность поиска его по id в течение суток после создания… просто код будет создаваться очень часто, а оно int(10), и этот int быстро дойдет до лимита… ладно бы там все значения хранились, а они по истечение суток удаляются (да, я не дописал в базе последний столб id|code|date), т.е. одновременно в базе будет например 1000 значений, а id будет постоянно увеличиваться… обнулять все не канает, т.к. в момент обнуления может поступить запрос от другого пользователя на другой код из тех у которых сутки не вышли…

  9. Михаил Полянин Ответить

    средствами мускула думаю никак, а так можно если id самому прописывать, Т.е. можно извращаться как-нить так:
    $id = 1;
    while (mysql_num_rows (mysq_query ("select id from `TABLE` where `id` = $id")))
    { $id++;}
    // Получишь наименьшее id которое не занято, т.е. потом что-то типа
    mysql_query ("insert into TABLE value ('$id', 'code', 'date'));

  10. Алексей Андреев Ответить

    >> / Получишь наименьшее id которое не занято, т.е. потом что-то типа
    >> mysql_query ("insert into TABLE value ('$id', 'code', 'date'));

    А если кто нибудь с другой сессии "влезет" с записью после получения id но до вставки в таблицу с новым id в текущей сессии?
    Это не есть гуд.

  11. Алексей Андреев Ответить

    Вот варианты:
    1. Откажитесь от этого поля, если можно без него.
    2. Используйте составной индекс в которой последнее поле – AUTO_INCREMENT, для независимой нумерации (например для каждого дня).
    3. Используйте дополнительную таблицу учета и блокирования id-ов сессиями.
    4. Не удаляйте записи, а меняйте ее статус на удаленную. При добавлении новой записи сначала попробуйте изменить удаленную запись (UPDАTЕ table1 SET del_flag = 0, …, … WHERE del_flag = 1 LIMIT 1), а затем, если не получится (affected_rows()==0), уже добавить новую.

    У каждого варианта есть свои НО, думаю разберетесь.
    Может есть еще варианты, но думаю и этих хватит.

  12. Евгений Неверов Ответить

    Используйте PostgreSQL, там есть последовательности (sequences), с помощью которых это достаточно легко всё реализуется.

  13. Михаил Полянин Ответить

    > А если кто нибудь с другой сессии "влезет" с записью после получения id но до вставки в таблицу с новым id в текущей сессии?

    Можно флаг какой-нить в файле ставить перед всем этим, и не забыть включить блокировку. Т.е. перед тем как начать искать наименьшее id тупо записывать в него 1 перед поиском и 0 после добавления, след пользователь будет ждать, пока блокировка снимется… Хотя всё через ж…у получается. А вообще автору структуру нужно правильно продумать и не придёться заниматься извратом

  14. ALTER TABLE `category` AUTO_INCREMENT =5045

    и все !

    нинадо никаких truncate

  15. Евгений Неверов Ответить

    Опять неправильное решение.

    Смотрите: у меня есть в таблице три записи с ID 1, 2 и 3 соответственно.
    Я удаляю запись номер 2 и делаю ALTER TABLE `table` AUTO_INCREMENT = 2
    Вставляю запись — она получает ID = 2 и всё корректно. Вставляю следующую запись и получаю ошибку: запись с ID = 3 уже существует.

    Так что это не решение вообще.

  16. вот ошибку ты не получишь это точно )

    сделай эксперимент и получишь результат ! ) очень даже интересный

  17. Евгений Неверов Ответить

    Что-то вообще странное: у меня на 5.0.51 ALTER меняющий AUTO_INCREMENT просто не вызывает никакого эффекта.

  18. Евгений Неверов Ответить

    И вставки продолжают идти дальше с последнего значения.

  19. ) это и есть результат !

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

Ответить