Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / update limit / 12 сообщений из 12, страница 1 из 1
02.10.2014, 15:07:48
    #38764963
Jude
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
update limit
Дано:
есть таблица с чемто. пусть слоны будут.
слон_ид стадо_ид1 12 13 1
и т.д.
есть таблица с чемто, пусть будут стада слонов

стадо_ид род_стадо1 0

собственно задача: если в стаде стало слонов более 100 шт - создать новое (новые) стада. т.е. в стаде не может быть более 100 голов. и если не так, срочно перегнать в новосозданное.

допустим создал стада:
Код: sql
1.
 insert into стадо (род_стадо) select tt.sid from (select s.стадо_ид sid, count(1) cnt from слоны s group by стадо_ид  having cnt > 100) tt 


теперь нужно перегнать слонов.
стада, требующие перегона :
Код: sql
1.
select from стадо where род_стадо>0 


предположим я собрал где у меня стадо для приема, где стадо-источник:
Код: sql
1.
select st2.стадо source, st.стадо destn  from (select * from стадо  where род_стадо>0) st join  стадо st2 on st.род_стадо = st2.стадо 


теперь собственно перегоняемс:
Код: sql
1.
2.
3.
4.
5.
6.
7.
update
(select stt.* el.слон_ид sid from
(select st2.стадо source, st.стадо destn  from (select * from стадо  where род_стадо>0) st join  стадо st2 on st.род_стадо = st2.стадо) stt join слоны el on el.род_стадо = stt.source) 
limit 100)elef 
join слоны on elef.sid = слоны.слон_ид
SET
слоны.стадо_ид = elef.destn;



Для единственной группы - отлично работает.
а вот как быть если групп несколько?
ну например мы заранее не знаем, что переполненных стад - одно?
т.е. есть некая доп цветовая дифференциация, например серых слонов отдельно, а белых отдельно?
последнее в пример не добавлял, дыбы не загромождать.
т.е.

Код: sql
1.
 insert into стадо (род_стадо) select tt.sid from (select s.стадо_ид sid, count(1) cnt from слоны s group by стадо_ид  having cnt > 100) tt 


дает нам, скажем , 5 строк.
запомнить и делать
Код: sql
1.
2.
3.
4.
5.
6.
7.
update
(select stt.* el.слон_ид sid from
(select st2.стадо source, st.стадо destn  from (select * from стадо  where род_стадо>0) st join  стадо st2 on st.род_стадо = st2.стадо) stt join слоны el on el.род_стадо = stt.source) 
limit 100*5)elef 
join слоны on elef.sid = слоны.слон_ид
SET
слоны.стадо_ид = elef.destn;


не катит, т.к. нет гарантии, что все животные поделятся пачками по 100 шт. скорее будет одно стадо в 500 голов а остальным будет по 0.
в общем что-то затупил.
прошу помощи в наталкивании на светлую мысль. спасибо.
...
Рейтинг: 0 / 0
02.10.2014, 15:58:28
    #38765044
Jude
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
update limit
Jude,

ну или никто не понял, или все на обеде
в общем вариант

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
update
(select stt.* el.слон_ид sid from
(select st2.стадо source, st.стадо destn  from (select * from стадо  where род_стадо>0) st join  стадо st2 on st.род_стадо = st2.стадо) stt join слоны el on el.род_стадо = stt.source 
where el.род_стадо = :param1
limit 100)elef 
join слоны on elef.sid = слоны.слон_ид
SET
слоны.стадо_ид = elef.destn;


и бежать в курсоре param1 = как-то не хочется, но как бы решение на виду.
...
Рейтинг: 0 / 0
02.10.2014, 16:07:27
    #38765053
alex564657498765453
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
update limit
я бы логически решал эту задачу по другому


все новые слоны добавляем в текущее стадо(айди ноль)
смотрим, если там стало больше ста, делаем апдейт лимит 100(не одного лишнего, а 100 переганяем в новосозданное стадо)
а стадо с айди 0 будет всегда текущим, куда добавляються новые слоны

