Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Проектирование БД Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2 3 4 5 6 7   вперед  Ctrl      все
 Реляционка тут бессильна?  [new]
registerers
Member

Откуда:
Сообщений: 47
Вот есть такой теоретический вопрос о реляционных связях между гетерогенными структурами данных. Матюк страшный, но на самом деле всё просто и такая проблема довольно часто возникает на практике, например в интернет-магазинах, всевозможных CRM-системах и не только.

Суть проблемы можно пояснить на примере того же банального интернет-магазина. Есть множество таблиц разных товаров, потому что набор свойств (атрибутов) у них разный. Например, булка хлеба и како-нибудь девайс. Вопрос - как положить в корзину и то, и другое, и пятое-десятое? Самое простое, что приходит в голову - это в таблице корзины выделить одно поле под айди товара, а другое - под ... (барабанная дробь) ... НАЗВАНИЕ ТАБЛИЦЫ, к которой относится этот айдишник. Но это же костыль-костыльный... Потому что никаких реляционных связей тут не построишь.

Картинка с другого сайта.

Мне в голову приходит только два типичных решения - это либо использования паттерна EAV (entity, attribute, value), либо все уникальные атрибуты каждого из видов товара держать в поле с особым типом данных - JSON/JSONB, как в БД PostgreSQL. Тогда, естесственно, сущность (таблица) будет одна и её можно спокойно класть в корзину.

Так вот интересно, существуют ли какие то более элегантные решения этой проблемы?
11 сен 17, 03:25    [20785530]     Ответить | Цитировать Сообщить модератору
 Re: Реляционка тут бессильна?  [new]
982183
Member

Откуда:
Сообщений: 1350
registerers
Есть множество таблиц разных товаров, потому что набор свойств (атрибутов) у них разный.

"Множество таблиц2 - глупость несусветная.
Есть стандартное решение.
Таблица товаров
Таблица свойств.
Таблица связей (чаще всего групп связей)
11 сен 17, 04:00    [20785535]     Ответить | Цитировать Сообщить модератору
 Re: Реляционка тут бессильна?  [new]
982183
Member

Откуда:
Сообщений: 1350
Погуглите проблему.
Десятки раз она обсасывалась.

[url=]https://zlob.in/2013/01/struktura-tablic-dlya-kataloga-tovarov-internet-magazina/[/url]
11 сен 17, 04:05    [20785540]     Ответить | Цитировать Сообщить модератору
 Re: Реляционка тут бессильна?  [new]
Ennor Tiegael
Member

Откуда:
Сообщений: 2857
Про supertype-subtype слышали?
11 сен 17, 08:06    [20785603]     Ответить | Цитировать Сообщить модератору
 Re: Реляционка тут бессильна?  [new]
registerers
Member

Откуда:
Сообщений: 47
982183
"Множество таблиц2 - глупость несусветная.


Множество таблиц - это и есть паттерн Flat tables, который описан в приведенной вами ссылки (кстати, спасибо за ссылку)

982183
Таблица связей (чаще всего групп связей)


А вот про таблицу связей можно подробнее?
11 сен 17, 17:14    [20787739]     Ответить | Цитировать Сообщить модератору
 Re: Реляционка тут бессильна?  [new]
registerers
Member

Откуда:
Сообщений: 47
Ennor Tiegael
Про supertype-subtype слышали?

Описанный мной костыль и есть паттерн supertype-subtype, разве нет?
11 сен 17, 17:15    [20787743]     Ответить | Цитировать Сообщить модератору
 Re: Реляционка тут бессильна?  [new]
Кот Матроскин
Member

Откуда: Москва
Сообщений: 7686
registerers
Ennor Tiegael
Про supertype-subtype слышали?

Описанный мной костыль и есть паттерн supertype-subtype, разве нет?


Нет. В означенном паттерне нет никаких tablename
11 сен 17, 17:32    [20787798]     Ответить | Цитировать Сообщить модератору
 Re: Реляционка тут бессильна?  [new]
registerers
Member

Откуда:
Сообщений: 47
Кот Матроскин
Нет. В означенном паттерне нет никаких tablename


Атрибут TableName в моём случае играет роль Type, суть одна. Это антипаттерн, так как смешиваются данные и метаданные. Другими словами, средствами РСУБД невозможно исключить ситуацию, когда в двух и более таблицах подтипа внешний ключ указывает на одну запись супертипа. В этом случае изменение типа приводит к нарушению ссылочной целостности
11 сен 17, 17:58    [20787882]     Ответить | Цитировать Сообщить модератору
 Re: Реляционка тут бессильна?  [new]
SERG1257
Member

