powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / обновление предыдущего значения
5 сообщений из 5, страница 1 из 1
обновление предыдущего значения
    #35542735
imoen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!
[заранее простите за возможную лажовость вопроса, но оч нужно, и поискав по форуму решения не увидел, (хотя может смотрел криво %))]

Внимание вопрос:
Допустим, есть таблица вида
ID, KPI, Period, Value, ValidAfter, ValidBefore

например:
1, Выручка, Август2008, 100, 10SEP2008, 31DEC2999

нужно добавить обновленные данные по Выручке
чтобы получилось так:
1, Выручка, Август2008, 100, 10SEP2008, 15SEP2008
2, Выручка, Август2008, 101, 15SEP2008, 31DEC2999

как правильно обновить предыдущую запись при добавлении новой записи, и как будет меньше тормозов при бОльших объемах таблицы и добавляемых данных
...
Рейтинг: 0 / 0
обновление предыдущего значения
    #35542786
imoen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ну да, и добавлю что сейчас сделано так:
1) обновляется предыдущее ValidBefore:
update baseDS as B
set ValidBefore =
(select ValidAfter from newDS as N
where B.KPI=N.KPI and B.Period=N.Period)
where B.ValidBefore = "31DEC2999"
and exists
(select * from newDS as N
where B.KPI=N.KPI and B.Period=N.Period);
2) содержимое newDS добавляется к baseDS
...
Рейтинг: 0 / 0
обновление предыдущего значения
    #35542824
_VVP_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
imoenДопустим, есть таблица вида
ID, KPI, Period, Value, ValidAfter, ValidBefore

например:
1, Выручка, Август2008, 100, 10SEP2008, 31DEC2999

нужно добавить обновленные данные по Выручке
чтобы получилось так:
1, Выручка, Август2008, 100, 10SEP2008, 15SEP2008
2, Выручка, Август2008, 101, 15SEP2008, 31DEC2999

как правильно обновить предыдущую запись при добавлении новой записи, и как будет меньше тормозов при бОльших объемах таблицы и добавляемых данных
imoenну да, и добавлю что сейчас сделано так:1) обновляется предыдущее ValidBefore:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
update baseDS as B
set ValidBefore =
(select ValidAfter from newDS as N
where B.KPI=N.KPI and B.Period=N.Period)
where B.ValidBefore = "31DEC2999"
and exists
(select * from newDS as N
where B.KPI=N.KPI and B.Period=N.Period);
2) содержимое newDS добавляется к baseDS
Есть пару комментариев:
1. При организации хранения периодических величин необходимо, чтобы точка (дата+время) начала нового значения была больше точки окончания старого значения. В приведенном примере это нарушается.
Пример проблемы : выполним запрос для поиска значения на точку (дата+время)
Код: plaintext
select * from BASEDS as PV where &DT between PV.VALIDBEFORE AND PV.VALIDAFTER
Если зададим дату &DT=15SEP2008, то на выходе получим 2 значения (ID=1 и ID=2).
2. Непонятно зачем организована таблица newDS? В ней нет никакой потребности - используйте параметризованные SQL DML операторы.
В рамках одной транзакции вначале делаете обновление baseDS, а потом делаете туда вставку:
Код: plaintext
1.
update BASEDS as B set VALIDBEFORE = &DT1- 1 / 86400  where B.KPI=&KPI and B.VALIDBEFORE=&MAX_DATE;
insert into BASEDS values([NEWID],&KPI,&PERIOD,&VALUE,&DT1,&MAX_DATE);
...
Рейтинг: 0 / 0
обновление предыдущего значения
    #35542926
_VVP_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
imoen
Допустим, есть таблица вида
ID, KPI, Period, Value, ValidAfter, ValidBefore

например:
1, Выручка, Август2008, 100, 10SEP2008, 31DEC2999

нужно добавить обновленные данные по Выручке
чтобы получилось так:
1, Выручка, Август2008, 100, 10SEP2008, 15SEP2008
2, Выручка, Август2008, 101, 15SEP2008, 31DEC2999

