Гость
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Firebird и функция StdDev / 25 сообщений из 27, страница 1 из 2
24.10.2018, 15:28
    #39722222
Irmantas Simaitis
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Firebird и функция StdDev
Привет всем. Возможно, у вас есть идеи, как из столбца с данными, вычислять значение функции STDDEV в новом столбце. Рассчитывается значение из последних 3 записей, включая текущую запись.

Функция StdDev
Модуль в Delphi: Math
Описание
Функция вычисляет стандартное среднеквадратичное отклонение (квадратный корень типовой дисперсии) значений массива чисел Data.

Пример в Excel добавил.
...
Рейтинг: 0 / 0
24.10.2018, 15:36
    #39722234
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Firebird и функция StdDev
24.10.2018 15:28, Irmantas Simaitis пишет:

> Привет всем. Возможно, у вас есть идеи, как из столбца с данными, вычислять значение функции STDDEV в новом столбце.

в FireBird 3.X есть Statistical Functions.
смотри описание в документации.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
24.10.2018, 18:58
    #39722433
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Firebird и функция StdDev
Irmantas Simaitis,

для FB 2.x - написать Stored Procedure

в таблицу можно подключить, например, через авто-вычисляемые столбцы (Computed By) если сможете сформулировать там, что такое "три последние записи" для любой случайн овзятой строки.

Только столбец этот не надо будет читать где угодно, а только там, гед роеально надо, иначе тормоза

Вариант - создать реальный столбец и заполнять его на триггерах After insert or update or delete
Но потребуется подумать, как правильно напистаь все триггеры, чтобы все зависимые строки во всех вариантах изменений исправлять
...
Рейтинг: 0 / 0
24.10.2018, 19:01
    #39722434
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Firebird и функция StdDev
AriochВариант - создать реальный столбец и заполнять его на триггерах After insert or update or delete
Но потребуется подумать, как правильно напистаь все триггеры, чтобы все зависимые строки во всех вариантах изменений исправлять

в многопользовательской среде не работоспособно
...
Рейтинг: 0 / 0
25.10.2018, 13:33
    #39722797
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Firebird и функция StdDev
Симонов Денис,

почему? разве триггеры вне транзакций работают?

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

.....а если бы у таблиц был ещё триггер before reading/selecting можно бы было и кэширующую схему создать
Впрочем, её и так можно, через триггерных вьюхи
...
Рейтинг: 0 / 0
25.10.2018, 13:53
    #39722814
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Firebird и функция StdDev
Arioch,

нет причина даже не в этом. 3 последних - это понятие сильно зависит от сортировки. В случае триггеров проблема в порядке вставки/обновления/удаления записей. Триггеры результат работы которых зависит от последовательности вставки/обновления/удаления в топку, даже в однопользовательском режиме.
...
Рейтинг: 0 / 0
25.10.2018, 14:44
    #39722866
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Firebird и функция StdDev
насчёт вьюхи я погорячился, кэширование можно организовать даже в рамках одной таблицы.

из триггеров заNULLяем столбец-кэш, а читаем из ещё одного COMPUTED BY столбца c ленивым восстановлением данных через SP

Код: sql
1.
Select Coalesce( 7, ( select * from Div_By_Zero ( 0 ) ) ) from rdb$database



Симонов ДенисВ случае триггеров проблема в порядке вставки/обновления/удаления записей

кто последний встал - того и тапки.

какая последняя транзакция коммитится, данные той и попадают в последний запуск триггера, а предыдущие значения в тригеррах рассчитываются, конечно, но потом перезатираются
...
Рейтинг: 0 / 0
25.10.2018, 14:47
    #39722869
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Firebird и функция StdDev
Ariochпотребуется подумать, как правильно написaть все триггеры, чтобы все зависимые строки во всех вариантах изменений исправлять

что это может потребовать serious thinking я сразу написал
...
Рейтинг: 0 / 0
25.10.2018, 14:51
    #39722873
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Firebird и функция StdDev
Arioch,

дело не только в транзакции, но и в запросах вида

INSERT...
SELECT...

которые позволяют вставлять записи пачками.
...
Рейтинг: 0 / 0
25.10.2018, 14:52
    #39722875
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Firebird и функция StdDev
Ariochиз триггеров заNULLяем столбец-кэш, а читаем из ещё одного COMPUTED BY столбца c ленивым восстановлением данных через SP

Код: sql
1.
Select Coalesce( 7, ( select * from Div_By_Zero ( 0 ) ) ) from rdb$database



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

