Генерация последовательного идентификатора с использованием MySQL - PullRequest
0 голосов
/ 27 апреля 2020

Мне нужно создать ссылку на штрих-код для каждого полученного заказа. Первый штрих-код 200000 и увеличивается на 1 для каждого последующего заказа. Я должен быть абсолютно уверен, что я не назначаю один и тот же штрих-код более чем одному заказу. Проект получает много заказов и часто очень быстро.

Чтобы решить эту проблему, я создал таблицу базы данных MySQL с именем barcodes с первичным ключом с автоматическим приращением. Идентификатор первой строки - 200000.

Каждый раз, когда мне нужно сгенерировать штрих-код, я делаю вставку в таблицу barcodes и затем использую PHP mysqli_insert_id() для вставки идентификатора. Затем я обновляю таблицу orders, чтобы штрих-код был установлен на это значение.

Это хорошо работает и не позволяет мне присвоить один и тот же штрих-код более чем одному заказу.

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

select next_barcode from barcodes where id=1

И затем

update barcodes set next_barcode=next_barcode+1 where id=1

Моя проблема в том, что мой код может вызывать функцию который выполняет SELECT в одно и то же время (т. е. до выполнения ОБНОВЛЕНИЯ) и два заказа получают один и тот же штрих-код.

Возможно, существует надежный подход к блокировке таблицы? Или, может быть, мой нынешний подход - лучший способ go?

Ответы [ 2 ]

2 голосов
/ 27 апреля 2020

Что касается использования, auto_increment, который вы используете в настоящее время, является лучшим способом для go для вашего варианта использования. Уникальность гарантируется при проектировании , и база данных делает тяжелую работу для вас под капотом.

Единственный возможный недостаток - это то, что вы можете столкнуться с пробелами в id s, например если по какой-либо причине происходит сбой insert, последовательность id может быть потеряна, и следующая вставка снова увеличит id, что приведет к разрыву в последовательности.

Если это проблема для вам, тогда один вариант - использовать синтаксис insert ... select для получения последнего идентификатора и нового идентификатора в одном запросе при вставке, например:

insert into barcodes (id, ...)
select coalesce(max(id), 0) + 1, ...
from barcodes

Это предотвращает получение одинаковыми * 1016 двумя строками *. Но опять же, я бы не рекомендовал это; использование auto_increment более эффективно и просто.

2 голосов
/ 27 апреля 2020

То, что вы делаете, довольно хорошо. Вы гарантированно не получите один и тот же идентификатор дважды. Если вы изобретаете для этого свою собственную систему, вам нужно будет заблокировать множество таблиц, уничтожить параллелизм или сделать все через транзакции. Определенно возможно выполнить sh то, что вы делаете с транзакциями, но лучший способ go об этом, вероятно, будет в основном повторять то, что AUTO_INCREMENT уже делает ... это просто сложнее.

Одна вещь, которую нужно сохранить помните, что в некоторых случаях MySQL может пропустить идентификатор в AUTO_INCREMENT, но вы гарантированно никогда не получите один и тот же номер дважды.

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