Фон
У меня есть сеть из примерно 2000 датчиков, каждый из которых имеет около 100 точек данных, которые мы собираем с 10-минутными интервалами. Эти точки данных обычно являются значениями типа int, но некоторые являются строками и числами с плавающей точкой. Эти данные должны храниться в течение 90 дней, больше, если это возможно, и все еще эффективно.
Дизайн базы данных
Когда мне изначально было поручено выполнение этого проекта, я написал приложение на C #, в котором файлы для каждого датчика были разделены запятыми. В то время было не так много, когда кто-то хотел посмотреть на тренды, мы открывали CSV-файл в Excel и отображали его по мере необходимости.
Все росло, и мы переключились на базу данных MySQL. Я создал таблицу для каждого датчика (да, я знаю, много таблиц!); это работало хорошо, но у него есть некоторые ограничения. С таким количеством таблиц, очевидно, невозможно написать запрос, который будет искать данные среди всех датчиков при поиске определенного значения.
В следующей версии я переключился на Microsoft SQL Server Express и поместил все данные датчиков в одну большую таблицу. Это также работает и позволяет нам выполнять запросы для поиска значений среди всех представляющих интерес датчиков. Однако я столкнулся с ограничением в 10 ГБ для версии Express и решил переключиться обратно на MySQL, а не инвестировать в SQL Server Standard.
Вопрос
Я доволен производительностью и масштабируемостью MySQL, но не уверен, что лучше придерживаться подхода «все данные в одной таблице». Кажется, 10 ГБ в одной таблице требуют другого дизайна. Я должен отметить, что необходимость запроса данных для построения графиков все еще существует, и я обеспокоен тем, что будут проблемы с производительностью для запроса, который отображает график, например, данные о температуре для одного датчика в течение полных 90 дней. (Другими словами, график должен быть чем-то, что можно быстро создать, не дожидаясь, пока SQL рассортирует кучу данных, просто чтобы изолировать интересующий датчик.)
Должен ли я каким-то образом разделить эту таблицу, чтобы повысить производительность? Или такой большой стол не является чем-то необычным?
У меня есть индексы для столбцов Sensor ID и Timestamp, которые в значительной степени определяют границы для любого запроса. (т.е. получить данные для датчика X от времени A до времени B).
Я прочитал немного о шардинге и разбиении, но не считаю, что они уместны в этом случае.
Редактировать:
На основании комментариев и ответов, некоторая дополнительная информация может быть полезна:
Не неопределенное хранение: в настоящее время я не храню данные за последние 90 дней. Ежедневно я запускаю запрос, который удаляет данные старше 90 дней. Если это станет важным в будущем, я буду хранить больше, но пока этого достаточно. Это помогает контролировать размер и высокую производительность.
Тип двигателя: оригинальная реализация MySQL использовала MyISAM. При создании таблиц на этот раз для новой реализации (одна таблица данных вместо многих) они по умолчанию использовали InnoDB. Я не верю, что у меня есть требование для одного или другого.
Нормализация: Есть, конечно, другие таблицы, кроме таблицы сбора данных. В этих таблицах поддержки хранятся такие данные, как информация о сети для датчиков, информация о входе в систему для пользователей и т. Д. Нормализировать особо нечего (насколько я знаю). Причина, по которой таблица данных имеет так много столбцов, состоит в том, что у каждого датчика столько переменных. (Несколько температур, уровень освещенности, давление воздуха и т. Д.) Нормализация для меня означает, что нет избыточных данных или повторяющихся групп. (По крайней мере, для 1NF.) Для данного датчика для хранения всех значений в определенное время требуется одна строка данных, и там нет взаимосвязей 1: N (что я вижу).
Я мог бы функционально разбить таблицу, сделав (например) все значения температуры в одной таблице, а все значения давления воздуха - в другой. Хотя это может повысить эффективность для тех, кто делает запрос только по температуре, мне все равно придется вставлять все данные одновременно. Тем не менее, повышение эффективности может быть полезным для операций SELECT. Очевидно, что лучше разбить таблицу по вертикали, исходя из того, как часто пользователи запрашивают данные. Возможно, это все, что я должен сделать. Я полагаю, что, задавая свой вопрос, я ищу подтверждение того, что это стоило бы.
Изменить 2:
Использование данных: В конечном счете, большая часть данных никогда не просматривается и не нужна, потому что мы обычно фокусируемся только на элементах с проблемами. Но, пытаясь найти проблемы, мы используем различные инструменты для поиска данных и определения того, какие элементы нужно увеличить.
Например, мы заметили корреляцию между значением использования памяти (запатентованная программа для конкретного клиента) и перезагрузкой / сбоем. Одна из точек данных, которые я собираю, связана с этим использованием памяти, и я смог просмотреть исторические данные, чтобы показать, что устройства становятся нестабильными после превышения определенного использования памяти. Сегодня для подмножества устройств, на которых запущено это программное обеспечение, я проверяю это значение и запускаю команду перезагрузки, если оно слишком велико. Пока это не было обнаружено, я не думал, что сбор этих данных имеет ценность.
По этой причине я утверждал, что около 100 точек данных будут собираться и храниться, даже если значение сомнительно. Но при обычном повседневном использовании пользователи обычно проверяют, возможно, дюжину этих параметров. Если пользователь интересуется определенной географической областью, он может (используя программное обеспечение) генерировать графики или электронные таблицы данных для, возможно, нескольких десятков датчиков. Нередко можно увидеть 30-дневный график с двумя или тремя линиями графика, показывающими такие вещи, как температура, давление воздуха и уровень освещенности. Выполнение этого запустит запрос, подобный следующему:
SELECT sensor_id, location, data_timestamp, temp1, air1, light1
FROM data
WHERE data_timestamp >= '2012-02-01'
AND sensor_id IN (1, 2, 3);
(В исходной версии MySQL, где у каждого датчика была своя собственная таблица, будут выдаваться три отдельных запроса, но результаты объединяются в программном обеспечении для создания графика.)
Поскольку data
таблица содержит так много строк (~ 10 миллионов), несмотря на наличие индексов id
и data_timestamp
, производительность заметно хуже, чем в сценарии с несколькими таблицами (4500 строк возвращаются за 9 секунд, а в этом примере - менее одной секунды). Возможность определить, какие датчики соответствуют определенным критериям, в схеме с несколькими таблицами практически равна нулю, и, следовательно, причина перехода к одной таблице.
Этот тип запроса может быть выполнен несколькими пользователями в быстрой последовательности, поскольку они выбирают различные группы данных и сравнивают графики для каждого результата. Это может быть довольно неприятно ждать около 10 секунд на график или таблицу.
Данные отбрасываются через 90 дней. Это могло быть заархивировано, но это не в настоящее время требование.
Надеемся, что эта информация поможет более адекватно показать, как данные используются после сбора и хранения.