Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Как обойтись малой кровью? / 21 сообщений из 21, страница 1 из 1
19.01.2012, 11:47
    #37621686
Hunterex
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как обойтись малой кровью?
Помогите, пожалуйста решить задачу
малыми ресурсами и временем
задача:

1) Есть таблица следующей структуры

code varchar(255)
group int

например:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
code1     1
code2     1
code3     1

code4     2
code5     2


code6     3
code7     3
code8     3



2) есть входные данные

code4, code5 и новый code9,

Надо:

добавить code9 в гр., которая заранее не известна.
Ее нужно определить по code4 и code5
иными словами
как мне отсеять code4 и code5 и добавить code9 в группу в которой уже находятся code4 и code5?


Задача реальная, не учебная.
Спасибо всем, кто поможет.
...
Рейтинг: 0 / 0
19.01.2012, 12:06
    #37621744
АнатоЛой
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как обойтись малой кровью?
Hunterex,
1) В чём кокретно проблема?
2) Если задача реальная - какая СУБД?
3) Какие ограничения: SQL, StoProc, одним выражением, на входе три параметра или таблица (строк всегла 3)?
...
Рейтинг: 0 / 0
19.01.2012, 12:48
    #37621894
Hunterex
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как обойтись малой кровью?
Проблема в том, что приложение критично к времени выполнения.
Надо как можно изящнее обновлять группы.
СУБД - MSSQL, количество строк 5-10 миллионов, в группе количество членов неограниченно, но всегда >1
не хочется делать много выборок для определения того что кода нет в базе и выяснения группы куда его определить
Ограничений особых нет. В основном время. Обновление группы будет проходить в отдельном треде, но тредов может быть много, поэтому от скорости будет так же зависеть и объем сжираемой памяти.
...
Рейтинг: 0 / 0
19.01.2012, 13:01
    #37621946
JoFan
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как обойтись малой кровью?
Hunterex,

а если на входе будет: code4 code4 code9
куда надо добавить code9 ?
...
Рейтинг: 0 / 0
19.01.2012, 13:04
    #37621953
Hunterex
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как обойтись малой кровью?
Добавляется только code9 в группу где находится code4
...
Рейтинг: 0 / 0
19.01.2012, 13:19
    #37622004
JoFan
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как обойтись малой кровью?
Hunterex,

извиняюсь - скопипастил криво )

надо так:
а если на входе будет: code4 code6 code9
куда надо добавить code9 ?
т.е. в две группы добавить?
...
Рейтинг: 0 / 0
19.01.2012, 13:24
    #37622024
Hunterex
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как обойтись малой кровью?
Нет. Так не будет. Будут приходить только коды, которые принадлежат одной группе. Просто со временем могут появляться в этой группе новые коды, которых нет в базе.
...
Рейтинг: 0 / 0
19.01.2012, 13:38
    #37622071
JoFan
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как обойтись малой кровью?
HunterexНет. Так не будет. Будут приходить только коды, которые принадлежат одной группе.

тогда зачем 2 кода, почему одним не обойтись ?
т.е. например "code5 и новый code9"

HunterexПросто со временем могут появляться в этой группе новые коды, которых нет в базе.

в какой "этой" ?

поле "code" уникально?
...
Рейтинг: 0 / 0
19.01.2012, 14:00
    #37622150
Злой Бобр
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как обойтись малой кровью?
Hunterex,

Фиг поймешь че вам нада. Научитесь сначала внятно описывать условия. )))
...
Рейтинг: 0 / 0
19.01.2012, 15:47
    #37622482
АнатоЛой
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как обойтись малой кровью?
1. Вы не ответили, в каком виде приходят входные данные, таки "пакетами" в виде табличек, где в каждом пакете члены только одной группы? При этом номер группы в пакете неизвестен и этот номер становится известен только в БД?
2. Вопрос практический, поэтому лучше сразу топик переносите в МS SQL...
...
Рейтинг: 0 / 0
19.01.2012, 18:04
    #37622882
SERG1257
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как обойтись малой кровью?
Злой Бобр Фиг поймешь че вам нада. Научитесь сначала внятно описывать условия+1
Hunterex добавить code9добавить запись?
Hunterex в гр., которая заранее не известна.определить группу по входным параметрам?
Hunterex как мне отсеять code4 и code5 и добавить code9 в группу в которой уже находятся code4 и code5?Кроме вас на этот вопрос никто не ответит.
Hunterex Надо как можно изящнее обновлять группы.Стоп-стоп-стоп, выше вы хотели добавлять запись?
Hunterex количество строк 5-10 миллионовВ какой таблице?
...
Рейтинг: 0 / 0
19.01.2012, 19:06
    #37622996
