В таблице _copies у меня хранятся все экземпляры всех имеющихся книг. Одно из полей там - lib_id - не ключевое, и не идентификатор. Там записан "библиотечный номер" этого экземпляра (8 цифр - типа 12345678).
Есть форма для добавления нового экземпляра какой-нибудь книги. В этой форме вручную вписывается этот "библиотечный номер" экземпляра.
Хочу сделать на этой форме кнопочку, которая бы вставляла рекомендуемое значение этого номера.
Представляю себе алгоритм примерно таким:
1. Берём минимальное значение, котороое можем использовать для библиотечного номера - например 10000000 (значение задано в настройках, например).
2. Прибавляем единицу и смотрим, доступно* ли это значение (10000001)
3. Если доступно - рекомендуем его.
4. Если нет - смотрим следующее значение (переходим к пункту 2).
5. RPOFIT
*Доступно - то есть нет никакого другого экземпляра с таким номером.
Подскажите, как реализовать?
Спустя 1 час, 50 минут, 53 секунды (21.04.2011 - 14:25) djar написал(а):
<?php
include("sql_connect.php");
$i = 10000000;
do {
$i++;
$res = mssql_query("SELECT * FROM _copies WHERE lib_id='".$i."'");
$number = mssql_num_rows($res);
if ($nubmer == 0) {
$row = mssql_fetch_assoc($res);
$find = 1;
}
}
while (is_null($find));
$lib_id = $row['lib_id'];
?>
А как долго этот цикл будет проходить, например, сто тысяч записей?
Спустя 1 час, 13 минут, 32 секунды (21.04.2011 - 15:39) Renden написал(а):
djar
Самое простое это запрос вида
На выходе имеем максимальное знаечени lib_id котрое есть в базе, прибавляем к нему +1 и выводим пользователю как предлагаемое)
Ибо не вижу смысла в том что в 8 цифарак будет значение которое свободно между всеми книгами. Лучше брать макс и прибавлять 1.
Ну или на крайний случай, генерировать его рандомо rand() в каком-то диапазоне, например от 100000000 до 200000000 и это число проверять на наличие в базе, если его нет предлагать пользователю, если есть генерить рандомом новое и опять проверять и предлагать.
Ибо дело тут не в циле php он даже на милион думаю выполнится достаточно быстро, дело в том что в этом циле запрос, допустим он будет 0.0001 мс, 100 тыс записей будет выполняться как минимум 100 секунд, но так быстро запрос врятли выпонится, скорее всего у тя таймаут скрипта уйдет и php просто отвалиться, а если нет, ждать ты будешь минут 10)))
Самое простое это запрос вида
SELECT lib_id FROM _copies ORDER BY lib_id DESC
LIMIT 1
На выходе имеем максимальное знаечени lib_id котрое есть в базе, прибавляем к нему +1 и выводим пользователю как предлагаемое)
Ибо не вижу смысла в том что в 8 цифарак будет значение которое свободно между всеми книгами. Лучше брать макс и прибавлять 1.
Ну или на крайний случай, генерировать его рандомо rand() в каком-то диапазоне, например от 100000000 до 200000000 и это число проверять на наличие в базе, если его нет предлагать пользователю, если есть генерить рандомом новое и опять проверять и предлагать.
Ибо дело тут не в циле php он даже на милион думаю выполнится достаточно быстро, дело в том что в этом циле запрос, допустим он будет 0.0001 мс, 100 тыс записей будет выполняться как минимум 100 секунд, но так быстро запрос врятли выпонится, скорее всего у тя таймаут скрипта уйдет и php просто отвалиться, а если нет, ждать ты будешь минут 10)))
Спустя 15 часов, 11 минут, 58 секунд (22.04.2011 - 06:51) djar написал(а):
Renden, спасибо, попробую сделать rand().
Брать максимальное и прибавлять не получится потому, что, ну вот я пришёл автоматизировать библиотеку. Сначала забиваем те книги, которые в ней имеются, а вряд ли мы будем перебирать их по порядку этого lib_id. Сначала возьмём 678, потом 125 - а если в итоге получися, что между ними не все номера заполнены книгами, кто знает?) Пропадёт место, которое можно было бы заполнить новыми экземплярами.
Брать максимальное и прибавлять не получится потому, что, ну вот я пришёл автоматизировать библиотеку. Сначала забиваем те книги, которые в ней имеются, а вряд ли мы будем перебирать их по порядку этого lib_id. Сначала возьмём 678, потом 125 - а если в итоге получися, что между ними не все номера заполнены книгами, кто знает?) Пропадёт место, которое можно было бы заполнить новыми экземплярами.
Спустя 26 минут, 47 секунд (22.04.2011 - 07:17) Семён написал(а):
В таких случаях нужно использовать hash
Спустя 9 минут, 16 секунд (22.04.2011 - 07:27) djar написал(а):
Семён, где конкретно использовать? Это функция php?
Спустя 1 минута, 26 секунд (22.04.2011 - 07:28) Игорь_Vasinsky написал(а):
Renden
Цитата |
SELECT lib_id FROM _copies ORDER BY lib_id DESCLIMIT 1 |
Или так
SELECT MIN(`lib_id`) as `lib_id` FROM _copies
Спустя 3 минуты, 41 секунда (22.04.2011 - 07:32) Игорь_Vasinsky написал(а):
Цитата |
1. Берём минимальное значение, котороое можем использовать для библиотечного номера - например 10000000 (значение задано в настройках, например). 2. Прибавляем единицу и смотрим, доступно* ли это значение (10000001) |
И зачем каждый раз проверять есть ли значение в БД или нет, может сразу выдёривать MAX и + 1 ?
SELECT MAX(`lib_id`) as `lib_id` FROM _copies
Спустя 4 минуты, 20 секунд (22.04.2011 - 07:36) Игорь_Vasinsky написал(а):
Цитата |
Брать максимальное и прибавлять не получится потому, что, ну вот я пришёл автоматизировать библиотеку. Сначала забиваем те книги, которые в ней имеются, а вряд ли мы будем перебирать их по порядку этого lib_id. Сначала возьмём 678, потом 125 - а если в итоге получися, что между ними не все номера заполнены книгами, кто знает?) Пропадёт место, которое можно было бы заполнить новыми экземплярами. |
Тогда о какой автоматизации идёт речь? если всё ручками...
Спустя 36 минут, 25 секунд (22.04.2011 - 08:12) djar написал(а):
Цитата |
Тогда о какой автоматизации идёт речь? если всё ручками... |
А как иначе, если я принесу свою программу в уже работающую библиотеку. Как им заносить сведения о своих книгах в БД? Сначала lib_id вписывать вручную, чтобы не приходилось заново регистрировать экземпляры в каталогах. Как весь фонд занесут и придут новые книги - тогда уже нужно будет придумывать lib_id для этих новых экземпляров, и тут то и понадобится кнопка "предложить номер".
Сделал рандомом, работает. Ещё бы не работало)
do {
$lib_id_rec = rand(10000001,99999999);
$res = mssql_num_rows(mssql_query("SELECT * FROM _copies WHERE lib_id='".$lib_id_rec."'"));
if ($nubmer == 0) {
$find = 1;
}
}
while (is_null($find));
Спустя 56 минут, 11 секунд (22.04.2011 - 09:09) Семён написал(а):
нужно в lib_id генерировать не число, а hash вида
f6148d5327b13587db953ec7f72052dd
f6148d5327b13587db953ec7f72052dd
Спустя 9 минут, 44 секунды (22.04.2011 - 09:18) djar написал(а):
Семён, а для чего?