Еще одна база данных TimeSeries — это экспериментальная база данных временных рядов, вдохновленная InfluxDb и RavenDB .
YATsDb реализован на чистом .NET и современном C# с высокой производительностью (около 30 тыс. вставок в секунду на процессоре Intel i7-8550U, 1,80 ГГц, 24 ГБ ОЗУ, SSD - вставка строк по одной).
Мне нужна была база данных временных рядов для домашних IoT-проектов, но использовать InfluxDb было бы скучно. Реализация прототипа, умевшего вводить данные и делать запросы, заняла всего 12 часов.
YATsDb — это полная реализация базы данных с графическим интерфейсом пользователя, определениями OpenAPI и заданиями. Для запуска требуется среда выполнения .NET 8.
YATsDb.Lite — это скомпилированная версия AOT с основными функциями базы данных временных рядов. Он не зависит от целевых систем.
Полученный двоичный файл имеет относительно небольшой размер <15 МБ .
Ниже приведен пример использования YATsDb/YATsDb.Litle с использованием cURL ( YATsDb также предоставляет определение конечной точки OpenAPI).
В примерах базовый URL-адрес — http://localhost:8080/.
Создайте новую корзину smart_home
:
curl -XPOST http://localhost:8080/management/bucket --header " Content-Type: application/json " --data-binary " { " bucketName " : " smart_home " , " description " : null} "
Введите образцы данных в простом формате строки ( <measurement>[,<tag>] <value>[,<value>...n] [<timestampInMs>]
), этот формат основан на InfluxDb , но не использует именованные значения. , а позиционные значения. Кроме того, до InfluxDb в качестве времени всегда используется временная метка unix в миллисекундах.
Следующие примеры данных представляют собой данные домашних измерений датчиков — температуры, влажности, интенсивности света.
curl -XPOST http://localhost:8080/write/smart_home --data-binary " sensors_data,Room1 22.0,45,80.4 1719242779202 "
curl -XPOST http://localhost:8080/write/smart_home --data-binary " sensors_data,Room1 23.1,39.4,75.0 1719243079200 "
curl -XPOST http://localhost:8080/write/smart_home --data-binary " sensors_data,Room1 23.2,41.7,NULL 1719243379246 "
curl -XPOST http://localhost:8080/write/smart_home --data-binary " sensors_data,Room2 23.0,41,80.4 1719243379256 "
curl -XPOST http://localhost:8080/write/smart_home --data-binary " sensors_data,Room1 22.0,45,80.4 1719243679194 "
curl -XPOST http://localhost:8080/write/smart_home --data-binary " sensors_data,Room2 22.7,47.4,NULL 1719243979257 "
curl -XPOST http://localhost:8080/write/smart_home --data-binary " sensors_data,Room1 22.1,47,NULL 1719244279035 "
curl -XPOST http://localhost:8080/write/smart_home --data-binary " sensors_data,Room3 18.7,NULL,NULL 1719244579031 "
curl -XPOST http://localhost:8080/write/smart_home --data-binary " sensors_data,Room1 24.7,51.7,2.4 1719244879109 "
Можно отправить несколько строк в одном сообщении, но не каждая оболочка это поддерживает.
curl -XPOST http://localhost:8080/write/smart_home --data-binary " sensors_data,Room1 24.7,51.7,2.4 1719244879109
sensors_data,Room1 24.8,55.7,3.9 1719244899109 "
YATsDb позволяет выполнять запросы с синтаксисом, напоминающим SQL, но вместо имен использует позиции значений. Результатом запроса является результат JSON.
Выберите данные о влажности из Комнаты 2 старше 12 часов:
curl -XPOST http://localhost:8080/query/raw/smart_home --data-binary " SELECT AVG(1), MIN(1), MAX(1), COUNT(1) FROM sensors_data WHERE TAG('Room2') AND INTERVAL(NULL, -10h) GROUP BY +10m "
Полная грамматика для вставки данных — простой линейный протокол:
<lines> ::= <line> [ [r]n...n ]
<line> ::= <measurement> <values> [<timestamp>]
<measurement> ::= measurement_name [, tag]
<values> ::= <value> [, ...250]
<value> ::={ double_value | NULL }
<timestamp> ::= unix timestamp in milliseconds
Размер без бирки:
sensors_data 12.5 1608852317000
Измерение с биркой:
sensors_data,home/room3/esp32 12.5 1608852317000
Измерение с несколькими значениями:
sensors_data,home/room3/esp32 12.5,-14.3,89,47.0036 1608852317000
Измерение с отсутствующими значениями (используйте NULL
для отсутствующего значения):
sensors_data,home/room4/esp32 12.5,NULL,89,47.0036 1608852317000
Измерение без метки времени unix — используется текущее время сервера:
sensors_data,home/room3/esp32 12.5
Многострочные значения:
sensors_data,home/room3/esp32 12.5 1608852317000
pc_data,Workstation1 25.78,47.5,236566 1608852317900
sensors_data,home/room3/esp32 13.5 1608852417000
Полная грамматика для запроса данных:
<SELECT statement> ::= SELECT <projection statement> FROM measurement_name
[<WHERE statement>]
[<GROUPBY statement>]
[<LIMIT statement>]
<projection statement> ::= { * | <projection> [ ,...250 ]}
<projection> ::= <projection function>(<index>)
<projection function> ::= { VARIANCE | SUM | COUNT | AVG | IDENTITY | MAX | MIN | STDDEV | REMEDIAN | SIGN | CHANGE_PER_SEC | CHANGE_PER_HOUR | CHANGE_PER_DAY }
<index> ::= integer_number
<WHERE statement> ::= WHERE <where function> [AND ...n]
<where function> ::= { TAG(<string>) | INTERVAL(<interval exp>, <interval exp>) }
<string> ::= string
<interval exp> ::= { integer_number | <time span> | <string> | NOW() }
<time span> ::= { + | - }double_value{ ms | s | m | h | d | w | y }
<GROUPBY statement> ::= GROUP BY <time span>
<LIMIT statement> ::= LIMIT { integer_number | integer_number, integer_number | ..integer_number }
Выбрать все данные:
SELECT * FROM sensors_data
Выберите первые 5 записей из Room3 :
SELECT * FROM sensors_data WHERE TAG('Room3') LIMIT 0,5
Выберите группу данных температуры с точностью до 10 минут:
SELECT AVG(0), MIN(0), MAX(0) FROM sensors_data GROUP BY +10m
Выберите данные о влажности из Room2 :
SELECT AVG(1), MIN(1), MAX(1), COUNT(1) FROM sensors_data WHERE TAG('Room2') GROUP BY +1d
Выберите данные о влажности из Комнаты 2 старше 12 часов:
SELECT AVG(1), MIN(1), MAX(1), COUNT(1) FROM sensors_data WHERE TAG('Room2') AND INTERVAL(NULL, -12h) GROUP BY +10m
Выбрать последнюю запись:
SELECT * FROM sensors_data LIMIT ..1
Сгруппируйте все данные:
SELECT AVG(0), AVG(1), AVG(2) FROM sensors_data
Выберите по конкретному времени (используя временную метку unix в миллисекундах):
SELECT AVG(0), COUNT(0) FROM sensors_data WHERE INTERVAL(1603519860000, 1608852317000) GROUP BY +10m
Выберите по конкретному времени (используя удобочитаемое время):
SELECT AVG(0), COUNT(0) FROM sensors_data WHERE INTERVAL('2012-06-12 08:33:12.478', '2012-06-13') GROUP BY +10m