Производительность типа столбца Postgresql

#sql #database #postgresql #database-design

#sql #База данных #postgresql #проектирование базы данных

Вопрос:

Итак, допустим, мне нужно создать таблицу. Один из столбцов будет содержать массив строк, например, фрукты, которые кто-то купил. Теперь мне нужно выполнить поиск, например, кто купил какие фрукты, например, яблоко и т. Д. Теперь я могу выбрать два типа данных для столбца:

  1. Тип Json

    При таком подходе столбец будет хранить объект JSON и использовать операторы POSTGRESQL json для проверки наличия фрукта.

  2. строковый тип

    При этом мы объединяем все фрукты, например, «яблочный апельсиновый виноград». Для проверки существования мы можем использовать функцию LIKE или любую другую функцию сопоставления строк.

Хотя я сам не проводил сравнительный анализ, я хотел узнать у экспертов, какой подход будет наилучшим. Предположим, что для любой строки количество плодов не будет больше 200. Мы также получаем обновления, но они не такие частые. Скорее всего, мы получим больше запросов, чем обновлений.

Комментарии:

1. Ни один из подходов не подходит. Идите так, как предлагает @GMB, это, безусловно, лучшее. В дополнение к этому таблица мостов может иметь дополнительные атрибуты — время покупки, количество, цена и т.д.

Ответ №1:

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

 create table users (
    user_id serial primary key,
    name text
);

create table fruits (
    fruit_id serial primary key,
    name text
);

create table users_fruits (
    user_id  int references users(user_id)   on delete cascade,
    fruit_id int references fruits(fruit_id) on delete cascade
);
  

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

Затем вы можете легко и эффективно искать всех пользователей, у которых есть фрукты «apple», с помощью запроса типа:

 select u.*
from users u
where exists (
    select 1
    from users_fruits uf
    inner join fruits f on f.fruit_id = uf.fruit_id
    where uf.user_id = u.user_id and f.name = 'apple'
)