|
sqlite3/Qt 4.3.0 - разогнать удаление записей
|
|||
---|---|---|---|
#18+
Здравствуйте! В общем, ситуация: имеется таблица, хранящая в себе древовидную :-\ структуру данных (такой изврат мне понадобился из-за того, что структура ожидается объемом полмиллиона нодов, в оперативку её не факт, что есть смысл запихивать (хотя можно), плюс по ней нужен поиск по вилдкардам/маскам, который дает БД). Т.е. записи в духе "integer id, integer parent, данные", id - это primary key unique not null autoincrement, а parent указывает на id родительской записи в той же таблице (он может быть равен 0, если это "корневая" запись. Теперь вопрос. Как такое "дерево" быстро удалить? (в один запрос никак, насколько я понимаю?) банальный перебор всех потомков (т.е. select id from asdf where parent=:id, чтобы узнать потомков, затем для него delete и все то же для каждого найденного потомка) работает жутко медленно - порядка минуты для 8000 записей. Можно чуть ускорить процесс, делая delete from asdf where id=:id or parent=:id, но все равно получается медленно, плюс требуется искать записи с потомками, это означает либо подзапрос (тормоза) либо дополнительное поле в базу. Как можно разогнать процесс такой структуры? Или проще отказаться от хранения дерева в БД и искать другие пути? Спасибо. Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2007, 02:23 |
|
sqlite3/Qt 4.3.0 - разогнать удаление записей
|
|||
---|---|---|---|
#18+
ErV wrote: > Здравствуйте! > В общем, ситуация: В общем, от идеи хранить древовидную структуру данных в табличной базе данных пришлось отказаться - слишком неэффективно. Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2007, 03:37 |
|
sqlite3/Qt 4.3.0 - разогнать удаление записей
|
|||
---|---|---|---|
#18+
ErV wrote: > слишком неэффективно. Хотя не факт... поиск быстро работает... в любом случае, вопрос об удалении дерева из базы остается открытым. Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2007, 04:36 |
|
sqlite3/Qt 4.3.0 - разогнать удаление записей
|
|||
---|---|---|---|
#18+
Если уж требуется часто убивать все дерево, и однозначно ивестно, что нижестоящие деревья не входят в какие-либо другие деревья, может стоит для каждой записи ввести ИД верхнего уровня.? Будет увличение дисковой памяти, но работать на удаление будет быстро. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2007, 13:14 |
|
sqlite3/Qt 4.3.0 - разогнать удаление записей
|
|||
---|---|---|---|
#18+
Nick_mi wrote: > Если уж требуется часто убивать все дерево, и однозначно ивестно, что > нижестоящие деревья не входят в какие-либо другие деревья, может стоит > для каждой записи ввести ИД верхнего уровня.? Будет увличение дисковой > памяти, но работать на удаление будет быстро. В принципе, я о таком же варианте думал, спасибо. Плохо то, что sqlite слишком медленно (хотя я реализовать мог криво) работает на добавление новых записей для такой структуры. (записи надо добавлять пачками по несколько тысяч штук. вчера обкатывал - тормозит по черному, плюс база весит в 7 раз больше чем пожиравший оперативку вариант, из-за которого все и было затеяно), т.е. от бд придется отказаться. Спасибо за совет, вопрос закрыт. Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2007, 14:08 |
|
sqlite3/Qt 4.3.0 - разогнать удаление записей
|
|||
---|---|---|---|
#18+
ErVТеперь вопрос. Как такое "дерево" быстро удалить? (в один запрос никак, насколько я понимаю?)Ну почему же? SQLite3 умеет триггера делать. Добавь в свою базу такой триггер и проблема решена. Код: plaintext 1. 2. 3.
... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2007, 18:20 |
|
sqlite3/Qt 4.3.0 - разогнать удаление записей
|
|||
---|---|---|---|
#18+
White Owl wrote: > Ну почему же? > SQLite3 умеет триггера делать. Добавь в свою базу такой триггер и > проблема решена. create trigger Kill_Whole_Tree after delete on > TreeTable for each row begin > delete from TreeTable where parentid=old.id; > end; > Теперь достаточно убить любую ноду, и все ее потомки будут убиты > триггером. Мммм... Не то. Потомки потомков не убивеются. Т.е. сносится не все дерево, убивается пара сотен нодов и все. Объем же убиваемого дерева от 8 до 100 тысяч нодов. Целостность данных гарантирую (т.е. выполняется условие, что нет ни одного нода, для которого отсутствет родитель, если нод не корневой). ЗА совет спасибо. Соответственно, встречный вопрос: этого (триггеров), насколько я помню, не было в "understaning sql" (http://sql.ru/docs/sql/u_sql/index.shtml). Что есть смысл почитать, чтобы с этим разделом ознакомиться? Сосднюю документацию? (http://sql.ru/docs/mysql/rus_ref например?) Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2007, 20:47 |
|
sqlite3/Qt 4.3.0 - разогнать удаление записей
|
|||
---|---|---|---|
#18+
ErVНе то. Потомки потомков не убивеются. Т.е. сносится не все дерево, убивается пара сотен нодов и все.Это как это? Если потомков не убивать, то появится набор узлов без родителей. Можно в принципе убивать потомков до Х-колена а остальным обнулять родителя таким образом превращая их в корневые ноды, но это будет еще более странно :) ErVСоответственно, встречный вопрос: этого (триггеров), насколько я помню, не было в "understaning sql" (http://sql.ru/docs/sql/u_sql/index.shtml). Что есть смысл почитать, чтобы с этим разделом ознакомиться? Сосднюю документацию? (http://sql.ru/docs/mysql/rus_ref например?)ээээ.... вообще-то, триггера это не совсем стандартная вещь, поэтому в книгах по стандарту SQL (как у Грабера например) это описано не будет а если и будет, то только в плане "есть еще такая штука в расширениях". А MySQL триггеров вообще делать не умеет, поэтому они в его книжке тоже не описаны. Не стандартно это :) Зато в SQLite триггера есть и конечно там они описаны: http://www.sqlite.org/lang_createtrigger.html Но там уже практика, без теории.... А вот где почитать теорию.... Извините, но тут я не смогу помочь. Я сам их на практике изучал сравнивая описания триггеров в БД разных типов :) ... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2007, 23:46 |
|
sqlite3/Qt 4.3.0 - разогнать удаление записей
|
|||
---|---|---|---|
#18+
White Owl wrote: > Это как это? Если потомков не убивать, то появится набор узлов без > родителей. Можно в принципе убивать потомков до Х-колена а остальным > обнулять родителя таким образом превращая их в корневые ноды, но это > будет еще более странно :) Не знаю почему, но в консоли оно не работает (хотя идея отличная). Могу скинуть тестовую базу (180кбайт в рар-архиве), если хотите. Сессия выглядит следующим образом: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.
триггер не вызывается и получаются ноды без родителей. версия sqlite - 3.4.1. >Зато в SQLite триггера есть и конечно там они описаны: >http://www.sqlite.org/lang_createtrigger.html >Но там уже практика, без теории.... А вот где почитать теорию.... >Извините, но тут я не смогу помочь. Я сам их на практике изучал >сравнивая описания триггеров в БД разных типов :) ПОнятно, большое спасибо. Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
12.09.2007, 05:02 |
|
sqlite3/Qt 4.3.0 - разогнать удаление записей
|
|||
---|---|---|---|
#18+
ErVНе знаю почему, но в консоли оно не работает (хотя идея отличная). .... Т.е. видно, что сносятся потомки первой ноды, но для всех остальных триггер не вызывается и получаются ноды без родителей.Хм....странно.... похоже на недоделку. Попробуй заменить в заголоке триггера after на before, заработает? ... |
|||
:
Нравится:
Не нравится:
|
|||
12.09.2007, 17:50 |
|
sqlite3/Qt 4.3.0 - разогнать удаление записей
|
|||
---|---|---|---|
#18+
White Owl wrote: > Хм....странно.... похоже на недоделку. Попробуй заменить в заголоке > триггера after на before, заработает? Нет. Эффект точно такой же. Один в один. Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
12.09.2007, 22:55 |
|
sqlite3/Qt 4.3.0 - разогнать удаление записей
|
|||
---|---|---|---|
#18+
Значит увы... триггера похоже пока не рабочие. Не умеют отрабатывать рекурсивно. Надо писать в саппорт.... ... |
|||
:
Нравится:
Не нравится:
|
|||
12.09.2007, 23:20 |
|
sqlite3/Qt 4.3.0 - разогнать удаление записей
|
|||
---|---|---|---|
#18+
White Owl wrote: > Значит увы... триггера похоже пока не рабочие. Не умеют отрабатывать > рекурсивно. Надо писать в саппорт.... Понятно. Спасибо за помощь. ЗЫ. Вопрос закрыт. Решил отказаться от использования БД. Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
13.09.2007, 00:30 |
|
sqlite3/Qt 4.3.0 - разогнать удаление записей
|
|||
---|---|---|---|
#18+
лол... а если убивать то место где привязка к дереву стоит, а в кроне делать обход всего дерева постепенно и убивать непривязанные ноды (те у кототых нет родителя) ... |
|||
:
Нравится:
Не нравится:
|
|||
29.05.2008, 08:01 |
|
sqlite3/Qt 4.3.0 - разогнать удаление записей
|
|||
---|---|---|---|
#18+
theLexIлол... а если убивать то место где привязка к дереву стоит, а в кроне делать обход всего дерева постепенно и убивать непривязанные ноды (те у кототых нет родителя) До ...цатого колена включительно :-) ... |
|||
:
Нравится:
Не нравится:
|
|||
11.06.2008, 12:40 |
|
sqlite3/Qt 4.3.0 - разогнать удаление записей
|
|||
---|---|---|---|
#18+
может воспользоватся http://www.scalingweb.com/embedded_file_system.php и держать дерево в меморимаппед файле ? хе... изврат... но чего не придумаеш... ... |
|||
:
Нравится:
Не нравится:
|
|||
11.06.2008, 19:58 |
|
sqlite3/Qt 4.3.0 - разогнать удаление записей
|
|||
---|---|---|---|
#18+
Есть еще фокус в том, что почти нигде рекурсивный триггер не работает. Причем выдает ошибку, а тут получается, что хоть что-то делает... ... |
|||
:
Нравится:
Не нравится:
|
|||
12.11.2010, 13:49 |
|
sqlite3/Qt 4.3.0 - разогнать удаление записей
|
|||
---|---|---|---|
#18+
_Black_Cat_Есть еще фокус в том, что почти нигде рекурсивный триггер не работает. Причем выдает ошибку, а тут получается, что хоть что-то делает... Работает. Рекурсивные триггеры появились год назад. Впрочем, триггеры тут вовсе не по делу, т.к. для такой задачи есть стандартный механизм, описанный в любой приличной книжке по SQL: http://www.sqlite.org/foreignkeys.html#fk_actions For an "ON DELETE CASCADE" action, this means that each row in the child table that was associated with the deleted parent row is also deleted. Поддержка Foreign Key в SQLite добавлена одновременно или почти одновременно с рекурсивными триггерами. Что касается постановки задачи, то линейную масштабируемость можно получить, только реализуя разделение дерева на поддеревья. В частности, модуль FTS3 именно так внутри устроен - и работает чертовски эффективно, у меня в тестах до полмиллиарда записей (база порядка 100 гиг), скорость вставки оставалась неизменной. Как хранилище использует обычные таблицы, но есть свои хитрости. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.11.2010, 00:55 |
|
|
start [/forum/topic.php?fid=54&fpage=25&tid=2009274]: |
0ms |
get settings: |
10ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
36ms |
get topic data: |
14ms |
get forum data: |
3ms |
get page messages: |
60ms |
get tp. blocked users: |
2ms |
others: | 14ms |
total: | 161ms |
0 / 0 |