@NordNerd

Какую структуру таблиц выбрать для описания некоторой сущности, у представителей которой часть атрибутов совпадает, а часть — различна?

Всем добрый день! Проектирую структуру базы данных в MySQL, и возникла проблема: предположим, что есть некая сущность, которую нужно отразить в таблицах базы данных. У всех конкретных экземпляров этой сущности есть некий общий набор свойств, но есть свойства, которые различаются для некоторых подмножеств экземпляров сущности.

Например, у продаваемых машин (новых или бывших в употреблении) есть некий общий набор параметров (производитель, цвет, год выпуска и т.д.). Однако если машина новая, то у неё есть особые параметры, - например, связанные с гарантией от производителя, чего нет у подержанной машины. А у подержанных машин есть свойства, которых нет у новых: пробег, длительность эксплуатации и т.д.

Как быть в этом случае? Создавать единую таблицу с кучей null или же несколько раздельных таблиц? Или делать таблицу для общих свойств и вспомогательные таблицы для дополнительных свойств? Может, есть некая общепринятая практика в этом случае?
  • Вопрос задан
  • 129 просмотров
Решения вопроса 2
mayton2019
@mayton2019
Bigdata Engineer
Путей много. Можно завести 2 таблички. Одна для новых машин. Другая - для подержанных. Со
своими наборами пропертей. Тогда и индексы строить удобно.
И с точки зрения типизации этот подход верный. Если язык разработки (Python/PHP) различает
типы машин - то для каждого типа нужна отдельная табличка. Это в духе ORM.
Недостаток - надо делать union all двух таблиц если мы хотим делать поиск по общим пропертям.

Можно завести 1 табличку с полем типа JSON и свалить туда все проперти которые могут быть
опциональны для новых машин и для Б/У. Это делает схему более компактной. И поиск по основным
полям работает универсально. Для кастомных полей надо искать описание в MySQL языков работающих
с JSON (JSonPath) для того чтоб выбирать и фильтровать и индексировать их.

Можно поступить как в BigData. Свалить все проперти что есть в одну большую таблицу. Будет в ней
допустим 500 колонок. И большая часть из них - пустая. Заполняется null. Такая модель тоже работоспособна.
Но для человека наблюдающего глазами таблицу будет неудобно с ней работать. Особенно когда нужное
тебе поле находится где-то на 400х колонках и надо скроллить грид мышкой вправо чтоб хотя-бы прочитать
глазами значения. И эволюция такой схемы проходит тяжелее. Т.к. alter table обычно блокирует таблицу
от транзакций DML и нужен регламент что добавлять новую колонку.
Ответ написан
Комментировать
@Shavadrius
Если у вас используется ORM, то спихните всю работу на него. Он вам через правильное наследование классов и подход code first сам сгенерирует нужную ему структуру в БД (вроде будет генерироваться одна таблица на сущность с кучей столбцов, это если 1-1 связь. Если 1-М или М-М - то будут дополнительные таблицы).
Если сами руками все делаете в Базе Данных, то можете просто ввести дополнительный столбец под JSON и писать туда доп.параметры. Правда не знаю как там индексируется это поле и настраивается поиск по нему, но скорее всего современные СУБД такое умеют.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
hint000
@hint000
у админа три руки
Как быть в этом случае? Создавать единую таблицу с кучей null или же несколько раздельных таблиц? Или делать таблицу для общих свойств и вспомогательные таблицы для дополнительных свойств? Может, есть некая общепринятая практика в этом случае?
Нет чёткой общепринятой практики, потому что в разных случаях оптимальное решение может быть разное, в зависимости от постановки задачи.
Иногда "единую таблицу с кучей null", иногда json, иногда EAV (не рекомендуется, но всё же лучше иметь возможность (знать о возможности), чем не иметь возможность): https://qna.habr.com/q/1224626
У каждого варианта свои минусы и плюсы.

Например, если "общих параметров" больше, чем "особых параметров", то куча null выглядит разумным выбором.
Ответ написан
ipatiev
@ipatiev
Потомок старинного рода Ипатьевых-Колотитьевых
Как правильно написали выше, общепринятой практики нет.
С натяжкой общепринятой можно назвать практику, когда часть свойств пишется в JSON поле, но как раз для описанного в вопросе случая она не должна применяться. Здесь однозначно подходит стандартная реляционная структура. Нет гарантии? Пишем null. Нет пробега? Пишем 0 км.

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

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы