Как увеличивать id на +1 в mysql без AUTO_INCREMENT

Делаю телеграмм бота на telebot. Пользователь пишет команду /start и добавляется в БД с user_id телеграмма, и столбцом ID который я создал сам (для нормальной нумерации 1, 2, 3 и тд, для последующей частичной рассылки в будущем). И тут такая проблема, что авто инкремент оставляет цифру в памяти. То есть, если пользователь уже есть в БД, и пишет ещё раз /start, в БД он не добавляется, но следующий пользователь которого не было получает ID с пропуском цифры, потому что цифра предыдущего зарегистрированного осталась в памяти. То есть получается 1, 2, 9, 10 и тд. Собственно, как можно реализовать id+1? Или как то по другому можно?

def process_database(message):
    try:
        cursor = db.cursor()
        sql = "INSERT INTO people (user_id) VALUES ($s)"
        val = (message.from_user.id, )
        cursor.execute(sql,val)
        db.commit()
    except Exception as e:
            pass
    bot.send_message(message.chat.id,'Введите текст для перевода.')

ОБНОВЛЕНО: введите сюда описание изображения введите сюда описание изображения


Ответы (2 шт):

Автор решения: Manul74

Лучше не пользоваться такой ручной темой id+1. Могут быть дубликаты. Автоинкремент сделайте как и положено. А рядом ваше поле и там "инкрементируйте" уже как хотите. Например при вставке сделайте select Count и +1. Либо вариант. Рядом служебная таблица с автоинкрементом, куда вставляете что либо. Вам надо только для получения автоинкремент поля.Когда точно знаете что запись будет вставлена. Считываете с нее ID и вставляете в свою. Я так делал когда мне нужно было каждый год обнулять нумерацию документов. Но потеря номера была недопустима. Я обнулял служебную таблицу truncate table. Но в основной всеравно был автоинкремент. Он шел дальше. по типу получится:

AI    Ваша нумерация 
30    50
31    51
32    1   (с нового года)
33    2
34    3
...
→ Ссылка
Автор решения: hwak

с пропуском цифры

Откажитесь вообще от инкремента - генерируйте случайное число или UUID каждый раз. Или вообще используйте user_id телеграмма как собственный ID. Такой вариант будет оптимальнее всего без ущерба производительности.

И тут такая проблема,что авто инкремент,оставляет цыфру в памяти

Причина ошибки, вероятно, из-за того, что не откатилась транзакция, в которой sequence с ID увеличился.

Я думаю, вам нужно перед созданием INSERT проверять, что такой клиент уже создан, и если отсутствует, то только тогда делать INSERT.

INSERT INTO people (users_id)
SELECT * FROM (SELECT %s) AS tmp
WHERE NOT EXISTS (
    SELECT users_id FROM people WHERE users_id = %s
);

Ещё можно использовать синтаксис: INSERT IGNORE INTO table или INSERT … ON DUPLICATE KEY UPDATE

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

Если вы очень хотите обойтись без AUTO_INCREMENT, то можно было бы предложить сделать свой аналог sequence или например для каждого пользователя самостоятельно генерировать ID таким методом: select max(id) from table или select count(id) from table. Но эти варианты хуже по производительности)

→ Ссылка