LINUX.ORG.RU

Проектирование БД: наследование

 ,


0

2

Добрый день. Необходимо сейчас проектировать базу данных. И возникла такая задача: У нас есть в системе пользователи. У пользователей есть общие данные. А также ссылки на таблицу пользователей других таблиц. Но, при этом, сами пользователи могут различаться ролями. И, в зависимости от роли, у них разные дополнительные данные и ссылки из других таблиц. Как такое грамотнее будет реализовать, в т.ч точки зрения нормализации БД? Идея запихунть все в одну таблицу - не очень нравится. Пока есть следующие предположения - Выделяем общую таблицу User. И также отдельные таблицы с дополнительными данными для каждой нужной нам роли. Из этих таблиц unique foreign key на таблицу User. Но, как мы понимаем, unique будет работать только на таблицу конкретной роли, а не на все, что не всегда может быть хорошо.

И также отдельные таблицы с дополнительными данными для каждой нужной нам роли.

По таблице на роль? Не жирно? И что там будет храниться? key-value?

crutch_master ★★★★★
()
Последнее исправление: crutch_master (всего исправлений: 1)
Ответ на: комментарий от crutch_master

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

peregrine ★★★★★
()
Ответ на: комментарий от peregrine

У меня стойкое ощущение, что он собрался использовать РСУБД совсем не так, как надо и его надо отговорить от этой дурацкой затеи.

crutch_master ★★★★★
()
Последнее исправление: crutch_master (всего исправлений: 1)
Ответ на: комментарий от crutch_master

У меня стойкое ощущение, что он собрался использовать РСУБД совсем не так, как надо и его надо отговорить от этой дурацкой затеи.

+1. Таблица Users и Authorities (Roles) хватит. Остальное програмно.

anonymous
()
Ответ на: комментарий от crutch_master

По таблице на роль? Не жирно? И что там будет храниться? key-value?

Там всего две роли. Грубо говоря, продавец и покупатель. В зависимости от роли, данные разные. Но есть некоторые общие данные также и код, который обрабатывает именно User - независимо от роли.

crarkie
() автор топика
Ответ на: комментарий от crutch_master

У меня стойкое ощущение, что он собрался использовать РСУБД совсем не так, как надо и его надо отговорить от этой дурацкой затеи.

Возможно. Опыт проектирования БД у меня не слишком большой. Именно поэтому и задал вопрос тут, чтобы подсказали те, у кого опыт явно больше.

crarkie
() автор топика
Ответ на: комментарий от crarkie

Но есть некоторые общие данные также и код, который обрабатывает именно User - независимо от роли.

Какие данные? В чём их суть?

и код

Какой код и причём тут субд? Ты же не собираешься хранить в субд код?

crutch_master ★★★★★
()
Ответ на: комментарий от crutch_master

У меня стойкое ощущение, что он собрался использовать РСУБД совсем не так, как надо и его надо отговорить от этой дурацкой затеи.

Я понимаю, что NoSQL следует брать, если структура каждый раз может разной быть. Т.е те же документы. Но у меня структура всегда одинаковая. Просто в зависимости от роли дополнительные данные для каждого пользователя будут разные. Можно и с unique foreign key накостылить. И будет работать. Но красиво ли так.

crarkie
() автор топика
Ответ на: комментарий от crutch_master

Какой код и причём тут субд? Ты же не собираешься хранить в субд код?

Код на строне backend. Там же используется ORM.

crarkie
() автор топика
Ответ на: комментарий от crutch_master

Какие данные? В чём их суть?

Допустим, есть таблица Transaction. из нее идет ForeignKey на User. В зависимости от роли дополнительные данные могут быть по типу заказов и адреса доставки для покупателя. У продавца, например, это будут товары. С одной стороны можно все это и разделить. Но не хочется делать 2 таблицы Transaction для каждой роли. И там таких таблиц пару.

crarkie
() автор топика

Просто используй один и тот же номер записи и в таблице user, и в таблицах userext. В таблице user поле номера является первичным ключом, в таблицах userext поле номера является первичным ключом и внешним ключом на таблицу user.

iliyap ★★★★★
()
Ответ на: комментарий от r0ck3r