если мы хотим в рилтайме это делать.

чтобы гарантировано небыло стада с 100 слоном, тогда надо
логика как выше, + тригер на апдейт (тригер после вставки)

если периодически
и поэтому переполненых стад может быть несколько...по логике выше такого быть не может.
может быть что мы несколько раз из текущего стада, сможем сформировать новое на 100 голов
...
Рейтинг: 0 / 0
02.10.2014, 16:08:18
    #38765056
alex564657498765453
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
update limit
проще говоря, я предлагаю смотреть на это дело как на очередь...

новые слоны стоновяться в очередь, как только в очереди больше 100 слонов, первые 100 уходят стадом, остальные стоят ждут пока новая сотня не наберёться...
...
Рейтинг: 0 / 0
02.10.2014, 16:47:52
    #38765101
Jude
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
update limit
alex564657498765453проще говоря, я предлагаю смотреть на это дело как на очередь...

новые слоны стоновяться в очередь, как только в очереди больше 100 слонов, первые 100 уходят стадом, остальные стоят ждут пока новая сотня не наберёться...
ну как бы так и работает.

тут трудность в чем:
например пришло 20к слонов.
сделал групировку по, скажем , цветам.
создал базовые стада = 5шт, куда разместил новоприбывших (секретное поле ид = 0).
далее у части стад будет перебор по квоте - больше 100 голов.
для них делаю апдейт 100штукам с ид новосозданного стада.
но чтобы уйти от беготни в курсоре/хранимке / не дай бог на клиенте - изыскиваю пути как обойти этот момент.
ну вот с созданием - у меня парент ид = все новые но пустые стада легко выгребаются .
а вот как поперегонять по 100 из первой партии - не понятно, кроме как перебором.

т.е. в идеале было бы так, по моему пониманию:

создать стада 0 .
залить всех слонов.
для тех стад где count>100 создать по первому дочернему стаду.
перелить первых 100 слонов из "стада ид 0" - т.е. из тех самых первоночальных стад в новосозданные дочерние.

ну и вновь проверка. можно, к примеру, дочернем в том же мульте апдейте сделать парент = 0. оставив цвет слонов в покое.
после апдейта остатки слонов, к примеру:
стадо количествосинее 3450синее 1 100зеленое 2560зеленое 1 100красное 25красное 1 100белое 96серое 102серое 1 100
ну чтобы не с номерами, сделал буквы, для ясности.
т.е. на следующую итерацию по "деслонизации " стада, попадут первым запросом:
синее, зеленое, серое.
синее1 и т.д. условия >100 не пройдут - следовательно дочерних клонов - пустышек не будет.
вопрос как же апдейтить , например не 3450 синих слонов , только 100 (любых, но синих) из синего стада.
если через параметр , как писал выше , типа 1 стазо 1 запрос - все ок.
а как-то группой пока не увидел как :(
разве что через доп вложеный ждойн с роу ид, но по моему так себе дороже получится из-за накладных расходов.
в общем пока вижу перебор в курсоре , с подстановкой ид стада. :(
...
Рейтинг: 0 / 0
02.10.2014, 17:31:46
    #38765176
Jude
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
update limit
Jude,

ну в общем пока придумал только так:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
 select
...
(select s.слон_ид from слоны s where s.стадо_ид = tt.id order by s.слон_ид limit 100,1) mid
...

from 
...
(тут выборка которая дает стада оверквотинг с псесвонимом tt )
.. /*joinим чего-то*/
and слон_ид < mid 


будет работать, если слон ид = уникальное поле типа автоинкремент.
тогда первая сотня зальется без проблем.
...
Рейтинг: 0 / 0
02.10.2014, 17:38:30
    #38765190
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
update limit
Слоны безлики. Следовательно, достаточно хранить их общее количество, и делить на стада только тогда, когда это потребуется (а иных задач, чем определение количества стад и определение количества слонов в последнем, возможно, неполном, стаде, я придумать не могу).
...
Рейтинг: 0 / 0
02.10.2014, 17:47:05
    #38765204
alex564657498765453
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
update limit
мдя... не совсем врубился в логику..но

1)апдейт можно делать с лимитом 100 чтобы перевести только сто слонов
2)если слоны всегда в стада по цвету определяються, то я бы и изначально делал разные очереди для разного цвета

