Схема хранения изменяющихся данных с историей

Есть около 300 тыс объектов ( например легковых автомобилей) для каждого автомобиля раз в неделю производится замер параметров ( пробег, давление в шинах, количество топлива), параметров будет в районе 20 штук, нужно все это хранить в базе.

В освновном пользователей интерисуют только последние параметры. Но иногда необходимо отвечать на вопросы типа «А как менялось давление в шинах во времени», «А какие параметры менялись на прошлой неделе»

Интуиция говорит, что наверное надо смотреть в сторону mongo, но тех задание явно говорит, что будем использовать Mysql :)

Пока родилось два варианта

1)

Первая таблица (название data)

id| object_name | param1 | param1_is_changed | param1_change_date | param2…

Вторая таблица (название data_history)

id| object_name | param1 | param1_is_changed | param1_change_date | param2… | version | change_date

При каждом изменении любого параметра, предыдущая версия записывается в data_history, у того параметра который изменился ставится влажок is_changed

2) Первая таблица (название data)

id| object_name

Вторая таблица ( хранит только последние значения)

id | object_id | param_name | param_value | date

Третья таблица ( хранит историю значений из второй таблицы)


Сейчас мы отслеживаем около 50 тыс объектов, в неделю происходит около 200 изменений в параметрах. Все параметры числовые, поэтому вопрос избыточности хранения в первом случае волнует только в плане производительности БД, но никак не места на диске. Второй метод вроде хорош, но его не очень просто реализовать используя ORM.

Ваше мнение? как спроектировать DB? как найти компромисс между эффективной БД и удобством написания приложения к ней.
  • Вопрос задан
  • 4455 просмотров
Пригласить эксперта
Ответы на вопрос 7
Такую тему уже поднимали. Ваша первая модель похожа на ТИП 4.

Зачем поле param1_is_changed? Нужно определять какое именно поле изменилось, они меняются не группой?

Логики во втором методе, пока, не вижу.

Думаю, можно будет спроектировать так, что бы при выборке разницы а производительности не было.
Ответ написан
@Denter
А вариант с RRD не рассматривается?

Вопрос к переформулированию постановки задачи, потому как по определению RRD означает деградацию детализации старых данных. Но зато куча плюшек — начиная от фиксированного размера базы, заканчивая массой готовых реализаций и визуализации.
Ответ написан
kashey
@kashey
Программирую большую половину жизни
Сам использовал вариант 2.
Как не странно — очень часто выбрать правильное — не так уж и просто.
Долго парился с группами и правильными ордерами, чтобы выбирать последние данные кучи разнородного материала.

Кончилось тем что историю храню отдельно, а последний срез данных — отдельно.
Вообще никаких проблем, да и операции с главной базой стали проще и быстрее
Ответ написан
Комментировать
@MikhailEdoshin
Вообще натуральная модель, насколько я понимаю, будет такой:

Таблица 1. Vehicle (ID, Last Reading ID).

Таблица 2. Reading (ID, Vehicle ID, Date, и измеренные значения: Fuel, Oil, Tire Pressure, и т. д.).

Если она не устраивает по каким-то соображениям, тогда уже переходить к другим моделям. Пока что для меня, например, неочевидно преимущество хранения разнородных значений в одном поле. Да, это всё числа, но если вдруг добавится нечисловое значение, придётся существенно менять модель.
Ответ написан
Комментировать
pietrovich
@pietrovich
>Второй метод вроде хорош, но его не очень просто реализовать используя ORM.
дык, в mysql уже давно есть триггеры, емнип. организуйте сбор истории триггерами на insert/update/delete, а отображение истории можно уже крутить как угодно если плясать от отдельной таблицы (или вьюшки которая юнионов сошьет актуальные и архивные данные).
Ответ написан
mgyk
@mgyk
1) Таблица с данными. Date, ID_объекта, ID_параметра, Значение_Параметра.
2) Таблица Current аналогичная первой, только без дат, обновление триггером, или пересчет по крону.
3) Таблицу с измерениями разбиваем по месяцам, engine=ARCHIVE
Ответ написан
Комментировать
pentarh
@pentarh
Трехмерная таблица а-ля Google BigTable
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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