Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як працюють масиви в PostgreSQL і коли їх використовувати?

PostgreSQL дозволяє зберігати в колонці масив значень будь-якого типу: text[], int[], uuid[].

CREATE TABLE posts (
    id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    title text NOT NULL,
    tags text[] NOT NULL DEFAULT '{}'
);

INSERT INTO posts (title, tags) VALUES ('Черги в Laravel', ARRAY['laravel', 'queues']);

SELECT * FROM posts WHERE 'queues' = ANY(tags);       -- містить елемент
SELECT * FROM posts WHERE tags @> ARRAY['laravel'];   -- містить усі
SELECT * FROM posts WHERE tags && ARRAY['vue', 'react'];  -- є хоча б один спільний
SELECT unnest(tags) AS tag, count(*) FROM posts GROUP BY tag;   -- розгорнути в рядки

Для швидкого пошуку - GIN-індекс: CREATE INDEX posts_tags_idx ON posts USING gin (tags); (працює з @>, &&, але не з = ANY).

Індексація з одиниці: tags[1] - перший елемент.

Коли масив доречний:

  • Невеликий список простих значень, що читається й замінюється разом із рядком: теги, ролі, налаштування-прапорці.
  • Значенням не потрібні власні атрибути й посилання на інші таблиці.

Коли краще окрема таблиця:

  • Елементи посилаються на інші сутності - масив ID не має зовнішніх ключів, і видалення пов'язаного запису не прибере його з масиву.
  • Потрібні атрибути зв'язку (хто й коли додав тег).
  • Потрібно часто змінювати окремі елементи чи масив великий.
  • Потрібні звичайні JOIN і агрегати - на масивах вони можливі, але громіздкіші.

Пастки: NULL і порожній масив '{}' - різні речі; = ANY(NULL) дає NULL; багатовимірні масиви мусять бути «прямокутними». Laravel не має типу масиву в схемі - колонку додають через $table->addColumn(...) чи сирий SQL, а читають з кастом.

Докладніше в документації: Масиви

Схожі питання