Какой самый эффективный способ хранения измерений с переменным количеством полей в базе данных? - PullRequest
4 голосов
/ 27 октября 2009

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

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

Ответы [ 3 ]

4 голосов
/ 27 октября 2009

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

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 с)

0 голосов
/ 27 октября 2009

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

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

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

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

0 голосов
/ 27 октября 2009

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

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

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

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

...