Код: sql
1.
2.
3.
4.
Select iif( 1=1,
  ( select * from Div_By_Zero ( 0 ) ),
  ( select * from Div_By_Zero ( 3 ) )
) from rdb$database
...
Рейтинг: 0 / 0
25.10.2018, 14:53
    #39722876
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Firebird и функция StdDev
Симонов Дениспозволяют вставлять записи пачками.

в FB триггеры работают per row, а не per statement - так какая разница для триггеров у меня один insert/update/merge на 10 записей, или 10 по одной записи
...
Рейтинг: 0 / 0
25.10.2018, 14:57
    #39722881
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Firebird и функция StdDev
Arioch,

вот именно поэтому разница есть. Если SELECT не упорядочен будет случайная каша. И это только при одном пользователе.
...
Рейтинг: 0 / 0
25.10.2018, 14:58
    #39722883
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Firebird и функция StdDev
Симонов ДенисЕсли SELECT не упорядочен будет случайная каша

Будет, во время исполнения INSERT'a.

А после его исполнения
Ariochкто последний встал - того и тапки.
...
Рейтинг: 0 / 0
25.10.2018, 15:01
    #39722885
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Firebird и функция StdDev
Arioch,

ага, да с какого перепуга то. Собираешься пересчитывать на вставках значения в записях вставленных ранее?
...
Рейтинг: 0 / 0
25.10.2018, 15:13
    #39722888
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Firebird и функция StdDev
Симонов Денис,

Ну не на всех же, у нас скользящее окно.

Irmantas Simaitisиз последних 3 записей, включая текущую запись.

Агрегат считается только по первичке "соседей", поэтому изменения самого аггрегата никуда в другие строки не распространяются, только изменения первички. Поэтому наведённых изменений 2-го и т.д. уровня рекурсивности просто нет!

Всё примитивно, хотя и не вполне эффективно.

Допустим у нас есть строки.

A
B
C
D

E
F
G
H
...

от строки D зависят строки с B по F {т.е. с Current ID +- (3-1) }

Что мы можем сделать со строкой D ?

1) изменить значение (payload) - нужно инвалидировать или перерасчитать строки B - F
2) удалить вообще - то же самое
3) изменить ID ? отдельно не считается - это аналогично удалению+вставке

Теперь имеем

A
B
C
E
F

G
H
...

и вставляем строку D, что надо делать? снова - пересчитать агрегат по строкам B-F

Никаких других операций над таблицей не просматривается. Откуда возьмётся неконсистентность?
...
Рейтинг: 0 / 0
25.10.2018, 15:22
    #39722891
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Firebird и функция StdDev
Arioch,

ну я даже не знаю как тебе объяснить. Ещё раз ты внутри INSERT триггера собрался UPDATE соседних строк делать? А ничего что на UPDATE у тебя тоже триггеры есть. Даже если ты выпендришься и реализуешь такую хитрую схему пересчёта, то

1. Она будет работать не эффективно (ты уже сам заметил)
2. Будет провоцировать UPDATE конфликты, когда их не ждёшь. Что самое забавное даже на вставке записей
3. В случае ошибок этот чудесный клубок триггеров фиг распутаешь, чтобы понять в чём дело

Так зачем советовать проктостоматологические методы?
...
Рейтинг: 0 / 0
25.10.2018, 15:32
    #39722898
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Firebird и функция StdDev
Симонов Денисну я даже не знаю как тебе объяснить.

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

Симонов ДенисА ничего что на UPDATE у тебя тоже триггеры есть

абсолютно ничего

AriochАгрегат считается только по первичке "соседей", поэтому изменения самого аггрегата никуда в другие строки не распространяются, только изменения первички. Поэтому наведённых изменений 2-го и т.д. уровня рекурсивности просто нет!

Симонов ДенисОна будет работать не эффективно

Как и всегда, зависит от соотношения чтений и записей. Если 1:1000 - то да, надо считать в SELECT'e и ничего нигде не хранить. А если 1000:1 - то наоборот.

К вопросу что конкретно будет проктостоматологией - это тоже относится.

Симонов ДенисБудет провоцировать UPDATE конфликты

Почему ?

В принципе кэширование можно и в отдельную таблицу вынести.
Особенно, если базовая таблица уже широкая.

Симонов ДенисВ случае ошибок этот чудесный клубок триггеров