Таблица User Таблица Roles Таблица User-Roles

Думаю, возьму этот вариант. Пока выглядит самым адекватным.

crarkie
() автор топика
Ответ на: комментарий от iliyap

Просто используй один и тот же номер записи и в таблице user, и в таблицах userext. В таблице user поле номера является первичным ключом, в таблицах userext поле номера является первичным ключом и внешним ключом на таблицу user.

Т.е one-to-one, с той разницей, что ссылатся могут из разных таблиц?

crarkie
() автор топика
Ответ на: комментарий от crarkie

Допустим, есть таблица Transaction. из нее идет ForeignKey на User. В зависимости от роли дополнительные данные могут быть по типу заказов и адреса доставки для покупателя

Это всё реализуется на бекенде. В рбд должны быть только данные в 3-ей нормальной форме (возможна небольшая избыточность, без фанатизма) и никаких финтов ушами с оопэ. Рбд это просто таблицы, записи, ссылки на записи. Не надо в ней пытаться что-то городить сверх этого, субд и с этими тремя простыми вещами не всегда хорошо справляются. На ORM тебе придётся городить DTO. Не думай, что можно просто взять сделать структуру бд сразу под ORM.

crutch_master ★★★★★
()
Последнее исправление: crutch_master (всего исправлений: 1)
Ответ на: комментарий от crutch_master

На ORM тебе придётся городить DTO

Если можно, то поподробнее тут? Т.е, грубо говоря, join-ить нужные данные из нескольких таблиц и конструировать уже на беке нужный нам обьект?

crarkie
() автор топика
Ответ на: комментарий от crarkie

Допустим, есть таблица Transaction. из нее идет ForeignKey на User. В зависимости от роли дополнительные данные могут быть по типу заказов и адреса доставки для покупателя. У продавца, например, это будут товары. С одной стороны можно все это и разделить. Но не хочется делать 2 таблицы Transaction для каждой роли. И там таких таблиц пару.

Как то это выглядит не очень... Такое впечатление, что единый блок данных о «транзакции» ты пытаешься растащить по покупателям/продавцам. Зачем? Сделай его единым и к нему два внешних ключа на User - продавец и покупатель.

yyk ★★★★★
()
Ответ на: комментарий от crarkie

По сути ORM должна просто повторять структуру БД. Ну можно пару мелких фич добавить типа ассоциативного массива вместо списка в связанной таблице. А всё что сильно сложнее этого вываливается в DTO, т.е. такие объекты, где, например, собираются данные из n таблиц по одному полю. Ты же не будешь обходить все эти orm объекты каждый раз, чтобы построить какой-нибудь список, типа цена, название товара, список магазинов где он есть и сколько его там. Хотя после такого ты поймешь, что ORM - это отстой, что-то более-менее сложное выливается в выборку всей базы по одному запросу, кроме бложиков да примитивного вебчика оно ни на что не годится и сделаешь те же самые DTO на запросах.

crutch_master ★★★★★
()
Ответ на: комментарий от crutch_master

Рбд это просто таблицы, записи, ссылки на записи. Не надо в ней пытаться что-то городить сверх этого, субд и с этими тремя простыми вещами не всегда хорошо справляются.

И привет 3-звенка! СУБД - это еще и отношения и целостность. Если по-твоему субд с этим не очень хорошо справляется, то другие решения скорее всего потребуют еще больше мощностей и усилий. И надо сначала доказать, что в его конкретном случае это имеет смысл, а не приводить своё виденье мира как истину в последней инстанции при таких скудных исходных данных.

Давно не срались по теме использования баз ))))

yyk ★★★★★
()
Ответ на: комментарий от yyk

Хотя после такого ты поймешь, что ORM - это отстой

В целом согласен. Но сейчас не настолько крупный проект, чтобы об этом парится и хочется просто rapid-development. А тут ORM очень даже помогает. Если нужно делать выборку по куче запросов, фильтрацию сложную на стороне БД, то ORM тут будет затыком. Но так как я пишу на Python, то можно еще и SQLAlchemy Core взять, который не такой ограниченный как ORM, но и не такой запаристый, как Raw SQL.

crarkie
() автор топика
Ответ на: комментарий от yyk

Давно не срались по теме использования баз ))))

