169 похожих чатов

Коллеги, подскажите, как нормальные люди хранят иерархические данные? Сущности, которые у

меня есть:
product_id - товар
sale_date - дата продажи этого товара
region_id - регион продажи (область, край, республика)
segment_id - к какому сегменту относится продажа
pay_sum - деньги

При этом каждый регион относится к федеральному округу, а каждый федеральный округ ко всей РФ.
И каждый сегмент относится к общему сегменту. Основных сегментов много (пара десятков), но общих всего три (пересечений нет).

Сейчас у нас в основную таблицу льются данные по регионам и основным сегментам, потом группируются по общим сегментам, потом каждый сегмент (и основной, и общий) группируются по ФО и по РФ. И всё это лежит в одной таблице.

Так нормально вообще хранить данные с кучей повторений? Или лучше, например, к каждой строке просто добавить столбцы parent_segment, federal_region_id и county_region_id. И потом просто группировать по ним?

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

6 ответов

43 просмотра

Непонятно вот что - зачем разные уровни агрегации держать в одном месте. Мне сложно представить ситуацию, когда такое месиво летит с бэкенда (агрегаты в целом с бэка лететь не должны), поэтому я бы сырье держала отдельно, агрегаты - отдельно (в другой таблице) Про federal_region_id и иже с ними - кажется разумным завести справочник-соответствие country_region_id - region_id отдельной таблицей и джойнить, когда надо.

Stas-B Автор вопроса
Алена Ядвичук
Непонятно вот что - зачем разные уровни агрегации ...

Моя догадка, что сделано это было когда-то давно ради скорости получения данных. Но эти выгрузки всё равно сейчас делаются по несколько минут иногда, так что не уверен, что это работает. И СУБД у нас везде оракл. Думаю вот, может для этого колоночную лучше взять? И тогда по идее агрегаты даже хранить не надо будет. Справочники все есть, но они для агрегирования только и используются. Или например индексов насыпать... Хотя думаю они там и так есть

Stas B
Моя догадка, что сделано это было когда-то давно р...

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

какую конкретно проблему вы решаете? в предыдущем сообщении у вас аналитики жалуются на недостаток места, в этом вы хотите насыпать индексов (~занять ещё места).

Stas-B Автор вопроса
Kirill Leontev
какую конкретно проблему вы решаете? в предыдущем ...

Пока что у меня задача чисто исследовательская. Я буду менять сборку данных в своём проекте, которые потенциально будут отдаваться в другом формате. И хочу под это продумать здоровую архитектуру. Для этого анализирую текущее решение. Аналитики жалуются на место с текущим подходом, когда агрегаты по всем регионам и сегментам лежат в одной таблице. Я думаю не про добавление индексов на текущую архитектуру, а про замену агрегатов на индексы.

Stas B
Пока что у меня задача чисто исследовательская. Я ...

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

Похожие вопросы

Обсуждают сегодня

30500 за редактор? )
Владимир
47
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
вы делали что-то подобное и как? может есть либы готовые? увидел картинку нокода, где всё линиями соединено и стало интересно попробовать то же в ddl на lua сделать. решил с ч...
Victor
8
Подскажите пожалуйста, как в CustomDrawCell(Sender: TcxCustomGridTableView; ACanvas: TcxCanvas; AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean); получить наз...
A Z
7
Ребят в СИ можно реализовать ООП?
Николай
33
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
1
Он в одиночку это дело запилил или была какая-то команда?
Aquinary
12
~ 2m21s  nix shell github:nixos/nixpkgs#stack ~  stack ghc -- --version error: … while calling the 'derivationStrict' builtin at /builtin/derivation.nix:...
Rebuild your mind.
6
Всем привет, нужна как никогда, нужна помощь с IO в загрузчике. Пишу в code16 после установки сегментных регистров, пишу вывод символа. Пробовал 2 варианта: # 1 mov $0x0E, %a...
Shadow Akira
14
Карта сайта