Массивы вместо множественных JOIN
Should Have
Иногда использование массивов может быть эффективнее, чем множественные JOIN или подзапросы.
Пример с массивами:
-- Получение всех тегов для продуктов одним запросом
SELECT p.product_id, p.product_name, ARRAY_AGG(t.tag_name) as tags
FROM products p
JOIN product_tags pt ON p.product_id = pt.product_id
JOIN tags t ON pt.tag_id = t.tag_id
GROUP BY p.product_id, p.product_name;
Поиск по массивам
Should Have
PostgreSQL имеет операторы для работы с массивами, которые могут быть очень эффективными.
Пример поиска в массиве:
-- Найти продукты с определенным тегом
SELECT * FROM products
WHERE tags @> ARRAY['organic']; -- Оператор @> проверяет, содержит ли массив указанное значение
-- Найти продукты с любым из указанных тегов
SELECT * FROM products
WHERE tags && ARRAY['organic', 'gluten-free']; -- Оператор && проверяет пересечение массивов
Создание таблиц с массивами
Should Have
Как мы уже писали в уроке 7, что использование массивов в структуре таблиц может значительно упростить схему базы данных и сократить количество таблиц и строк.
Пример создания таблицы с массивом:
-- Традиционный подход с отдельной таблицей для тегов
CREATE TABLE products (
product_id SERIAL PRIMARY KEY,
product_name VARCHAR(100),
price DECIMAL(10, 2)
);
CREATE TABLE product_tags (
product_id INTEGER REFERENCES products(product_id),
tag_name VARCHAR(50),
PRIMARY KEY (product_id, tag_name)
);
-- Подход с использованием массива
CREATE TABLE products_with_arrays (
product_id SERIAL PRIMARY KEY,
product_name VARCHAR(100),
price DECIMAL(10, 2),
tags TEXT[] -- Массив тегов
);
Преимущества использования массивов:
Пример вставки данных в таблицу с массивом:
-- Вставка продукта с несколькими тегами
INSERT INTO products_with_arrays (product_name, price, tags)
VALUES ('Organic Banana', 1.99, ARRAY['organic', 'fruit', 'fresh']);
Сравнение запросов для получения продуктов с тегами:
-- Традиционный подход с JOIN
SELECT p.product_id, p.product_name, p.price, t.tag_name
FROM products p
JOIN product_tags t ON p.product_id = t.product_id
WHERE t.tag_name = 'organic';
-- Подход с массивами
SELECT product_id, product_name, price, tags
FROM products_with_arrays
WHERE tags @> ARRAY['organic'];