Yeah! Даешь срач на 20 страниц! Щас посмотрим, сколько осталось sql-дидов и есть ли у них еще порох.

И привет 3-звенка!

Что плохого в 3-звенке?

СУБД - это еще и отношения и целостность.
отношения

ссылки на записи

целостность

Ну естественно. Ссылки же на записи, а не дохлые ссылки.

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

Субд плохо справляются, например, с иерархическим деревом. Тупо хранить parent_id - всё ок, но делать выборку всех потомков - уже начинаются всякие костыли, переподвыборки, встроенные язычки и сделать это проще на любом мейнстримном яп.

а не приводить своё виденье мира как истину в последней инстанции

Нее. Так хорошего треда не выйдет.

crutch_master ★★★★★
()
Ответ на: комментарий от crarkie

Да, one-to-one. Но это не мешает иметь запись в person, которой соответствует и запись в seller, и запись в purchaser.

iliyap ★★★★★
()
Ответ на: комментарий от crarkie

хочется просто rapid-development

О, вот как правильно называется шлёп-шлёп и в продакшон, ну да, если надо сдать и больше никогда не видеть. А зачем вообще тебе понадобился магазин на питоне, если есть opencart и еще куча всего?

crutch_master ★★★★★
()
Ответ на: комментарий от iliyap

Но это не мешает иметь запись в person, которой соответствует и запись в seller, и запись в purchaser.

С точки зрения целостности, можето constraint навесить как-то, чтобы ссылка была либо в seller, либо в purchaser. Боюсь просто, что такой constraint дорогой по производительности будет, ибо в нем надо делать select.

crarkie
() автор топика
Ответ на: комментарий от crarkie

Это ограничение не нужно. Наоборот это правильная модель окружающего мира — одно и то же лицо может выступать как продавец в одних сделках, и как покупатель в других.

iliyap ★★★★★
()
Последнее исправление: iliyap (всего исправлений: 1)
Ответ на: комментарий от crutch_master

А зачем вообще тебе понадобился магазин на питоне, если есть opencart и еще куча всего?

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

crarkie
() автор топика
Ответ на: комментарий от iliyap

Это ограничение не нужно. Наоборот это правильная модель окружающего мира — один и тот же человек может выступать как продавец в одних сделках, и как покупатель в других.

В окружающем мире да. В моем проекте - нет) Но да ладно, там условный constraint будет итак гарантироваться бэком.

crarkie
() автор топика
Ответ на: комментарий от crarkie

Да 3 таблицы надо, транзакции, покупки, продажи. В последних двух - id транзацкии. Роль (id в таблице пользователей) никак не должна влиять на то, что там связывается. Выборка для одной роли и выборка для другой - это две разные выборки, нет смысла их лепить в одну. РБД всё равно не умеет и не должна уметь в динамический набор колонок в зависимости от условий.

crutch_master ★★★★★
()
Последнее исправление: crutch_master (всего исправлений: 1)
Ответ на: комментарий от crarkie

Конспирация, госдеп, все дела.

Сворачиваемся!.. Все на трактор!.. Бесплатно помогать поднимать налоги или вести глобальные картотеки?.. ))))

yyk ★★★★★
()
Ответ на: комментарий от crarkie

Если множественное наследование надо запретить, то в таблице объектов базового класса добавляют поле class — перечислимое, контролируемое check constraint-ом check class in (1, 2, 3). В таблицах объектов производных классов тоже добавляют поле class, делают составной внешний ключ (n, class) на таблицу объектов базового класса, и check constraint check class=1.

iliyap ★★★★★
()
Ответ на: комментарий от yyk

Сворачиваемся!

Стойте, а как же срач на 20 страниц? Последний раз тут что-то нормальное было наверное пол года назад.

crutch_master ★★★★★
()
Последнее исправление: crutch_master (всего исправлений: 2)
Ответ на: комментарий от iliyap

Можно пример со структурой, как вся эта оопота будет выглядеть и хранится на какой-нибудь мейнстримовой субд типа postrges или mysql. Ну или просто один вопрос. Key-value таблицы будут?

crutch_master ★★★★★
()
Последнее исправление: crutch_master (всего исправлений: 2)
Ответ на: комментарий от crutch_master