Hunterex
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как обойтись малой кровью?
Еще раз.

Например, сегодня на мой запрос веб-сервис отдает мне массив из 3-кодов. Это коды деталей. Они взаимозаменяемы. Только производители разные.

Я проверяю по базе. Их там нет.

Записываю эту группу кодов в таблицу, присваиваю им какой-то там №. И продолжаю себе работать.

Но у моего поставщика через несколько дней вдруг появились на складе детали от нового производителя,
которые тоже могут заменить те детали из группы, которую я создал (см. выше).
Теперь мне надо пополнить Этими новыми кодами ту группу деталей, которая уже есть в базе. Т.е., используя, терминалогию описанную выше к кодам code4 и code5 добавить новый code9. Т.е. пополнить группу 2. Вот и вся задача. Что тут не понятного?
...
Рейтинг: 0 / 0
19.01.2012, 19:56
    #37623082
АнатоЛой
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как обойтись малой кровью?
Hunterex, ещё раз:
1. А может тебе завтра веб-сервис вернуть массив из 4-кодов?
2. Тебе только добавлять новые? А если группа была code2,code3,code4 а тебе серви вернул code2,code4,code5, что делать с code3?

телепат switched ON:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
PSEUDO-PL-SQL:

-- таблица с ранее сохранёнными группами

CREATE TABLE codes(
  code char NOT NULL, 
  inner_group integer NOT NULL
);

-- входная таблица с взаимозаменяемыми деталями
CREATE TEMP TABLE input_codes(
  id_input_code autoincrement, 
  code char NOT NULL,
  inner_group integer NULL
);

...
  -- находим номер группы
    SELECT min(inner_group)
             , max(inner_group)
           INTO v_mn
                 , v_mx
       FROM codes
           INNER JOIN input_codes 
               ON codes.code = input_codes.code;

  -- защита от дурака
   IF v_mn <> v_mx THEN
     RAISE EXCEPTION 'Входные данные не хотят подчиняться логике Hunterexa';
   END IF;

  -- раз уж MS SQL и версия неизвестна :)

  MERGE codes 
    USING  input_codes
       ON (input_codes.code = codes.code) AND (v_mn = codes.inner_group)
    WHEN NOT MATCHED BY TARGET 
      THEN INSERT (code, inner_group)
	    VALUES (source.code, v_mn);
...
Рейтинг: 0 / 0
19.01.2012, 20:01
    #37623096
SERG1257
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как обойтись малой кровью?
Код: sql
1.
2.
create table mytable (code varchar(255) primary key, grp_id int references groups, other_data varchar(255))
CREATE NONCLUSTERED INDEX idx_grp_id ON mytable(grp_id)



То бишь у вас две принципиально разные вставки - добавить группу и пополнить группу
для второго случая - вставить code9 c группой как у code4 (code5 здесь лишний и что делать если он по ошибке имеет не ту же самую группу как code4)

Код: sql
1.
2.
insert into mytable (code,grp_id)
select @code9,(select grp_id from mytable a where code=@code4)



Чем вас не устраивает подход "в лоб"?
...
Рейтинг: 0 / 0
19.01.2012, 20:11
    #37623122
АнатоЛой
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как обойтись малой кровью?
SERG1257, insert требует прдварительной проверки на отстуствие. Либюо перехвата exeption :)
...
Рейтинг: 0 / 0
20.01.2012, 13:35
    #37623945
Hunterex
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как обойтись малой кровью?
Немного не так.

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

Из группы коды никогда не удаляются! Только пополнение.
...
Рейтинг: 0 / 0
20.01.2012, 13:44
    #37623966
АнатоЛой
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как обойтись малой кровью?
телепат switched ON 2:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
PSEUDO-PL-SQL:

-- таблица с ранее сохранёнными группами

CREATE TABLE codes(
  code char NOT NULL, 
  inner_group integer NOT NULL
);

-- входная таблица с взаимозаменяемыми деталями
CREATE TEMP TABLE input_codes(
  id_input_code autoincrement, 
  code char NOT NULL,
  inner_group integer NULL
);

