Мне кажется, что этот вопрос не даст точного ответа, поскольку требует слишком сложного анализа и глубокого погружения в детали нашей системы.
Мы распределили сеть датчиков.Информация, собранная в одной базе данных и обработанная в дальнейшем.
Текущий дизайн БД состоит в том, чтобы разбивать одну огромную таблицу в месяц.Мы стараемся держать его на уровне 1 млрд. (Обычно 600–800 млн. Записей), поэтому скорость заполнения составляет 20–50 млн. Записей в день.
Сервер БД в настоящее время представляет собой MS SQL 2008 R2, но мы начали с 2005 года и выполняем обновлениево время разработки проекта.
В самой таблице содержатся поля SensorId, MessageTypeId, ReceiveDate и Data.Текущее решение состоит в том, чтобы сохранить данные датчика в поле данных (двоичные, 16-байтовой фиксированной длины) с частичным декодированием его типа и сохранить его в messageTypeId.
У нас есть другой тип сообщений, отправляемых датчиками (ток составляет около 200) и может быть дополнительно увеличено по требованию.
Основная обработка выполняется на сервере приложений, который извлекает записи по требованию (по типу, sensorId и диапазону дат), декодирует их и выполняет требуемую обработку.Для такого количества данных достаточно текущей скорости.
У нас есть запрос на увеличение емкости нашей системы в 10-20 раз, и мы беспокоимся, способно ли наше текущее решение к этому.
У нас естьтакже 2 идеи для «оптимизации» структуры, которые я хочу обсудить.
1 Данные датчика можно разбить на типы, для простоты я буду использовать 2 основных: данные уровня (значения) (аналоговые данные с диапазоном значенийзначения), данные состояния (фиксированное количество значений)
Таким образом, мы можем перестроить нашу таблицу в кучу маленьких, используя следующие правила:
для каждого значения фиксированного типа(тип состояния) создайте свою собственную таблицу с SensorId и ReceiveDate (поэтому мы избегаем типа хранилища и двоичного двоичного объекта), все зависимые (расширенные) состояния будут храниться в собственной таблице, аналогичной внешнему ключу, поэтому, если у нас есть State
со значениями A
и B
, и зависимые (или дополнительные) состояния для него 1
и 2
заканчиваются таблицами StateA_1
, StateA_2
, StateB_1
, StateB_2
.Таким образом, имя таблицы состоит из фиксированных состояний, которые оно представляет.
для каждой аналоговой информации, которую мы создаем в отдельной таблице, это будет аналог первого типа, но может содержать дополнительное поле со значением датчика;
Плюсы:
- Храните только необходимый объем данных (в настоящее время наш двоичный двоичный объект Data содержит пространство до самого длинного значения) и уменьшенный размер БД;
- Чтобы получить данные изДля конкретного типа мы получаем таблицу прав доступа вместо фильтра по типу;
Минусы:
- AFAIK, это нарушает рекомендуемые методы;
- Требуется разработка инфраструктуры дляавтоматизировать управление таблицами, так как администратор БД будет поддерживать его вручную;
- Количество таблиц может быть значительно большим, поскольку требуется полный охват возможных значений;
- Изменения схемы БД при введении новых данных датчикаили даже новое значение состояния для уже определенных состояний, таким образом, может потребовать комплексного изменения;
- Комплексное управление приводит к склонности к ошибкам;
- It может быть, черт возьми, движок БД для вставки значений в такую организацию таблицы?
- Структура БД не фиксирована (постоянно изменяется);
Вероятно, все минусы перевесят несколько плюсов, но если мы получим значительныйприрост производительности и / или (менее предпочтительный, но очень ценный) объем памяти, может быть, мы следуем этим путем.
2 Может быть, просто разделить таблицу на датчик (это будет около 100 000 таблиц) или лучше по диапазону датчика и / илипереходить на разные базы данных с выделенными серверами, но мы хотим избежать аппаратного промежутка, если это возможно.
3 Оставить как есть.
4 Переключиться на другой тип СУБД, например, СУБД, ориентированные на столбцы (HBase ипохоже).
Что ты думаешь?Может быть, вы можете предложить ресурс для дальнейшего чтения?
Обновление: Природа системы в том, что некоторые данные с датчиков могут поступать даже с месячной задержкой (обычно с задержкой в 1-2 недели), некоторые всегда подключены к сети, какой-то датчик имеет встроенную память и в конечном итоге подключается к сети. Каждое сообщение датчика имеет связанную дату события и дату получения сервером, поэтому мы можем отличить последние данные от собранных некоторое время назад. Обработка включает в себя некоторые статистические вычисления, определение отклонения параметров и т. Д. Мы создали сводные отчеты для быстрого просмотра, но когда мы получаем данные от обновлений датчиков, старые данные (уже обработанные), мы должны перестроить некоторые отчеты с нуля, поскольку они зависят от всех доступных данные и агрегированные значения не могут быть использованы. Таким образом, мы обычно храним данные за 3 месяца для быстрого доступа и другие данные в архиве. Мы изо всех сил стараемся сократить объем данных, необходимых для хранения данных, но решили, что нам нужно все это для обеспечения точности результатов.
Update2:
Здесь таблица с первичными данными. Как я упоминаю в комментариях, мы удаляем все зависимости и ограничения из него во время «потребности в скорости», поэтому он используется только для хранения.
CREATE TABLE [Messages](
[id] [bigint] IDENTITY(1,1) NOT NULL,
[sourceId] [int] NOT NULL,
[messageDate] [datetime] NOT NULL,
[serverDate] [datetime] NOT NULL,
[messageTypeId] [smallint] NOT NULL,
[data] [binary](16) NOT NULL
)
Пример данных с одного из серверов:
id sourceId messageDate serverDate messageTypeId data
1591363304 54 2010-11-20 04:45:36.813 2010-11-20 04:45:39.813 257 0x00000000000000D2ED6F42DDA2F24100
1588602646 195 2010-11-19 10:07:21.247 2010-11-19 10:08:05.993 258 0x02C4ADFB080000CFD6AC00FBFBFBFB4D
1588607651 195 2010-11-19 10:09:43.150 2010-11-19 10:09:43.150 258 0x02E4AD1B280000CCD2A9001B1B1B1B77