Скажу я. Не могу сказать за все СУБД, потому буду про кауч.
В NoSQL нет джойнов. соответсвенно если у вас большое число разнотипных и больших оьъектов, связанных между собой, то хранение их в кауче (а точнее выборка) будет не слишком эффективно и вот почему.
Если хранить с полем, содержащим идентификатор связанного документа, то можно будет сделать квази-джойн на 1 уровень в глубину (на самом деле это не джойн, а просто сахар, для связанного id уже после мапа прогружается документ). Обсуловлено это тем, что функция map (в которой собственно происходит выборка) явяется чистой и для получения результата может пользоваться только переданным ей документом. Это нужно для оптимизации автоматического построения и обновления индексов.
Есть вариант хранения многоуровневой иерархии в одном документе, но это содержит ряд недостатков.
1. Документу нельзя только обновить поле. Надо загрузить документ, исправить поле и залить документ. Отсюда получаем, что для больших документов будет неэффективно.
2. Если требуется часто менять вложенные подобъекты, то вам придется самому озаботиться обновлением этих подобъектов во всех документах. Кстати аналогично будет и при денормализации БД в РСУБД.
Поэтому для себя делаю вывод, что в частности кауч подходит для хранения плоских или почти плоских моделей, без глубоких взаимосвязей. Причем оптимально его использовать для моделей с нечеткой структурой. НУ и само собой, когда нужна или планируется горизонтальная масштабируемость.
Ничего вам не придется. По крайней мере не во все NoSql СУБД. Это как раз в SQL субд вам надо озаботится о наличии индексов, а кауч все сделает наиоболее оптимальным образом для конкретного запроса. Естественно запрос должен быть описан во vew.
Например Couch для каждого view(считайте что это запрос) атоматически строит B+ дерево. То есть выборка будет оптимальна. Да и обновление этого дерева будет так же быстро за счет чистоты функции map. То есть для нового документа достаточно посчитать ключ и воткнуть в нужное место дерева.
Я об этом догадывался ;) я имею в виду есть ли удобные механизмы выборки объектов, подходящих под определенное условие (естественно с использованием индексов), какова относительная скорость работы, если допустим похожую структуру реализовать в связке hibernate + РСУБД на типовых выборках?
То, что вы описали, это есть лишь один из вариантов хранения (с parent_id) и СУБД просто предоставляют удобный способ этим пользоваться, однако существуют и другие способы хранения, оптимизированные для других операций.
Для некоторых задач не нужно ничего сложнее adjacency list (для которого как раз синтаксический сахар и предназначен), а некоторые придется описывать с помощью nested sets например.
В общем это я к чему. К тому, что как хранить иерархические данные в РСУБД зависит от типа решаемых задач.
P.S. Случаем никто не замерял скорость работы данных рекурсивных CTE, если надо выбрать все поддерево (например посчитать сумму опреленного поля у узла и всех его подузлов в полную глубину) на больших таблицах?
Если я не ошибаюсь — это объектная СУБД. Не подскажете, как она работает в сравнении со связкой РСУБД + hibernate в плане удобства, скорости и так далее? Все таки hibernate это по сути костыль.
А я вот все больше убеждаюсь, что не предназначены реляционные СУБД для хранения иерархических данных. Любой из способов хранения содержит те или иные недостатки. Наверняка существуют какие-то специализированные СУБД, например те же графовые.
Была похожая проблема. Правда принтер не работал под Linux, но не суть. Решилось так. На компе с принтером с помощью ghostscript создал виртуальный принтер и перенаправил задания с него на реальный. В настройках виртуального принтера можно выбрать любую модель. На компьюетере без принтера просто выбираем ту же модель и указываем, что принтер на другом компе.
Желательно выбирать PS принтер, с ними проблем должно быть меньше.
Вот ссылка с мануалом: www.stat.tamu.edu/~henrik/GSPSprinter/GSPSprinter.html
Ваш вариант не содержит хвостового вызова и потому в языках с его оптимизацией оптимизирован не будет
А в .Net (точнее в C#) лучше рекурсию не использовать вовсе, поскольку там нет оптимизации хвостовых вызовов на уровне компилятора. Хотя в CLR инструкция все же присутсвует. Хотя может со времен .NET 3.5 что-то изменилось, честно не в курсе.
Хотя применительно в данному примеру это неважно, поскольку здесь не такая большая глубина, чтобы заметить разницу или получить StackOwerflow
В NoSQL нет джойнов. соответсвенно если у вас большое число разнотипных и больших оьъектов, связанных между собой, то хранение их в кауче (а точнее выборка) будет не слишком эффективно и вот почему.
Если хранить с полем, содержащим идентификатор связанного документа, то можно будет сделать квази-джойн на 1 уровень в глубину (на самом деле это не джойн, а просто сахар, для связанного id уже после мапа прогружается документ). Обсуловлено это тем, что функция map (в которой собственно происходит выборка) явяется чистой и для получения результата может пользоваться только переданным ей документом. Это нужно для оптимизации автоматического построения и обновления индексов.
Есть вариант хранения многоуровневой иерархии в одном документе, но это содержит ряд недостатков.
1. Документу нельзя только обновить поле. Надо загрузить документ, исправить поле и залить документ. Отсюда получаем, что для больших документов будет неэффективно.
2. Если требуется часто менять вложенные подобъекты, то вам придется самому озаботиться обновлением этих подобъектов во всех документах. Кстати аналогично будет и при денормализации БД в РСУБД.
Поэтому для себя делаю вывод, что в частности кауч подходит для хранения плоских или почти плоских моделей, без глубоких взаимосвязей. Причем оптимально его использовать для моделей с нечеткой структурой. НУ и само собой, когда нужна или планируется горизонтальная масштабируемость.
Для некоторых задач не нужно ничего сложнее adjacency list (для которого как раз синтаксический сахар и предназначен), а некоторые придется описывать с помощью nested sets например.
В общем это я к чему. К тому, что как хранить иерархические данные в РСУБД зависит от типа решаемых задач.
P.S. Случаем никто не замерял скорость работы данных рекурсивных CTE, если надо выбрать все поддерево (например посчитать сумму опреленного поля у узла и всех его подузлов в полную глубину) на больших таблицах?
Желательно выбирать PS принтер, с ними проблем должно быть меньше.
Вот ссылка с мануалом: www.stat.tamu.edu/~henrik/GSPSprinter/GSPSprinter.html
А в .Net (точнее в C#) лучше рекурсию не использовать вовсе, поскольку там нет оптимизации хвостовых вызовов на уровне компилятора. Хотя в CLR инструкция все же присутсвует. Хотя может со времен .NET 3.5 что-то изменилось, честно не в курсе.
Хотя применительно в данному примеру это неважно, поскольку здесь не такая большая глубина, чтобы заметить разницу или получить StackOwerflow