3)
у нас 20к слонов, и мы хотим по цветам чорный белый серый по создавать стада

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

но можно пойти как чтоб без цикла
раз уж ты выборку делаешь подзапросом, то переменными можно пронумеровать слонов в каждой групе, и тогда номер групы определять по целочисленому делению номера слона на 100
...
Рейтинг: 0 / 0
02.10.2014, 18:00:36
    #38765219
Jude
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
update limit
alex564657498765453мдя... не совсем врубился в логику..но

Это моя вина. перестарался со скрытием исходной задачи.

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

но чтобы была ясность по задаче - изначальное количество групп не известно.
т.е. есть некий теоретический максимум - но первая итерация - это создание "базового" стада по 1 на каждое значение параметра группировки - в моем примере = цвет.
просто я не сразу сообразил что без этого задача искажается, и забыл добавить.

ну а дальше уже разбиение на подгруппы - стада по 100 макс, сколько надо.

пока задачу по пересечению со "старыми" - решаю через спец параметр , который новосозданным ставлю 0.
т.е. по факту не решаю. типа всегда "первичное создание стад":)

спасибо, идея интересная.
...
Рейтинг: 0 / 0
02.10.2014, 18:29:46
    #38765270
Jude
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
update limit
alex564657498765453 + тригер на апдейт (тригер после вставки)


на данном этапе порция заливаемых "слонов" = около 250к
но их может быть больше.
время критично - т.к. на полную обработку отводится до 2х минут.
собственно описанный момент - на финише, когда осталось распихать сгенерированных "слонов" по стадам.
т.е. тригеры - не хорошо. по времени не уложиться могу - в моем случае не подходит(хотя сперва про это подумал).
так - таблицы будут в районе 10 млн+ на шард, поэтому пока в песочнице - можно, а в боевом решении - тут прикидываю грохать ли индексы перед заливкой а потом как зальется строить наново, или идти другим путем :) в общем пока в поиске.

мож порционность и поможет, но боюсь ее - как бы боком не вышла.
...
Рейтинг: 0 / 0
02.10.2014, 22:15:12
    #38765429
javajdbc
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
update limit
Jude,

пронумеруйте слонов, (или используйте ИД если он
получается почти без пропуска) и разделите на 100,
возмите пол или потолок

номер_статда = (row_number / 100).флор
...
Рейтинг: 0 / 0
02.10.2014, 23:58:50
    #38765481
alex564657498765453
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
update limit
Judealex564657498765453 + тригер на апдейт (тригер после вставки)


на данном этапе порция заливаемых "слонов" = около 250к
но их может быть больше.
время критично - т.к. на полную обработку отводится до 2х минут.
собственно описанный момент - на финише, когда осталось распихать сгенерированных "слонов" по стадам.
т.е. тригеры - не хорошо. по времени не уложиться могу - в моем случае не подходит(хотя сперва про это подумал).
так - таблицы будут в районе 10 млн+ на шард, поэтому пока в песочнице - можно, а в боевом решении - тут прикидываю грохать ли индексы перед заливкой а потом как зальется строить наново, или идти другим путем :) в общем пока в поиске.

мож порционность и поможет, но боюсь ее - как бы боком не вышла.

а тригеров не стоит бояться.

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

если в тригере стоит (а можешь и проверить)
New.somefield = rand()

то это не намного дольше если ты вставку будешь делать указав этому полю ранд()


но если за две минуты 250к вставить... чтото тут не так.
ну в целом да, сначала абы вставить, потом разбивать на групы.
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / update limit / 12 сообщений из 12, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]