Так нет никакого клубка, есть только три триггера, ну или один универсальный.
Самое сложное изменений - и то, ЕСЛИ такое разрешается, изменение ID у уже существующей записи.
...
Рейтинг: 0 / 0
25.10.2018, 15:54
    #39722920
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Firebird и функция StdDev
AriochПочему ?

Можешь на листочке расписать, когда 2 INSERT захотят сделать UPDATE одной и той же записи. Может тогда поймёшь.

>> Никаких других операций над таблицей не просматривается. Откуда возьмётся неконсистентность?

Неконситентность может и не возьмётся, а вот сильная разница в затронутых апдейтами записях в зависимости от порядка вставки ещё как. Т.е. реально не возможно предсказать сколько очередная вставка должна пересчитать записей. Хотя в консистентности сего решения я тоже не уверен.
...
Рейтинг: 0 / 0
25.10.2018, 16:58
    #39722951
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Firebird и функция StdDev
Симонов Денискогда 2 INSERT захотят сделать UPDATE одной и той же записи.

обычный конфликт изменений в двух транзакциях


Симонов ДенисТ.е. реально не возможно предсказать сколько очередная вставка должна пересчитать записей

от нуля до пяти (2*3-1), при этом на больших таблицах почти всегда будет 5

да, на 100% предсказать невозможно, ну и что?
...
Рейтинг: 0 / 0
25.10.2018, 17:08
    #39722956
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Firebird и функция StdDev
Arioch,

мне надоело с тобой спорить. Хочешь плодить у себя гавнокод пожалуйста, только не надо советовать другим.
...
Рейтинг: 0 / 0
25.10.2018, 17:11
    #39722958
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Firebird и функция StdDev
Код: sql
1.
2.
insert into SIMONOV_UPDATE_CONFLICT (ID, PAYLOAD)
SELECT ID, 100 FROM SIMONOV_INSERT



ГДЕ обещанный конфлик на вставке, где ???

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
35 записей было обновлено в таблице SIMONOV_UPDATE_CONFLICT

19 записей было добавлено в таблицу SIMONOV_UPDATE_CONFLICT

------ Информация о производительности ------
Время подготовки запроса = 0ms
Время выполнения запроса = 16ms
Current memory = 9 479 692
Max memory = 9 794 612
Memory buffers = 2 048
Reads from disk to cache = 0
Writes from cache to disk = 0
Чтений из кэша = 535

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
create or alter procedure SIMONOV_INSERT
returns (
    ID integer)
as
begin
  id = 1;
  while ( ID < 20 ) do
  begin
    suspend;
    id = id + 1;
  end
end



Код: 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.
CREATE TABLE SIMONOV_UPDATE_CONFLICT (
    ID         INTEGER NOT NULL,
    PAYLOAD    INTEGER NOT NULL,
    AGGREGATE  INTEGER
);

ALTER TABLE SIMONOV_UPDATE_CONFLICT ADD CONSTRAINT PK_SIMONOV_UPDATE_CONFLICT PRIMARY KEY (ID);

SET TERM ^ ;

CREATE OR ALTER TRIGGER SIMONOV_UPDATE_CONFLICT_AI0 FOR SIMONOV_UPDATE_CONFLICT
ACTIVE AFTER INSERT POSITION 0
AS
begin
  update SIMONOV_UPDATE_CONFLICT
  set AGGREGATE = AGGREGATE + 1
  where (ID between NEW.ID-2 and NEW.ID+2) and (ID <> NEW.ID);
end
^

CREATE OR ALTER TRIGGER SIMONOV_UPDATE_CONFLICT_BI0 FOR SIMONOV_UPDATE_CONFLICT
ACTIVE BEFORE INSERT POSITION 0
AS
begin
  NEW.AGGREGATE = NEW.AGGREGATE + 1;
end
^


...
Рейтинг: 0 / 0
25.10.2018, 17:13
    #39722961
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Firebird и функция StdDev
Симонов Денис,

ну то есть ты ляпнул абы что, ни одного примера хотя бы отдаленно проблемного за несколько часов придумать не смог, но указывать кому и что можно говорить будешь первым. Потому что ты художник, ты так видишь.
...
Рейтинг: 0 / 0
25.10.2018, 17:21
    #39722973
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Firebird и функция StdDev
Arioch,

ты в двух потоках запусти да ещё так чтобы id чередовались.

UPDATE внутри одной транзакции одной и той же записи можно делать сколько угодно без всяких конфликтов.

