|
Организация очередей?
|
|||
---|---|---|---|
#18+
Привет! Кто-нибуть сталкивался с такой задачей: надо организовать базу движения очередей клиентов. Пока пришла только одна идея: создать таблицу с порядковыми номерами в очередях (таких 10), связанную один-к-одному с таблицей клиентов (чтоб не блокировать таблицу клиентов). При вставке/удалении в середину очереди открывать транзакцию, блокировать всю таблицу очередей, обновлять все записи более какого-то номера на N+1, вписывать освободившийся номер клиенту, закрывать транзакцию. А может есть идеи поэлегантнее и, главное, понадежнее? ... |
|||
:
Нравится:
Не нравится:
|
|||
04.12.2004, 23:55 |
|
Организация очередей?
|
|||
---|---|---|---|
#18+
1. 10 очередей или 10 клиетов в очереди? 2. Обязательно ли клиенту знать его порядковый номер? ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2004, 14:57 |
|
Организация очередей?
|
|||
---|---|---|---|
#18+
2 Accessor: 1) 10 очередей (но это в принципе-то не важно), по 5-2000 клиентов на каждую, причем могут быть одновременно (пересекатются) 2) Обычно хотят знать. Но это критично знать самой организации, т.к. "снимок" очереди на определенный момент оформляется как документ. Пока работа идет в Word+Excel с кучей заморочек... А база (на dBase) пока учитывает только самих клиентов. Надо все это слить в одну задачу в Access. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2004, 19:58 |
|
Организация очередей?
|
|||
---|---|---|---|
#18+
Первое действительно не важно. А вот со вторым сложнее... А по какому признаку клиент заходит в очередь? Как определяется его место там? ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2004, 20:09 |
|
Организация очередей?
|
|||
---|---|---|---|
#18+
AccessorА по какому признаку клиент заходит в очередь? Как определяется его место там? По решению оператора на основе разных факторов, в т.ч. даты первого обращения, имеющихся преференций и т.д. Свободу у оператора отбирать нельзя. Ему будет выводиться только подсказка. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.12.2004, 23:36 |
|
Организация очередей?
|
|||
---|---|---|---|
#18+
Тогда, думаю что то что вы предложили - лучше всего. Если я правильно понял: Таблица clientqueue ----------- queue_id - идентификатор очереди client_id - клиент num - порядковый номер клиента в очереди Добавление в клиента C очередь Q под номером N в 2 приема: UPDATE clientqueue SET num=num+1 WHERE client_id=C AND queue_id=Q AND num>=N INSERT INTO clientqueue VALUES (Q,C,N) ... |
|||
:
Нравится:
Не нравится:
|
|||
06.12.2004, 00:48 |
|
Организация очередей?
|
|||
---|---|---|---|
#18+
AccessorТогда, думаю что то что вы предложили - лучше всего. Если я правильно понял: Таблица clientqueue ----------- queue_id - идентификатор очереди client_id - клиент num - порядковый номер клиента в очереди Добавление в клиента C очередь Q под номером N в 2 приема: UPDATE clientqueue SET num=num+1 WHERE client_id=C AND queue_id=Q AND num>=N INSERT INTO clientqueue VALUES (Q,C,N) ИМХО в упдате убрать условие client_id=C и оставить только queue_id=Q AND num>=N ибо (client_id, queue_id) это ключ!!! ... |
|||
:
Нравится:
Не нравится:
|
|||
06.12.2004, 09:02 |
|
Организация очередей?
|
|||
---|---|---|---|
#18+
paparome ИМХО в упдате убрать условие client_id=C и оставить только queue_id=Q AND num>=N ибо (client_id, queue_id) это ключ!!! Да, с client_id я ошибся. Извините. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.12.2004, 09:09 |
|
Организация очередей?
|
|||
---|---|---|---|
#18+
Работа с людми вещ тонкая наверняка будут разборки с операторами и клиентами на тему "вас тут не стояло" потому лучше оформлять не конкретное место в очереди, а добавлять клиента всегда в конец, а потом дополнительной проводкой(записью в таблицу) изменять его вес при сортировке обязательно сопровождая такое изменение служебной инфой кто , когда и пр. а сам вес вычислять по таблице проводок как Sum всех операций а порядковый номер в очереди на заданный учетный период будет получатся через нумерацию строк запроса (сумма с накоплением в отчете по полю =1) Минимальный набор операций 1)Добавить клиента в конец очереди 2)Удалить клиента из очереди 3)обогнать впереди стоящего 4)пропустить сзади стоящего все остальные действия можно представить ввиде последовательности элементарных операций из минимального набора ... |
|||
:
Нравится:
Не нравится:
|
|||
06.12.2004, 09:24 |
|
Организация очередей?
|
|||
---|---|---|---|
#18+
2 Accessor Спасибо за потдержку идеи :) Только я для ускорения работы хотел завести на каждую очередь отдельное поле или табличку... 2 Latuk Разборки оператор-клиент конечно бывают. Но все в основном регулируется нормативными актами/правилами, так что особо не поспорят :) И вставка чаще всего идет как раз где-то в середину. Ваша идея конечно интересная, но: - и как определять вес? Каждый раз поднимать всю исорию для Sum? - это чтобы вставить в начало очереди надо прогнать в цикле клиента через 2000 записей по-одному? Ни чего себе транзакция получится... При моем решении, хотя оно и "в лоб", можно обогнать/пропустить сразу 2000 клиентов. - сортировать по номерам нормально можно только в отчете. В форме (карточке) клиента номер нормально не получить. - надежность получается низкой, т.к. нет однозначного соответствия. - тормоза обеспечены однозначно. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.12.2004, 21:29 |
|
Организация очередей?
|
|||
---|---|---|---|
#18+
AbelТолько я для ускорения работы хотел завести на каждую очередь отдельное поле или табличку... Думаю что это нецелесообразно... От 20000 записей в таблице еще никто не умирал, а выгода налицо - не надо мучаться с 10-ю таблицами. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.12.2004, 22:40 |
|
Организация очередей?
|
|||
---|---|---|---|
#18+
Появилась связанная проблемка :( Если отследить сбой расчетов при появлении одинаковых номеров легко обычным GROUP BY, то как же отлавливать возможные "дырки" в последовательности? Гнать FOR...NEXT не хочется :( ... |
|||
:
Нравится:
Не нравится:
|
|||
07.12.2004, 00:31 |
|
Организация очередей?
|
|||
---|---|---|---|
#18+
Особойо проблемы я не вижу. Все делается посредством пары-тройки запросов. Например: добавление в очередь в определенную позицию (номер по порядку): Код: plaintext 1. 2. 3. 4.
Дальше по аналогии... ... |
|||
:
Нравится:
Не нравится:
|
|||
07.12.2004, 01:09 |
|
Организация очередей?
|
|||
---|---|---|---|
#18+
Я описаль лиш элементарные логические операции совсем не обязательно ими ограничиватся или физически организовывать их в лоб например по моему способу для вставки клиента в середину очереди достаточно добавить в таблицу проводок всего одну запись в ваше придется проадейтить всех кто ниже его. так же мой способ позволит определить место в очереди на любое время и легко строить разного рода отчеты например динамику продвижения в очереди и т.п. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.12.2004, 08:27 |
|
Организация очередей?
|
|||
---|---|---|---|
#18+
LatukЯ описаль лиш элементарные логические операции совсем не обязательно ими ограничиватся или физически организовывать их в лоб например по моему способу для вставки клиента в середину очереди достаточно добавить в таблицу проводок всего одну запись в ваше придется проадейтить всех кто ниже его. так же мой способ позволит определить место в очереди на любое время и легко строить разного рода отчеты например динамику продвижения в очереди и т.п. Я не говорю, что твой вариант плох, я просто предложил свой. Да и в апдэйте 2000 записей я не вижу никакой заморочки. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.12.2004, 09:16 |
|
Организация очередей?
|
|||
---|---|---|---|
#18+
Все извините что отвечаю вечером: на работе интернет отрубили 2 Vsevolod_V Как раз этот подход сначала и обсуждался. Минусы: - невозможно отследить историю очереди в целом (разве что делать иногда "слепок"); - надо при старте проверять на сбой расчетов (дубли номеров и дырки [последнее не совсем ясно]); - надо блокировать всю таблицу для update (но если очереди в разных табличках, то блокируется только одна); - необходимость явной транзакции (т.к. в 2 шага). Плюсы: - скорость работы; - однозначность интерпретации данных (клиент = N очереди), которые можно показать и в форме, и в отчете, и искать по нему! - независимость очереди от сбоя системных часов и ошибки ввода даты на машине оператора. 2 Latuk Ваш подход сложноват для практики, но интересен. Номер очереди получается расчетным и это теоретический плюс для БД. Но идея механизма проводок не совсем понятна. Ясно, что это id клиента, id очереди, время проводки и некий параметр изменения веса. Что это может быть? А если такой "вес" уже есть в базе? 2 All Неужели никто на практике не сталкивался с подобной задачей? ... |
|||
:
Нравится:
Не нравится:
|
|||
08.12.2004, 00:41 |
|
Организация очередей?
|
|||
---|---|---|---|
#18+
Для того чтобы уменьшить количесво обновлений в тразакции, можно делать не сплошную нумерацию, а с шагом скажем M. если клиент должен встать между номерами в очереди k1 и k2 - давать номер (k1+k2)/2 если k2>k1+1 ;в противном случае всем, тем имеет номер >=k2 добавить к номеру M и вернуться к предыдущему шагу Естественно, всё делать в одной транзакции ... |
|||
:
Нравится:
Не нравится:
|
|||
08.12.2004, 00:59 |
|
Организация очередей?
|
|||
---|---|---|---|
#18+
2 Alexey Sh Хорошая идея! ;) А порядковый номер, если не в отчете, тогда рассчитывать как Count(*) Where номер<=k. И чтобы реже двигать всех, сделать шаг M=1000. Собствернно говоря получился аналог "веса клиента", предложенный Latuk'ом ... |
|||
:
Нравится:
Не нравится:
|
|||
08.12.2004, 22:58 |
|
Организация очередей?
|
|||
---|---|---|---|
#18+
Abel2 Alexey Sh Хорошая идея! ;) А порядковый номер, если не в отчете, тогда рассчитывать как Count(*) Where номер<=k. И чтобы реже двигать всех, сделать шаг M=1000. Собствернно говоря получился аналог "веса клиента", предложенный Latuk'ом И не забыть добавить процедуру периодического переупорядочивания ... |
|||
:
Нравится:
Не нравится:
|
|||
09.12.2004, 10:50 |
|
Организация очередей?
|
|||
---|---|---|---|
#18+
Идея Латука интересна, но кажется не вполне прозрачна: Положим: 1)таблица клиентов. 2)Таблица очередей (не апдейтится). 3) Таблица "проводок" (сдвигов, с полями дат проводок). Для простоты возьмем 1 очередь. пример вырождается в таблицу клиентов (ik) с полем номере очереди N0, и таблицу шифтов с полями даты, клиента и величины сдвига (шифта shift). В 0 приближении новый номер клиента IK на дату DATE будет считаться как N=N0(IK) + Sum(shift(IK, date<DATE)) + f(ik<>IK) где физ смысл f(ik<>IK) - это сдвиг в очереди клиента IK из-за сдвигов других клиентов (ik<>IK). Если не учитывать этого момента, то будут совпадения в величинах N0(IK) + Sum(shift(IK, date<DATE)) для разных IK. Видит ли латук, как в SQL правильно посчитать шифт элемента из за сдвигов других? если я предположу, что от порядка шифтов на некий момент времени результат не изменится, я, кажется, могу записать: f ~ COUNT(ik, WHERE N0(ik)<N0(IK) AND (N0(ik)+ Sum(shift(ik<>IK,date<DATE))>N0(IK)) - COUNT(ik, WHERE N0(ik)>N0(IK) AND (N0(ik)+ Sum(shift(ik<>IK,date<DATE))<N0(IK)) - а это вполне переводится на SQL, правда скорость его будет похоже расти как произведение числа клиентов на полное число проводок в очереди. (и, честно сказать, я не до конца уверен в логичности перехода от перестановочности шифтов к приведенной записи функции сдвига номера текущего клиента сдвигами других). С другой стороны, если в таблице проводок все же при атомарной операции записывать не величину изменения "сдвига" для одного клиента, но величины всех сдвигов (тем не менее сохранив дату операции - для истории), то при увеличении числа записей в >~2 раза <~NO раз (2 - для перестановок только последовательных, а NO (где - NO длина очереди) - для перестановок из начала в конец очереди), мы сможем считать номер как N=N0(IK) + Sum(shift(IK, date<DATE)) (т.к. сдвиг других элементов уже учтен в параллельных проводках сдвига других клиентов той же операцией), и сэкономить на посчете внутренних сумм в вычислении сдвига другими клиентами. При этом: 1. все записи проводок только добавляются, блокировки (если есть позаписная) одним процессом другого быть не должно 2. таблицу "проводок" разумно разбить на 2 а)- "шапка" - таблица операций с полем даты и расшифровкой операции, б) - атомарные проводки-шифты элементов (согласованные проводки можно делать как в триггере, так и в приложении, в одной транзакции). ... |
|||
:
Нравится:
Не нравится:
|
|||
10.12.2004, 11:28 |
|
Организация очередей?
|
|||
---|---|---|---|
#18+
2 4321 Мдя... теперь ясно, что вариант Латука замечателен для Oracle, но убийствен для mdb :( Кстати, что Вы подразумеваете под триггерами в mdb :) Не могли бы прокомментировать следующие моменты: - Что Вы имеете в виду под "должен быть один процесс"? Ведь транзакция и так выступает как 1 процесс? - Отделять "шапку" в другую таблицу это для скорости? Или подразумевается 1 ко многим? - Чтобы изменить кого-то в середине очереди, надо одномоментно каждый раз добавлять по 1000 проводок? Если так, то у меня mdb, а не Oracle :( ... |
|||
:
Нравится:
Не нравится:
|
|||
10.12.2004, 23:43 |
|
Организация очередей?
|
|||
---|---|---|---|
#18+
З.Ы. Кстати, а смысл добавлять кучу шифтов, когда можно добавить на текущую дату просто пересчитанные номера очереди. И никаких count, sum etc. Просто "=" и усе!!! И история хранится, и устаревшую историю можно скидывать периодически в архив. Гениально. Вот что значит симбиоз идей ... |
|||
:
Нравится:
Не нравится:
|
|||
10.12.2004, 23:55 |
|
Организация очередей?
|
|||
---|---|---|---|
#18+
AbelЗ.Ы. Кстати, а смысл добавлять кучу шифтов, когда можно добавить на текущую дату просто пересчитанные номера очереди. И никаких count, sum etc. Просто "=" и усе!!! И история хранится, и устаревшую историю можно скидывать периодически в архив. Гениально. Вот что значит симбиоз идей Согласен. Более того, "проводки" при помощи одиночных записей "шифтов" плохи тем, что на самом деле высказанная выше гипотеза перестановочности сдвигов не имеет никаих прав на существование. (Что демонстрируется при помощи двух "сдвигов": - 2-го элемента через один и третьего через один - а именно, в зависимости от порядка мы будем в результате иметь либо 1-2-3-4 (если сначала сдвинуть второй, потом тертий) или 1-4-2-3 - если сначала сдвигать третий, потом второй)) Т.е. при помощи обычных групповых операций SQL итогового положения по истории "нессимметричной" записи проводок (только для одного элемента, а не всех согласованных сдвигов номеров очереди) не восстановить - нужно еще и учитывать порядок "проводок" - процедура становится существенно рекурсивной. Посему придется записывать все произошедшие сдвиги (именно это выше и предлагалось - "шапка" - идентификатор и аналитика операций, сдвиги - величины смещений нумерации всех сдвинутых операцией элементов). Что эквивалентно записи "снимка" очереди (достаточно перезаписать не всю очередь, а только сместившиеся при сдвиге элементы - записей в таблице истории будет существенно меньше, но с выборкой придется исхитрятся - на вскидку не так уж сложно - для каждого клиента надо выбирать последнюю по времени, не превосходящему момент выборки, запись в очереди, "моментальный снимок" будет запросом наподобие: SELECT ik, (SELECT TOP 1 nk From очередь WHERE очередь.ik = клиенты.ik AND очередь.Дата<=[Дата выборки] AND очередь.id=[очередь выборки] ORDER by очередь.Дата DESC) AS nk FROM клиенты) - тут надо смотреть, что вы предпочитаете оптимизировать, быстродействие на выбоку или объем и быстродействие на запись. Вероятный плюс записей полного снимка очереди: - можно наложить констрайнт типа уникального индекса (id,ДАТА,ik,nk), который будет гарантировать логическую непротиворечивость снимков как целое. При записи в историю только сместившихся в очереди клиентов такой контроль логической непротиворечивости за счет констрайнтов в мдб точно не возможен (придется в вба проверzть отсутствие совпадений nk в вышеприведенной выборке), а на SQL-сервере скорей всего потребует аналогичного (вба) триггера (на стейтмент, а не на запись) проверки непротиворечивости. ЗЫ. под триггерами в мдб я ничего не подразумеваю. я подразумеваю, что ваш мдб(адп,мде) может быть клиентом чего угодно, в т.ч. некоего "нечта", поддерживающего такие небезызвестные механизмы "обработки событий" данных, как тригеры на стейтмент. Если это так - уместнее использовать триггеры, чем ненадежный (не перекрывающий все возможные способы изменения данных) механизм обработки событий форм клиента. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.12.2004, 13:21 |
|
Организация очередей?
|
|||
---|---|---|---|
#18+
4321 При записи в историю только сместившихся в очереди клиентов такой контроль логической непротиворечивости за счет констрайнтов в мдб точно не возможен Ну почему же? Если завести поле "дата_устаревания", то должна соблюдаться уникальность всех записей по (id, ik, Nk, время_добавления, время_устаревания). Во всех новых записях время_устаревания = null или 0. ЗЫ. Нет, у меня .mdb будет как собственно база. Есть и Oracle, который я только админю, но писать для него приложения не собираюсь. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.12.2004, 16:46 |
|
|
start [/forum/topic.php?fid=45&msg=32813545&tid=1669658]: |
0ms |
get settings: |
9ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
34ms |
get topic data: |
9ms |
get forum data: |
3ms |
get page messages: |
70ms |
get tp. blocked users: |
1ms |
others: | 309ms |
total: | 457ms |
0 / 0 |