Создать уникальный order_id

Привет! подскажите как сгенерировать уникальный order_id для заказа если в БД более 500 000 заказов?

Заказы хранятся в таблице ORDERS

Мой алгоритм верный или есть более правильный?

order_id должен быть в диапазоне от 0 до 9999999 Целым.

1 взять все order_id из таблицы ORDERS и сохранить массив в $db_orders
2 $tmp_order_id = rand(0, 99999999);
3. in_array($tmp_order_id, $db_orders) - Если в массиве - формируем новый случ $tmp_order_id и выполняем снова проверку на шаге 3.
4 если не в масиве - пишем в БД

Этот алгоритм сработает, если в БД мало order_id а как быть если order_id в БД больше 500 000?
 

fixxxer

К.О.
Партнер клуба
order_id должен быть в диапазоне от 0 до 9999999
Почему?

Этот алгоритм сработает, если в БД мало order_id а как быть если order_id в БД больше 500 000?
Получить дырку в нумерации можно одним sql-запросом, сджойнив таблицу саму на себя. Но все еще непонятно, зачем.

Если такой диапазон нужен для какой-то внешней фигни, имеет смысл завести отдельное поле для этой внешней фигни, а с основным id не извращаться и использовать обычный sequence / autoincrement.
 
Мне надо просто в БД вставлять заказ с order_id которого в БД нету.. чтобы заказ был УНИКАЛЬНЫМ! как мне это сделать..
 
можно взять и больший диапазон.. но не меньший..

Уникальным полем в таблице ORDERS есть order_id. Поле id в таблице ORDERS - это Autoincrement

Это не для внешней фигни.. просто нужно чтобы в таблицу помещался только ЗАКАЗ с уникальным order_id где order_id прин диапазону от 1 до 999999 или больше.. если заказ в БД с предв сформированным order_id - существует - формируем новый order_id и так до тех пор пока order_id не станет уникальным

Если еще другой алгоритм.. но не знаю, насколько он эффективнее первого

$tmp_order_id = rand(0,999999);
Проверяем содержится ли заказ с $tmp_order_id в БД. Если вернулась строка - формируем новый $tmp_order_id и так до тех пора пока не вернет 0 СТРОК.. но такие проверки могут длится очень долго если заказов в БД дохера..
 
Последнее редактирование:
Блин.. ну не то..
Пример.. пред order_id = 100
если использовать auto_increment для поля order_id то
след order_id будет 101 и
клиент если делает часто заказы сможет иметь представление о кол-ве заказов что делает магазин в любой пром. времени.

нужно, чтобы след order_id - было случайным УНИКАЛЬНЫМ ЦЕЛЫМ числом в диапазоне от 1 до 999999 или больше .. даже если в таблице ORDERS будет всего 100 строк то их order_id должны быть случайными и уникалыными.. из диапазона выше.
Пример в таблице 100 строк
order_id = 34553
order_id = 5
order_id = 898797

и т.д. еще 97 строк и все они с УНИКАЛЬНЫМ СЛУЧАЙНЫМ order_id

Как это реализовать самым эффективным способом?
 

fixxxer

К.О.
Партнер клуба
след order_id будет 101 и клиент если делает часто заказы сможет иметь представление о кол-ве заказов что делает магазин в любой пром. времени.
Наконец-то я увидел ответ на вопрос "зачем".

Сделай xor с константой на уровне пользовательского интерфейса.
 
RAND() - после генерации проверяй, есть уже такое значение или нет.
я об этом уже писал , что это не самый эффект способ.. если в таблице дохера строк..
вот этот алгоритм..

$tmp_order_id = rand(0,999999);
Проверяем (SELECT * FROM orders WHERE order_id=$tmp_order_id) содержится ли заказ с $tmp_order_id в БД. Если вернулась строка - формируем новый $tmp_order_id и так до тех пора пока не вернет 0 СТРОК.. но такие проверки могут длится очень долго если заказов в БД дохера..
Если $tmp_order_id = rand(0,999999); будет 500 или больше раз гененрировать одно и то же число, а это число $tmp_order_id уже содержится в БД то такие проверки будут очень долгими.
 

fixxxer

К.О.
Партнер клуба
Можно подробнее.. совсем не понял о чем вы написали.
Задача, на самом деле, в том, чтобы не показывать пользователю реальные идентификаторы, поскольку это раскрывает информацию о количестве заказов.
К настоящим идентификаторам товаров это отношения никакого не имеет, "рандомизированный" идентификатор тут - элемент пользовательского интерфейса.
Соответственно, задача сводится к тому, чтобы поставить в соответствие последовательным номерам "перемешанные": 1 -> x1, 2 -> x2, ..., n -> xN.
Проще всего это сделать xor-ом с захардкоженной константой.
 
Проще всего это сделать xor-ом с захардкоженной константой.
Спасибо! Теперь более понятно.. но все-равно не понятны слова ХОГ , Захардкоженная константа!

Можно хоть несколько элементарных примеров чтобы я понимал о чем речь.
 
поставить в соответствие последовательным номерам "перемешанные": 1 -> x1, 2 -> x2, ..., n -> xN.
все-таки не совсем тоже правильно.. менеджер же должен находить информацию о заказе по тому номеру (идентификатору) что клиент ему скажет.. т.е. эти ДОПОЛНИТЕЛЬНЫЕ идентификаторы заказа (тоже уникальные) что должны показыватся пользователю нужно хранить в БД с информацией о заказе..
 
Если разбить SQL SELECT order_id на несколько частей при которых может возвращаться массив $result cодерж до 100 000 строк и поочередно проверять in_array($tmp_order_id, $result) - если не найден, отправляем след запрос со смещением и получаем новые данные ... если же найден - формируем новый $tmp_order_id и выполняем заново SQL SELECT order_id
 
Задача, на самом деле, в том, чтобы не показывать пользователю реальные идентификаторы, поскольку это раскрывает информацию о количестве заказов.
К настоящим идентификаторам товаров это отношения никакого не имеет, "рандомизированный" идентификатор тут - элемент пользовательского интерфейса.
Соответственно, задача сводится к тому, чтобы поставить в соответствие последовательным номерам "перемешанные": 1 -> x1, 2 -> x2, ..., n -> xN.
Проще всего это сделать xor-ом с захардкоженной константой.
клиент может позвонить менеджеру и узнать инф по заказу и будет сообщать менеджеру order_id что видит у себя в кабинете.. как тогда менеджер найдет такой ордер в своей админке
 

jonjonson

Охренеть
Можно играться с составным идентификатором. Автоинкрементный идентификатор совместить с частью TIMESTEMP или частью даты и/или времени, дня недели. При этом к дате и времени применить CRC16. Можно поиграться с функцией MySQL UUID() и использовать часть её значения с автоинкрементным значением.

Главное задокументировать решение.
 

scorpion-ds

Новичок
Можно играться с составным идентификатором. Автоинкрементный идентификатор совместить с частью TIMESTEMP или частью даты и/или времени, дня недели. При этом к дате и времени применить CRC16. Можно поиграться с функцией MySQL UUID() и использовать часть её значения с автоинкрементным значением.
Любопытно, но именно это я вчера предложил, но мой комментарий почему-то удалили.

P.S.: Наверно правила форму как-то обновились, а я не знал ...
 
Сверху