в чем разница между созданием другой таблицы и использованием массивов в postgres

#arrays #postgresql #database-design #denormalization

#массивы #postgresql #база данных-дизайн #денормализация

Вопрос:

В моем университете мне дали задание создать простую университетскую базу данных с несколькими таблицами типа student, departments и т.д. Был интересный момент, когда я делал отношения между студентами и классами, один студент может выбирать несколько классов, меня учили создавать третью таблицу с двумя FK, и она должна выглядеть следующим образом: Адам (id — 1) посещает курс математики (id — 5), и в третьей таблице запись будет (1, 5), и вот вопрос, почему мы должны предпочесть третью таблицу вместо массивов, для меня гораздо проще разместить классы студентов в качестве дополнительного столбца в student таблица. Вот пример, представьте таблицу student (id, name, age, arrayOfClassesID) (1, Adam, 20, [1,8,9,6,7]) .

P.S. Это не мое домашнее задание, я его уже выполнил, но для меня это действительно интересно

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

1. Во-первых, у вас не может быть внешнего ключа, который гарантирует, что в этом массиве хранятся только допустимые идентификаторы классов

2. @a_horse_with_no_name, да, это первое, что пришло мне в голову. Но кроме этого, как насчет производительности, потому что, используя массивы, мы удаляем JOIN и, насколько я знаю, JOIN стоит дорого

3. Нет, объединения не «стоят дорого», это распространенное заблуждение. Вокруг этого построены реляционные базы данных. Единственный случай, когда массив имеет смысл, — это когда вы всегда считываете и записываете все элементы как одно значение и вам никогда не приходится искать отдельные элементы в массиве. Цитирую руководство » Массивы не являются наборами; поиск определенных элементов массива может быть признаком неправильного проектирования базы данных »

4. @a_horse_with_no_name, о, отлично, это действительно хороший ответ, поэтому, если я выберу всех студентов и их классы, массив будет иметь смысл, но если я сделаю что-то вроде выбора всех студентов, которые изучают математику и биологию, в этом случае массив будет плохой практикой. Я прав?

5. Использование array for FK s приведет к проблемам с производительностью с точки зрения линейного поиска внутри массива. Более того, это затрудняет выполнение запросов

Ответ №1:

С теоретической точки зрения проблема заключается в том, что такой дизайн нарушает первую нормальную форму. Это имеет практические последствия:

  • Как прокомментировал a_horse_without_name, проблема номер один заключается в том, что у вас не может быть ограничений внешнего ключа на элементы массива.

  • Индексирование для быстрого поиска работает ограниченным образом с использованием индексов GIN и @> оператора. Поиск с помощью LIKE или > не может быть оптимизирован.

  • Поиск класса для всех учащихся будет менее эффективным, даже с индексом GIN, а запрос будет более сложным и менее интуитивно понятным.

  • Если вы хотите удалить класс для student, вам придется переписать весь массив. Возможно, здесь это не большая проблема, но с более длинными массивами это может повредить.

Использование таблицы сопоставления — это естественный способ сделать это в реляционной базе данных.