Откуда:
Сообщений: 2499
Заведите общего предка для продуктов с двумя (пока) полями id primary key, name unique
Наложите на ProductA ProductB FK reference на эту общую таблицу
Эта же таблица будет удобна для поиска (в нее можно напихать индексированных полей для быстрого поиска) по всем товарам.
11 сен 17, 18:24    [20787963]     Ответить | Цитировать Сообщить модератору
 Re: Реляционка тут бессильна?  [new]
Кот Матроскин
Member

Откуда: Москва
Сообщений: 7686
registerers
Это антипаттерн, так как смешиваются данные и метаданные.

Не более, чем при использовании суррогатного ключа в таблице. Может, суррогатный ключ - это тоже антипаттерн? :)
registerers
Другими словами, средствами РСУБД невозможно исключить ситуацию, когда в двух и более таблицах подтипа внешний ключ указывает на одну запись супертипа. В этом случае изменение типа приводит к нарушению ссылочной целостности

Тоже мне, бином Ньютона - включаете поле Type в ключ, накладываете на него соответствующие ограничения в каждой из subtype-таблиц.
11 сен 17, 18:28    [20787976]     Ответить | Цитировать Сообщить модератору
 Re: Реляционка тут бессильна?  [new]
hVostt
Member

Откуда:
Сообщений: 11785
registerers
Так вот интересно, существуют ли какие то более элегантные решения этой проблемы?


Вынести атрибуты товаров в универсальную структуру: атрибут-значение.
Делать по таблице на каждый вид товара -- это наверное самое тупое, что вообще только можно выдумать.
11 сен 17, 23:02    [20788454]     Ответить | Цитировать Сообщить модератору
 Re: Реляционка тут бессильна?  [new]
Bsplesk
Member

Откуда:
Сообщений: 40
На самом деле EAV, не так уж и плох, да много join, посмотрите magneto, с jsonb не так все радужно, как малюют, так как вероятно наборы справочников вам все равно придется хранить (дополнительные дубли), + при записи jsonb данные необходимо валидировать, это удобно делать при помощи схем (к примеру одна схема на несколько типов), но допустим json-schema сырая, до xml-schema ещё как до Китая. С динамической моделью данных при работе с jsonb/json-schema тоже не все гладко ... Да и при текущей реализации jsonb это больше одно поле = один объект, иначе замучаетесь разворачивать все таки до работы со сложными графами сущностей все очень сыро, правда в 10 обещают улучшить, но это завязка на конкретную СУБД хоть и открытую....
11 сен 17, 23:21    [20788481]     Ответить | Цитировать Сообщить модератору
 Re: Реляционка тут бессильна?  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 43937

Bsplesk
да много join

join в EAV - тормоза для тех, кому лень программировать обработку наборов данных на
клиенте. Дельфийским мышекликателям настоятельно не рекомендую.

Posted via ActualForum NNTP Server 1.5

12 сен 17, 01:13    [20788576]     Ответить | Цитировать Сообщить модератору
 Re: Реляционка тут бессильна?  [new]
982183
Member

Откуда:
Сообщений: 1350
registerers
Множество таблиц - это и есть паттерн Flat tables, который описан в приведенной вами ссылки (кстати, спасибо за ссылку)

Там же и описываются громадные недостатки этого метода.
registerers
А вот про таблицу связей можно подробнее?

А связь номенклатуры и атрибутов вы хранить где думаете?
12 сен 17, 04:54    [20788633]     Ответить | Цитировать Сообщить модератору
 Re: Реляционка тут бессильна?  [new]
Незнайка.
Member [заблокирован]

Откуда:
Сообщений: 26
registerers
множество таблиц разных товаров, потому что набор свойств (атрибутов) у них разный

На каждый товар - отдельная таблица?
Кому и как такое могло в голову прийти?
12 сен 17, 07:23    [20788672]     Ответить | Цитировать Сообщить модератору
 Re: Реляционка тут бессильна?  [new]
982183
Member

Откуда:
Сообщений: 1350
На каждую группу товаров.
Технология "Flat tables" как было описано в ссылке выше :)
Вещь конечно узко специфичная. Я не сталкивался.
12 сен 17, 08:13    [20788716]     Ответить | Цитировать Сообщить модератору
 Re: Реляционка тут бессильна?  [new]
982183
Member

Откуда:
Сообщений: 1350
И тут уже оказывается всё обсасывалось.
17550595
12 сен 17, 08:17    [20788724]     Ответить | Цитировать Сообщить модератору
 Re: Реляционка тут бессильна?  [new]
Ares_ekb
Member