...
  -- вдруг группа новая и select не найдёт ни одной строки
  SET v_mn = NULL;
  SET v_mx = NULL;

  -- пытаемся найти номер группы
    SELECT min(inner_group)
             , max(inner_group)
           INTO v_mn
                 , v_mx
       FROM codes
           INNER JOIN input_codes 
               ON codes.code = input_codes.code;

  -- защита от дурака
 
   IF ISNULL(v_mn, -1) <> ISNULL(v_mx, -1) THEN

     RAISE EXCEPTION 'Входные данные не хотят подчиняться логике Hunterexa';
   END IF;

 -- если таки группа новая - инициализируем новый ид для группы
  SET v_mn = ISNULL(v_mn, seq_innner_group.nextval());

  -- раз уж MS SQL и версия неизвестна :)
  MERGE codes 
    USING  input_codes
       ON (input_codes.code = codes.code) AND (v_mn = codes.inner_group)
    WHEN NOT MATCHED BY TARGET 
      THEN INSERT (code, inner_group)
	    VALUES (source.code, v_mn);



П.С.: Hunterex, Вы лентяй!
...
Рейтинг: 0 / 0
20.01.2012, 13:52
    #37623996
Злой Бобр
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как обойтись малой кровью?
Hunterex,

Приведи пример в каком виде у тебя массив приходит. XML или что там у тебя?
...
Рейтинг: 0 / 0
21.01.2012, 00:28
    #37624947
Hunterex
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как обойтись малой кровью?
Данные приходят в виде массива

array[1].code
array[1].manufacturer

array[2].code
array[2].manufacturer

и т.д.

Я понимаю задача сложна для понимания но мне приходится ее решать.

Заметтье, группа не присутствует! Подразумевается, что детали принадлежат одной группе (ну по другому сказать это как синонимы в языке. Слова разные, а смысл один) , но новой или уже имеющейся надо определять каждый раз.

В этом массиве могут быть как коды уже ранее встречавшиеся и занесенные в базу, так и наряду с ними новые, которыми надо пополнить имеющуюся группу.
автор
Код: sql
1.
2.
 MERGE codes 
    USING ...



можно было бы использовать если бы обе таблицы имели бы № группы, а он у меня есть только в одной.
...
Рейтинг: 0 / 0
21.01.2012, 00:58
    #37624971
SERG1257
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как обойтись малой кровью?
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
create table mytable (code varchar(255) primary key, grp_id int references groups, other_data varchar(255))
CREATE NONCLUSTERED INDEX idx_grp_id ON mytable(grp_id)

create table #temp_codes_to_insert (code varchar(255) primary key)
--Заполняете вашу таблицу с порцией кодов
insert into #temp_codes_to_insert values (code4)
insert into #temp_codes_to_insert values (code5)
insert into #temp_codes_to_insert values (code9)

-- собственно вставка
declare @max_grp_id int
declare @min_grp_id int
declare @cnt int
declare @grp_id int

select
  @max_grp_id=max(grp_id),
  @min_grp_id min(grp_id),
  @cnt=count(*)
from mytable m join #temp_codes_to_insert i on i.code=m.code

if @cnt=0 
begin
 -- вставляете новую группу получаете ее grp_id
 set @grp_id=ident_current('groups')
end
else -- группа уже есть
begin
  if @max_grp_id<>@min_grp_id  -- не все коды принадлежат одной группе
    RAISERROR('не все коды принадлежат одной группе', 16, 1)
  else set @grp_id=@min_grp_id -- или @grp_id=@max_grp_id непринципиально
end

-- собственно вставка
insert into mytable (code,grp_id)
select code,@grp_id
from #temp_codes_to_insert i
where not exists (select * from mytable m where m.code=i.code)
...
Рейтинг: 0 / 0
21.01.2012, 01:19
    #37624979
АнатоЛой
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как обойтись малой кровью?
это всё я уже писал - ТС не читатель...

вот это
SERG1257
Код: sql
1.
2.
3.
4.
5.
  -- собственно вставка
  insert into mytable (code,grp_id)  
  select code,@grp_id
  from #temp_codes_to_insert i
  where not exists (select * from mytable m where m.code=i.code)


можно поменять на

Код: sql
1.
2.
3.
4.
5.
6.
  MERGE mytable o 
    USING  #temp_codes_to_insert AS i
       ON (i.code = o.code) -- можно даже без AND (o.inner_group = @grp_id )
    WHEN NOT MATCHED BY TARGET 
      THEN INSERT (code, inner_group)
	    VALUES (i.code, @grp_id);
...
Рейтинг: 0 / 0
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Как обойтись малой кровью? / 21 сообщений из 21, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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