Каков наиболее эффективный способ хранения измерений с переменным количеством полей в базе данных?

StackOverflow https://stackoverflow.com/questions/1629458

  •  06-07-2019
  •  | 
  •  

Вопрос

У нас есть система сбора данных, которая собирает измерения от датчиков окружающей среды, которые измеряют скорость воды, протекающей через реку или канал. Каждое измерение генерирует фиксированное количество значений (например, Дата, Время, Температура, Давление и т. Д.), А также список значений скорости.
Изначально датчики выдавали три значения скорости, поэтому я просто сохранял каждое значение в своем собственном столбце одной таблицы в базе данных FireBird. Позже был представлен датчик, который мог выдавать до девяти значений скорости, поэтому я просто добавил еще шесть столбцов. Несмотря на то, что большинство датчиков используют менее 9 значений, я решил, что это не будет проблемой, если в большинстве столбцов будут только нули.
Но теперь я сталкиваюсь с новым поколением, которое может выводить что угодно от 1 до 256 значений, и я предполагаю, что будет не очень эффективно добавить еще 247 столбцов, тем более что большинство измерений все равно будет содержать только от 3 до 9 значений. > Поскольку измерения собираются каждые 10 минут, а база данных содержит все данные от 30 до 50 датчиков, общий объем данных через несколько лет становится достаточно значительным, однако должна быть возможность создавать обзоры / графики для любого случайного периода времени.

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

Это было полезно?

Решение

Базы данных могут обрабатывать большие объемы данных в таблице, если вы используете эффективные индексы. Таким образом, вы можете использовать эту структуру таблицы:

create table measurements (
     id,
     seq integer, -- between 1 and 256
     ts timestamp, -- Timestamp of the measurement
     value decimal(...)
)

Создайте индекс для id , id, seq и ts . Это позволит вам эффективно осуществлять поиск по данным. Если вы не доверяете своей базе данных, просто вставьте несколько миллионов строк и выполните несколько операций выбора, чтобы увидеть, насколько хорошо она справляется.

Для сравнения: у меня есть база данных Oracle со 112 миллионами строк, и я могу выбрать запись по метке времени или идентификатору в течение 120 мс (0,12 с)

Другие советы

Вы можете сохранить сериализованные данные в текстовом поле, например, JSON-кодировку измерений как:

[<velocity-value-1>, <velocity-value-2>, ...]

Затем в вашем коде десериализуйте значения после запроса.

Это должно работать хорошо, если вы фильтруете свои запросы только по другим полям, а не по сохраненным значениям. Если вы выполните фильтрацию по значениям, использование их в предложениях WHERE станет кошмаром.

Я бы пошел со вторым столом:

table measurements (Id, DateTime, Temperature, Pressure)
table velocity (Id, MeasurementId, Sequence, Value)

Velocity.MeasurementId ссылается на Measurements.Id .
Velocity.Sequence - это индекс значения скорости для этого измерения (1-256).

Заполните эти таблицы данными, максимально приближенными к реальному, и протестируйте операторы sql, чтобы найти лучшие индексы.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top