Что быстрее в Oracle?Маленький стол с древовидной структурой и огромный плоский стол - PullRequest
4 голосов
/ 08 октября 2010

Я разрабатываю приложение, которое будет использовать Oracle , и у нас есть эта иерархия отделов , которую нам необходимо отобразить в нашей базе данных. Что-то похожее на это (я уверен, что вы все знаете, о чем я говорю, но на всякий случай я включу часть ERD):

alt text

Таким образом, в нем будут храниться данные, которые выглядят так:

[1 | 0]
[2 | 1]
[3 | 2]
[4 | 2]

Другими словами:

Department 1
     |__Department 2
             |___Department 3
             |___Department 4

И так далее ...

Это увеличит количество записей, требуемых в таблице, и к данным можно получить доступ с помощью команды CONNECT BY , имеющей только 1 запись на отдел. Обычно мы рассматриваем эту древовидную структуру как решение, но в этом новом приложении производительность является критической, поэтому мне было интересно, что, если у меня будет уплощенная таблица, которая будет выглядеть следующим образом.

[1 | 0]
[2 | 1]
[3 | 1]
[3 | 2]
[4 | 1]
[4 | 2]

Это позволяет вам иметь очень очевидные отношения без необходимости знать родительский Департамент для данного ребенка, чтобы знать, каковы его департаменты верхней иерархии. Но это увеличивает объем необходимых данных, так как вам нужна запись для каждого уровня, на котором находится Департамент, а это означает, что если у нас есть уровень Департамента на 15 ниже верхнего уровня, нам потребуется 15 записей для него. Департамент довольно большой, так что это может оказаться огромной таблицей (около 2 миллионов записей).

Хорошо, так что после краткого вступления, это вопрос; Кто-то на самом деле пробовал это, чтобы сказать мне, что быстрее / дешевле для БД между этими двумя вариантами: огромный плоский стол или маленький дерево?

Ответы [ 4 ]

7 голосов
/ 08 октября 2010

Я бы определенно выбрал первый вариант (иерархический подход).Я думаю, что лучше моделировать данные правильно, чем просто использовать плохую модель данных для повышения производительности.Поскольку вы моделируете иерархию здесь, имеет смысл хранить ее таким образом в БД.

Если вы хотите получить лучшее из обоих миров, я бы рекомендовал взглянуть на использование материализованного представления , чтобы «сгладить» иерархические данные, тогда вы по-прежнему сохраняете данные должным образом, но вы получаете прирост производительности (если есть), используя материализованное представление.модель данных и до сих пор найти способы получить хорошую производительность.Но плохая модель данных будет стоить вам долгие годы, и для ее исправления потребуется очень много времени .

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

2 голосов
/ 04 августа 2011

Альтернативой для быстрого доступа к иерархическим данным является Вложенный набор Модель данных:

Вложенный набор в вики

Это позволяет вам иметь однопроходный доступ ко всем дочерним узлам, независимо от глубины, однако может потребоваться автономное обслуживание, в зависимости от вашей имплементации.

0 голосов
/ 08 октября 2010

С чем-то вроде отделов невозможно иметь достаточное количество записей в таблице, где производительность может быть проблемой.Даже не беспокойся об этом.

Даже с некоторыми другими типами иерархических данных, где может быть так много записей, что это может повлиять на производительность, всегда есть другие технологии / подходы для решения этих проблем производительности (когда они всплывают), и стоимостьреализация этих других решений почти всегда меньше, чем усилия по разработке и обслуживанию, которые вы бы понесли, пытаясь закодировать вашу систему в соответствии с плоской схемой.

0 голосов
/ 08 октября 2010

Если вам нужна производительность чтения, попробуйте перечисление пути.

[1 | 0]
[2 | 1]
[3 | 2]
[4 | 2]

становится

[1 | '0']
[2 | '0.1']
[3 | '0.1.2']
[4 | '0.1.2']

Таким образом, вы можете выбрать ВСЕХ детей 2, выполнив

SELECT * FROM dept WHERE path LIKE '0.1.2%'

Конечно, это компромисс между нормализацией и производительностью.

...