в чем полезность типа массива? - PullRequest
7 голосов
/ 22 апреля 2011

Я совершенно новичок в postgresql, но у меня хороший опыт работы с mysql. Я читал документацию и обнаружил, что postgresql имеет тип массива. Я в замешательстве, так как не могу понять, в каком контексте этот тип может быть полезен в rdbms. Почему я должен выбирать этот тип вместо использования классического отношения ко многим?

Заранее спасибо.

Ответы [ 3 ]

4 голосов
/ 22 апреля 2011

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

SELECT id, content
FROM nodes
WHERE tree = X
ORDER BY path -- The array is here.

PostgreSQL будет сравнивать элементы массива естественным образом, поэтому ORDER BY path будет выгружать дерево в разумном порядке линейного отображения;затем вы проверяете длину path, чтобы выяснить глубину узла, и это дает вам отступ для правильного рендеринга.

Приведенный выше подход возвращает вас из базы данных на визуализированную страницу за один проход.данные.

PostgreSQL также имеет геометрические типы , простые типы ключ / значение и поддерживает создание различных других составных типов .

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

1 голос
/ 08 мая 2011

Я успешно их использую для агрегирования рекурсивных ссылок на деревья с использованием триггеров.

Например, предположим, что у вас есть дерево категорий, и вы хотите найти товары в любой из категорий (1,2,3) или в любой из их подкатегорий.

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

with recursive categories as (
select id
from categories
where id in (1,2,3)
union all
...
)
select products.*
from products
join product2category on...
join categories on ...
group by products.id, ...
order by ... limit 10;

Другой способ - предварительно агрегировать необходимые данные:

* * 1010

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

Чтобы обойти это, я увеличил статистику по столбцу с индексом gin и периодически просматриваю pg_stats для получения более подходящей статистики. Когда беглый взгляд на эту статистику показывает, что использование && для указанных значений вернет неверный план, я переписываю применимые вхождения && с помощью arrayoverlap () (последний имеет селективность заглушки 1/3), например ::

select products.*
from products
where arrayoverlap(cat_id, array(
      select id from categories where arrayoverlap(parents, array[1,2,3])
      ))
order by ... limit 10;

(То же самое касается оператора <@ ...) </p>

1 голос
/ 22 апреля 2011

Один пользователь SO использует его для того, что выглядит как машинный перевод .Комментарии к последующему вопросу могут помочь понять его подход.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...