4.2.1.2.1.4.1. Общий формат записи в базе данных и оценка её размера
Во фрагментах данных записи упорядочиваются в порядке возрастания совместного ключа <ItemKey, Timestamp>, что позволяет сократить объём служебной индексной информации. С этой целью последовательности записей хранятся следующим образом:
Последовательность записей разбивается на блоки размера ~4 КБ
В начале блока сохраняется опорная запись в полном формате
Далее, до начала следующего блока следуют записи в разностном формате
Полный формат записи
Descriptor ItemKey Timestamp FormatKey BodySize Body
Здесь:
Descriptor - служебная информация о записи, 1 байт
ItemKey - внутренний ключ элемента, временному ряду которого принадлежит запись, 4 байта
Timestamp - метка времени, 8 байт
FormatKey - ключ формата записи, 4 байта, на данный момент не используется, всегда сохраняется значение 0
BodySize - размер тела записи, 2 байта
Body - тело записи, которое зависит от источника, сохранившего её в базу данных, размер содержится в поле BodySize (в байтах)
Таким образом, совокупный размер служебной и индексной информации в полном формате (все поля, кроме тела записи Body) составляет 19 байт.
|
Разностный формат записи
В разностном формате запись сохраняется следующим образом:
Если поле ItemKey имеет то же значение, что и для предыдущей записи, оно не сохраняется
Если поле BodySize имеет то же значение, что и для предыдущей записи, оно не сохраняется
Поле FormatKey не сохраняется (т.к. сейчас всегда содержит значение 0)
Поле Timestamp: сохраняются только младшие байты, отличающиеся от соответствующих байтов значения поля предыдущей записи
Таким образом, если последующая запись принадлежит тому же элементу (ItemKey), имеет тот же размер тела (BodySize), то её размер сокращается на 10 байт (за счёт исключения полей ItemKey, FormatKey и BodySize).
Дополнительно размер записи уменьшается за счёт сокращения метки времени в зависимости от разницы значения поля Timestamp по отношению к соответствующему значению предыдущей записи. Поскольку используется точность хранения метки времени 1 миллисекунда, сокращение может быть следующим:
|
Разница, в мс
|
Примерная разница в с/мин/ч/д
|
Размер сохраняемой
метки времени,
байт
|
Сокращение метки времени,
байт
|
Общее сокращение служебной и индексной
информации,
байт
|
|
< 256
|
< ~0.25 с
|
1
|
7
|
17
|
|
< 65636
|
< ~1 мин
|
2
|
6
|
16
|
|
< 16777216
|
< ~4.6 ч
|
3
|
5
|
15
|
|
< 4294967296*
|
< ~49.7 д
|
4
|
4
|
14
|
Строка * и дальнейшие возможные значения для миллисекундной точности не имеют практического значения, т.к. в базе данных используется посуточная фрагментация.
Наибольший эффект описанной техники сокращения размера будет для элементов, записи по которым:
Имеют одинаковый фиксированный небольшой размер
Сохраняются с достаточно высокой интенсивностью
Пример
Если тело записи имеет размер 9 байт (значения типа int4/uint4/float в истории значений), записи сохраняются с частотой ~1 раз в минуту, то:
Размер опорной записи блока - 19 + 9 = 28 байт
Размер последующих разностных записей - 3 + 9 = 12 байт
Примерное число записей в 4-килобайтном блоке - ~340 - Доля опорной записи в размере блока: ~0.007 (< 1%)
|
В таблице ниже приведены оценки размеров записей истории значений, сохраняемые Модулем Истории, в зависимости от частоты сохранения:
|
Тип сигнала
|
Размер тела записи
|
Средний размер при сохранении с периодом ~250 мс
|
С периодом ~250 мс
|
С периодом ~4 часа
|
|
bool
|
5
|
7
|
8
|
9
|
|
int1/uint1
|
6
|
8
|
9
|
10
|
|
int2/uint2
|
7
|
9
|
10
|
11
|
|
int4/uint4
|
9
|
11
|
12
|
13
|
|
int8/uint8
|
13
|
15
|
16
|
17
|
|
float
|
9
|
11
|
12
|
13
|
|
double
|
13
|
15
|
16
|
17
|
|
string
|
9 + StringBody*
|
15 + StringBody*
|
16 + StringBody*
|
17 + StringBody*
|
*StringBody - тело строки длины N, которое хранится в формате UTF-8; размер в батайх зависит от используемых в строке символов.