как правильно обновить предыдущую запись при добавлении новой записи, и как будет меньше тормозов при бОльших объемах таблицы и добавляемых данных
Кстати, есть еще одно архитектурное решение, в котором исключим VALIDBEFORE:
T (ID, AXIS, ..., VALUE, DT)
Тогда датой окончания действия значения будет дата начала действия следующего значения:
1, Выручка, Август2008, 100, 10SEP2008
2, Выручка, Август2008, 101, 15SEP2008
Выборка:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
-- значение на дату с использованием сортировки
select [TOP  1 ] * from T
where T.AXIS=&AXIS and &DT>=T.DT
order by T.DT asc
-- значение на дату с вложенным запросом
select T2.ID, T2.AXIS, T2.VALUE, T2.DT, T1.DT_LAST from (
  select min(T.DT) as DT_LAST from T
  where T.AXIS=&AXIS and &DT>=T.DT
) as T1, T as T2
where T.AXIS=&AXIS and &DT>=T2.DT and &DT<IFNULL(T1.DT_LAST,&MAX_DATE)
...
Рейтинг: 0 / 0
обновление предыдущего значения
    #35543856
imoen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
&VALUE _VVP_
1. При организации хранения периодических величин необходимо, чтобы точка (дата+время) начала нового значения была больше точки окончания старого значения. В приведенном примере это нарушается.
Пример проблемы : выполним запрос для поиска значения на точку (дата+время)
Код: plaintext
select * from BASEDS as PV where &DT between PV.VALIDBEFORE AND PV.VALIDAFTER
Если зададим дату &DT=15SEP2008, то на выходе получим 2 значения (ID=1 и ID=2).
2. Непонятно зачем организована таблица newDS? В ней нет никакой потребности - используйте параметризованные SQL DML операторы.
В рамках одной транзакции вначале делаете обновление baseDS, а потом делаете туда вставку:
Код: plaintext
1.
update BASEDS as B set VALIDBEFORE = &DT1- 1 / 86400  where B.KPI=&KPI and B.VALIDBEFORE=&MAX_DATE;
insert into BASEDS values([NEWID],&KPI,&PERIOD,,&DT1,&MAX_DATE);


1. По поводу точки начала нового значения, данные добавляются последовательно, то есть, новая запись будет по любому иметь более поздний ValidAfter, ну если конечно на сервере время назад не откатят )
Для отбора какого-то предыдущего значения можно же брать [ValidAfter, ValidBefore), но на самом деле в этом фактически надобности нет, нужно будет отбирать лишь актуальное, то есть у которого ValidBefore = "31DEC2999"
2. По поводу newDS.
Вообще это
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
update baseDS as B
set ValidBefore =
(select ValidAfter from newDS as N
where B.KPI=N.KPI and B.Period=N.Period)
where B.ValidBefore = "31DEC2999"
and exists
(select * from newDS as N
where B.KPI=N.KPI and B.Period=N.Period);
фрагмент скуэль запроса из макроса на SAS base/SAS macro по добавлению новых значений в промежуточное хранилище. newDS - это таблица выгрузки из внешнего источника, а baseDS - таблица промежуточного хранилища. Таблицы две, так дложно быть.
Обновление ValidBefore реализовано sql запросом, а добавление новых записей делается SAS-ом

Второй вариант с исключением ValidBefore был изначально, но сортировка больших таблиц по 2 гига и более при получения актульного значения для публикации занимала тоже очень немало времени. Отбирать данные с ValidBefore ="31DEC2999" существенно быстрее. А если учесть что публикация данных из промежуточного хранилища должна быть ежедневной, а добавление больших объемов происходит гораздо реже, то потому было решено иметь два поля ValidAfter и ValidBefore

Вопрос возник потому, что при объемах newDS порядка 50000 записей и поболее, и baseDS в пару миллионов записей, обновление поля ValidBefore длится, ну эээээ, ну очень долго. Когда добавляются до 1000 записей, еще терпимо, и на время всей выгрузки не сильно влияет. Но бывает необходимость добавить большой объем данных. Есть ли какой метод который позволит сделать обновление ValidBefore не таким долгим. Или что другое можете посоветовать?
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / обновление предыдущего значения
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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