Ну и твой пример хрень полная. Где ID в случайном порядке? Где расчёт агрегата в зависимости от значения в текущей записи, а не просто +1. Какие-то id-2 id+2. Откуда уверенность что в id вообще нет пропусков?
...
Рейтинг: 0 / 0
25.10.2018, 17:35
    #39722978
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Firebird и функция StdDev
Может быть ты сам наконец что-нибудь сделаешь?

А если будут пропуски, то что изменится?

> Где ID в случайном порядке? Где расчёт агрегата в зависимости от значения в текущей записи

Код: 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.
48.
create or alter procedure SIMONOV_INSERT
returns (
    ID integer,
    V integer)
as
begin
  id = 1; V = 1;
  while ( V < 20 ) do
  begin
    suspend;
    V = V + 1;
    id = mod(V * 1111, 777);
  end
  suspend;
end^

SET TERM ; ^

CREATE TABLE SIMONOV_UPDATE_CONFLICT (
    ID         INTEGER NOT NULL,
    PAYLOAD    INTEGER NOT NULL,
    AGGREGATE  INTEGER DEFAULT 0 NOT NULL
);

ALTER TABLE SIMONOV_UPDATE_CONFLICT ADD CONSTRAINT PK_SIMONOV_UPDATE_CONFLICT PRIMARY KEY (ID);

SET TERM ^ ;

CREATE OR ALTER TRIGGER SIMONOV_UPDATE_CONFLICT_AI0 FOR SIMONOV_UPDATE_CONFLICT
ACTIVE AFTER INSERT POSITION 0
AS
begin
  update SIMONOV_UPDATE_CONFLICT
  set AGGREGATE = AGGREGATE + New.payload
  where (ID between NEW.ID-100 and NEW.ID+100) and (ID <> NEW.ID);
end
^

CREATE OR ALTER TRIGGER SIMONOV_UPDATE_CONFLICT_BI0 FOR SIMONOV_UPDATE_CONFLICT
ACTIVE BEFORE INSERT POSITION 0
AS
begin
  NEW.AGGREGATE = NEW.AGGREGATE + New.Payload;
end
^

insert into SIMONOV_UPDATE_CONFLICT (ID, PAYLOAD)
SELECT ID, V FROM SIMONOV_INSERT



Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
22 записей было обновлено в таблице SIMONOV_UPDATE_CONFLICT

20 записей было добавлено в таблицу SIMONOV_UPDATE_CONFLICT

------ Информация о производительности ------
Время подготовки запроса = 0ms
Время выполнения запроса = 0ms
Current memory = 9 126 340
Max memory = 9 383 324
Memory buffers = 2 048
Reads from disk to cache = 0
Writes from cache to disk = 0
Чтений из кэша = 406


P.S. массовые изменения данных из разных соединений в длинных транзакциях, которые чреваты конфликтом данным - это говнокод. Не надо такого другим советовать.
...
Рейтинг: 0 / 0
25.10.2018, 17:45
    #39722985
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Firebird и функция StdDev
а также и на одном триггере

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
CREATE OR ALTER TRIGGER SIMONOV_UPDATE_CONFLICT_AI0 FOR SIMONOV_UPDATE_CONFLICT
ACTIVE AFTER INSERT OR UPDATE POSITION 0
AS
begin
  if (new.payload is distinct from old.payload) then
  begin
    update SIMONOV_UPDATE_CONFLICT
    set AGGREGATE = AGGREGATE + New.payload
    where (ID between NEW.ID-100 and NEW.ID+100) -- and (ID <> NEW.ID)
    ;
  end
end
^


/* Trigger: SIMONOV_UPDATE_CONFLICT_BI0 */
CREATE OR ALTER TRIGGER SIMONOV_UPDATE_CONFLICT_BI0 FOR SIMONOV_UPDATE_CONFLICT
ACTIVE BEFORE INSERT POSITION 0
AS
begin
  -- NEW.AGGREGATE = NEW.AGGREGATE + New.Payload;
end



Код: plaintext
1.
2.
42 записей было обновлено в таблице SIMONOV_UPDATE_CONFLICT

20 записей было добавлено в таблицу SIMONOV_UPDATE_CONFLICT

Код: sql
1.
2.
3.
update SIMONOV_UPDATE_CONFLICT
set PAYLOAD = - payload
where mod(id / 10, 6) <= 2



Код: plaintext
43 записей было обновлено в таблице SIMONOV_UPDATE_CONFLICT
...
Рейтинг: 0 / 0
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Firebird и функция StdDev / 25 сообщений из 27, страница 1 из 2
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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