Гость
Форумы / SQLite [игнор отключен] [закрыт для гостей] / Триггер для обновления числа записей / 7 сообщений из 7, страница 1 из 1
10.09.2016, 16:35
    #39307071
amsdev
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Триггер для обновления числа записей
Приветствую !

Помогите новичку ) Есть таблица Groups которая содержит список под-таблиц с контактами:

Код: sql
1.
2.
3.
4.
5.
6.
CREATE TABLE Groups (
    ID  INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
    ListName  VARCHAR (100),
    ContactsCount INTEGER  DEFAULT (0),
    ContactsTableName VARCHAR (20)
);



2. Contacts - таблица контактов:

Код: sql
1.
2.
3.
4.
CREATE TABLE List1 (
    ID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
    ContactName VARCHAR (100) NOT NULL
);



Добавляем списки контактов в таблицу Groups:

Код: sql
1.
2.
INSERT INTO Groups (Name, ContactsTableName) VALUES ('Список контактов 1', 'List1');
INSERT INTO Groups (Name, ContactsTableName) VALUES ('Список контактов 2', 'List2');



Проблема вот в чем: в под-таблицах List1, List2 и т.д. может быть по несколько миллионов записей (контактов). При этом контакты могут массово добавляться или удаляться таким образом:

Код: sql
1.
2.
3.
4.
5.
START TRANSACTION;
INSERT INTO List1 (ContactName) VALUES ('Ivan Ivanov');
INSERT INTO List1 (ContactName) VALUES ('Petr Petrov');
... еще 1000 инсертов
COMMIT;



Аналогичным образом контакты будут массово удаляться через DELETE.

Встает вопрос: как поддерживать актуальным значения поля ContactsCount в таблице Groups ? SELECT COUNT (*) FROM List1 будет тормозить тем больше чем больше записей в таблице, а таблиц контактов может быть много ! В этой связи хотелось бы сделать триггер, который будет обновлять значение поле ContactsCount после выполнения транзакций на удаление или добавление.

Можно ли сделать триггер, который сработает ОДИН раз после транзакции, содержащей 1000 INSERT'ов (или DELETE'ов) ? Который сделает что-то типа этого:

Код: sql
1.
UPDATE Groups SET ContactsCount=ContactsCount+Insert_Transaction_Rows_Affected WHERE ContactsTableName=Insert_Transaction_Table_Name


При этом хотелось бы чтобы триггер срабатывал один раз после транзакции, а не 1000 раз для каждого INSERT'a в транзакции, иначе массовая вставка или удаление будут адски тормозить.

Возможно как-то решить эту проблему ? Я думаю это типовая задача и наверняка с ней кто-то сталкивался )

Огромное спасибо за помощь !
...
Рейтинг: 0 / 0
10.09.2016, 16:59
    #39307074
VSVLAD
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Триггер для обновления числа записей
amsdev,

Почему бы не использовать "классическую" схему (хранить все записи контактов в одной таблице, а не дробить на несколько)?
Groups (Group_id, Name)
Contacts (Contract_id, Group_id, Name)

А на счёт триггера, тогда можно и без него будет. Просто выбрать Count всех записей, сгруппированных по Group_Id. Тысяча инсертов, это немного. Выборка быстрая будет
...
Рейтинг: 0 / 0
10.09.2016, 17:03
    #39307076
amsdev
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Триггер для обновления числа записей
авторПочему бы не использовать "классическую" схему (хранить все записи контактов в одной таблице, а не дробить на несколько)?
Groups (Group_id, Name)
Contacts (Contract_id, Group_id, Name)


Потому что списки могут удаляться и DROP TABLE (по идее) отработает быстрее чем DELETE FROM AllLists WHERE GroupID=x

авторТысяча инсертов, это немного. Выборка быстрая будет

Миллионы INSET'ов или DELETE'ов, разбитые на транзакции по 1000.
...
Рейтинг: 0 / 0
10.09.2016, 17:59
    #39307090
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Триггер для обновления числа записей
amsdev ContactsTableName VARCHAR (20)
За это надо отрывать руки, ноги и все остальные выступающие части тела.

amsdevПри этом хотелось бы чтобы триггер срабатывал один раз после транзакции, а не 1000 раз для каждого INSERT'a в транзакцииНельзя. В сегодняшней версии SQLite триггер отрабатывает для каждой строки.
Триггер на транзакцию лежит в планах на разработку уже несколько лет.
Читать тут и тут:
http://sqlite.org/lang_createtrigger.html
http://sqlite.org/omitted.html

amsdevиначе массовая вставка или удаление будут адски тормозить.

Возможно как-то решить эту проблему ? Я думаю это типовая задача и наверняка с ней кто-то сталкивался )
Простой update агрегирующей таблицы после редактирования ведомой таблицы.
Но не сработает в имеющейся схеме.
...
Рейтинг: 0 / 0
10.09.2016, 18:17
    #39307093
amsdev
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Триггер для обновления числа записей
Хреново конечно, придется ручками считать и обновлять после выполнения транзакций...

авторContactsTableName VARCHAR (20)

авторЗа это надо отрывать руки, ноги и все остальные выступающие части тела.

За что ? ) В чем преступление ?
...
Рейтинг: 0 / 0
10.09.2016, 18:21
    #39307095
amsdev
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Триггер для обновления числа записей
Уточню: я планирую реализовать эту схему (где каждый список лежит в отдельной таблице) потому что у меня возможны операции Удалить список и Очистить список (т.е. удалить все записи в списке, в котором может быть несколько миллионов записей). Хотелось бы избежать DELETE для миллионов записей и заменить его на DROP TABLE->CreateTable. Собственно, эта схема предполагается именно по этой причине.
...
Рейтинг: 0 / 0
11.09.2016, 03:01
    #39307148
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Триггер для обновления числа записей
amsdevХреново конечно, придется ручками считать и обновлять после выполнения транзакций...

авторContactsTableName VARCHAR (20)

авторЗа это надо отрывать руки, ноги и все остальные выступающие части тела.

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

В любом случае, миллион записей за раз это, во первых, не так уж много.
Во вторых, это не может быть частой операцией. И задержка в несколько секунд не сделает погоды.
А в третьих я очень сомневаюсь что ты нам сказал реальные цифры. Не, есть конечно задачи в которых огромные объемы постоянно проходят через СУБД, но в этих задачах не бывает новичков :)
...
Рейтинг: 0 / 0
Форумы / SQLite [игнор отключен] [закрыт для гостей] / Триггер для обновления числа записей / 7 сообщений из 7, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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