Откуда: Екатеринбург
Сообщений: 1042
982183
https://zlob.in/2013/01/struktura-tablic-dlya-kataloga-tovarov-internet-magazina/

Я голосую за 6НФ. Почему-то по ссылке нет этого варианта. Вроде у Avito используется такой подход, но это не точно.
12 сен 17, 09:35    [20788958]     Ответить | Цитировать Сообщить модератору
 Re: Реляционка тут бессильна?  [new]
Ennor Tiegael
Member

Откуда:
Сообщений: 2857
registerers
Ennor Tiegael
Про supertype-subtype слышали?

Описанный мной костыль и есть паттерн supertype-subtype, разве нет?
Вообще ничего общего.

Делается одна таблица, условно говоря Products, которая выступает корнем вашей товарной иерархии. Туда можно поместить атрибуты, общие для всех (или почти всех) видов товаров: название, внутренний код, вес, Д*Ш*В, (возможно) цена и т.д.

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

На эту же таблицу будет ссылаться корзина. Только вот, зачем у вас корзина ссылается на заказы? Во всех магазинах, какие я видел, если товар лежит в корзине, значит заказ на него еще не существует, ммм? Корзину лучше сделать М:М связкой между Products и Customers, как у всех.
12 сен 17, 10:12    [20789085]     Ответить | Цитировать Сообщить модератору
 Re: Реляционка тут бессильна?  [new]
tip78
Member

Откуда: Москва
Сообщений: 473
registerers
982183
Таблица связей (чаще всего групп связей)


А вот про таблицу связей можно подробнее?

гуглите "Нормальная Форма"
12 сен 17, 11:06    [20789231]     Ответить | Цитировать Сообщить модератору
 Re: Реляционка тут бессильна?  [new]
registerers
Member

Откуда:
Сообщений: 47
Кот Матроскин
Может, суррогатный ключ - это тоже антипаттерн? :)

Да, суррогатный ключ - это тоже метаданные, но не смотря на то, что этот атрибут содержится в сущностях наряду с другими, в РСУБД, ключи обеспечены механизмами обеспечения ссылочной целостности через наложение ограничений (constraints).

Кот Матроскин
включаете поле Type в ключ, накладываете на него соответствующие ограничения в каждой из subtype-таблиц

Интересно, как вы себе представляете эти "соответствующие ограничения"?))
Вот, например, физическая модель, из которой видно, что любая из subtype-таблиц может ссылаться на одну и ту же запись в supertype-таблице:
Картинка с другого сайта.

Кстати, если это не костыль, то напишите JOIN-запрос для такого кейса)))
13 сен 17, 15:03    [20792998]     Ответить | Цитировать Сообщить модератору
 Re: Реляционка тут бессильна?  [new]
registerers
Member

Откуда:
Сообщений: 47
По поводу тезиса "делать по таблице на каждый вид товара - это самое тупое, что только можно придумать", отвечу сразу, чтоб закрыть этот вопрос. Есть такая штука, как компромисс между гибкостью и производительностью. Если гибкость не нужна, то юзаем Flat Tables, если нужна - EAV, NoSQL etc. И. кстати, кроме НФ есть ещё такое понятие как денормализация, которую как раз и применяют для оптимизации производительности.
13 сен 17, 15:13    [20793040]     Ответить | Цитировать Сообщить модератору
 Re: Реляционка тут бессильна?  [new]
registerers
Member

Откуда:
Сообщений: 47
Dimitry Sibiryakov
Bsplesk
да много join

join в EAV - тормоза для тех, кому лень программировать обработку наборов данных на
клиенте. Дельфийским мышекликателям настоятельно не рекомендую.

это как? выгребать все данные потаблично и джойнить на клиенте?? о_О
13 сен 17, 15:19    [20793056]     Ответить | Цитировать Сообщить модератору
 Re: Реляционка тут бессильна?  [new]
registerers
Member

Откуда:
Сообщений: 47
982183
Там же и описываются громадные недостатки этого метода.
registerers
А вот про таблицу связей можно подробнее?

А связь номенклатуры и атрибутов вы хранить где думаете?

Не совсем понимаю, о чём вы. Вместо тысячи слов лучше нарисуйте пример диаграммы на draw.io
13 сен 17, 15:24    [20793073]     Ответить | Цитировать Сообщить модератору
 Re: Реляционка тут бессильна?  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 43937

registerers
это как? выгребать все данные потаблично и джойнить на клиенте??

Нет: делать PIVOT на клиенте.

Posted via ActualForum NNTP Server 1.5

13 сен 17, 15:36    [20793119]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2 3 4 5 6 7   вперед  Ctrl      все
Все форумы / Проектирование БД Ответить