Проектирование базы данных SQL: как обойти хранение списка? - PullRequest
0 голосов
/ 17 января 2019

Итак, у меня есть таблица базы данных, в которой нужно хранить список упражнений для каждой подпрограммы, например: enter image description here

Я знаю, что вы не должны использовать списки для баз данных SQL, но я, честно говоря, понятия не имею, как еще я могу это сделать. Есть идеи?

Ответы [ 2 ]

0 голосов
/ 17 января 2019

Я знаю, что вы не должны использовать списки для баз данных SQL ...

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

create table routines (
    id serial primary key,
    name text,
    exercises text[]
);

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

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

0 голосов
/ 17 января 2019

Стандартный способ SQL сделать это с 2 таблицами

create table routine (
    id serial primary key,
    name text
);

create table exercises (
    routine_id integer references routine(id) on delete cascade /*optional*/,
    exercise text
);

Postgres дает хороший синтаксис (хотя и не на 100% стандартном) для создания подпрограмм с упражнениями за 1 раз:

with new_routine_id as (
    insert into routine(name)
    values ('Chest')
    returning id
)
insert into exercises
select id, unnest(array['Bench Press', 'Skull Crusher', 'Incline Bench Press'])
from new_routine_id

Выбор такой же, как и следовало ожидать:

select id, name, array_agg(exercise order by exercise /*it could be ordered using an additional field*/) as exercises
from routine
join exercises on id = routine_id
group by id, name

редактирует @klin опубликовал альтернативное решение с 1 таблицей, содержащей массив для упражнений напрямую. Решение совершенно корректно и, в некотором смысле, проще моего (я все-таки упомянул это решение в своем первом комментарии).

ИМХО, есть 1 причина, по которой решение будет "лучше", чем другое. Вы работаете в команде, где все знают, как обращаться с массивами?

  • ДА: выберите решение @ klin
  • НЕТ: выберите мое решение выше. Вы можете делать все, что вам нужно, только с обычными JOIN, без массивов.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...