Есть около 300 тыс объектов ( например легковых автомобилей) для каждого автомобиля раз в неделю производится замер параметров ( пробег, давление в шинах, количество топлива), параметров будет в районе 20 штук, нужно все это хранить в базе.
В освновном пользователей интерисуют только последние параметры. Но иногда необходимо отвечать на вопросы типа «А как менялось давление в шинах во времени», «А какие параметры менялись на прошлой неделе»
Интуиция говорит, что наверное надо смотреть в сторону mongo, но тех задание явно говорит, что будем использовать Mysql :)
При каждом изменении любого параметра, предыдущая версия записывается в data_history, у того параметра который изменился ставится влажок is_changed
2) Первая таблица (название data)
id| object_name
Вторая таблица ( хранит только последние значения)
id | object_id | param_name | param_value | date
Третья таблица ( хранит историю значений из второй таблицы)
Сейчас мы отслеживаем около 50 тыс объектов, в неделю происходит около 200 изменений в параметрах. Все параметры числовые, поэтому вопрос избыточности хранения в первом случае волнует только в плане производительности БД, но никак не места на диске. Второй метод вроде хорош, но его не очень просто реализовать используя ORM.
Ваше мнение? как спроектировать DB? как найти компромисс между эффективной БД и удобством написания приложения к ней.
Да is_changed нужно чтобы определить что изменилось, ведь машина могла стоять целый месяц в гараже давление в шинах у нее изменилось, а вот пробег нет.
Теперь я понял зачем вариант #2.
Я бы использовал именно его, и, скорее всего, даже объединил бы вторую и третью таблицу.
С выборкой, конечно, все не так просто и производительность пострадает, но мне кажется этот вариант красивей.
Вопрос к переформулированию постановки задачи, потому как по определению RRD означает деградацию детализации старых данных. Но зато куча плюшек — начиная от фиксированного размера базы, заканчивая массой готовых реализаций и визуализации.
Визуализация в «round-robin database» — лишь одна из плюшек. А так это — вполне себе DB для хранения подобных данных. Т.е. если Вы снимаете данные, к примеру, раз в день и Вас устраивает держать ежедневную информацию в течении года, а то что старше — держать среднее (или суммарное) за неделю, а старше трех лет — усреднять за месяц, то именно RRD — оптимальный вариант.
Не смотрите на RRD как на визуализатор. Просто для тех данных, что обычно в таких базах хранятся, обычно также нужна и визуализация. Но это только составляющая, а не основное назначение.
Сам использовал вариант 2.
Как не странно — очень часто выбрать правильное — не так уж и просто.
Долго парился с группами и правильными ордерами, чтобы выбирать последние данные кучи разнородного материала.
Кончилось тем что историю храню отдельно, а последний срез данных — отдельно.
Вообще никаких проблем, да и операции с главной базой стали проще и быстрее
Вообще натуральная модель, насколько я понимаю, будет такой:
Таблица 1. Vehicle (ID, Last Reading ID).
Таблица 2. Reading (ID, Vehicle ID, Date, и измеренные значения: Fuel, Oil, Tire Pressure, и т. д.).
Если она не устраивает по каким-то соображениям, тогда уже переходить к другим моделям. Пока что для меня, например, неочевидно преимущество хранения разнородных значений в одном поле. Да, это всё числа, но если вдруг добавится нечисловое значение, придётся существенно менять модель.
>Второй метод вроде хорош, но его не очень просто реализовать используя ORM.
дык, в mysql уже давно есть триггеры, емнип. организуйте сбор истории триггерами на insert/update/delete, а отображение истории можно уже крутить как угодно если плясать от отдельной таблицы (или вьюшки которая юнионов сошьет актуальные и архивные данные).
>(или вьюшки которая юнионом сошьет актуальные и архивные данные).
ай черт, не внимательно посмотрел на структуру таблиц. вычеркиваем вьюшки и юнионы :D
у меня, обычно, сохранялось соответствие объект — строка (проперти-колонки), с такой схемой было все просто. как жить с вашей схемой не знаю, колдовать с группировками/сортировками уж больно много надо
ORM не запрещает писать запросы. Это не ограничение, а дополнение.
Да, все сложнее, придется чуть-чуть подумать или посмотреть примеры, но я бы не сказал, что это сверхсложно.
1) Таблица с данными. Date, ID_объекта, ID_параметра, Значение_Параметра.
2) Таблица Current аналогичная первой, только без дат, обновление триггером, или пересчет по крону.
3) Таблицу с измерениями разбиваем по месяцам, engine=ARCHIVE