делать выборку всех потомков - уже начинаются всякие костыли

Просто логику по сохранению сущности нужно хранить в БД, тогда будут у тебя не костыли, а проектное решение.

//поддержал срач набросом

anonymous
()
Ответ на: комментарий от crutch_master

Можно пример со структурой, как вся эта оопота будет выглядеть и хранится на какой-нибудь мейнстримовой субд типа postrges или mysql. Ну или просто один вопрос. Key-value таблицы будут?

И да, и нет. Будет что-то по типу option-price таблицы. И отдельной ManyToMany таблицы OptionUser, чтобы не городить десятки одинаковых option-price.

crarkie
() автор топика
Ответ на: комментарий от crutch_master

Что плохого в 3-звенке?

Как и в любом другом расхайпленном инструменте - используют не там и не так. Но, наверное, и её использование где-то обосновано, и не только привычками разраба.

Субд плохо справляются, например, с иерархическим деревом.

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

Так это и ежу понятно (если нет претензий к нормализации ;))

Так хорошего треда не выйдет.

Конечно не выйдет, если ты с козырей ходишь )))

yyk ★★★★★
()
Ответ на: комментарий от crutch_master

ORM - это отстой

Не ORM, а JPA. Из-за всратости стандарта, позволяющего не реализовывать, например, union, мы и имеем то, что имеем.

и сделаешь те же самые DTO на запросах

И поймёшь, что с ORM было не так уж плохо. Это ж капец - руками каждый раз все CRUDы писать.

Deleted
()
Ответ на: комментарий от crutch_master

Точно срача не будет - тут я тебя поддержу: вот эту ООП-оту совать в СУБД - такой хоккей нам точно не нужен....

yyk ★★★★★
()
Ответ на: комментарий от Deleted

Раз не ORM, так сразу все запросы руками? Это вам пра-пра-дедушкина шашка на голову упала, что с тех пор у вас такой чёрно-белый (однобитовый) взгляд на мир?

yyk ★★★★★
()
Ответ на: комментарий от Deleted

Это ж капец - руками каждый раз все CRUDы писать.

Ну если система состоит полностью из CRUDов, то там и с orm нет никаких проблем. Собственно для этого orm только и нужен.

crutch_master ★★★★★
()
Ответ на: комментарий от Deleted

Это ж капец - руками каждый раз все CRUDы писать.

Ну вот, например, надо сделать выборку по произвольному набору данных. Т.е. есть список id, по ним и надо выбрать записей, так скажем 10к+. Как это сделать на hibernate, шоб было одним запросом и не выбирать сразу всю базу.

crutch_master ★★★★★
()
Последнее исправление: crutch_master (всего исправлений: 1)
Ответ на: комментарий от yyk

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

Тупо id, parent_id надо выбрать всех потомков одного id и потомков их потомков, и т.д., одним запросом.

crutch_master ★★★★★
()
Ответ на: комментарий от Deleted

Мопед не мой, это тебе к джавистам, они хвастались, что даже без ОРМ-ов у них куча библиотек по автоматизации составления, изменения, параметризации и прочего контроля SQL-запросов, и без всего этого траха с преодолением ограничений ОРМ-ов.

yyk ★★★★★
()
Ответ на: комментарий от Deleted

Докупить памяти, 10к - не так много))0)
Вообще, есть scroll().

Нет, так срача не получится, это слишком неадекватно. Какой нахрен скролл? Ты предлагаешь выбрать всё, что есть и скроллить? Это даже не из пушки по воробьям, это водородной бомбой по мухам.

crutch_master ★★★★★
()
Ответ на: комментарий от yyk

Мопед не мой, это тебе к джавистам, они хвастались, что даже без ОРМ-ов у них куча библиотек по автоматизации составления, изменения, параметризации и прочего контроля SQL-запросов

Где они хвастались? Я знаю кроме орм только mybatis и jdbi и оба они как-то не очень.

crutch_master ★★★★★
()
Ответ на: комментарий от Deleted

Из-за всратости стандарта, позволяющего не реализовывать, например, union, мы и имеем то, что имеем.

Сделай вьюху и будет тебе union.

crutch_master ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.