разбор метрик HAE: фикстуры, канонизация, парсер
- tmp/research/fixtures.py собирает фикстуры из архива, вычищая измерения и сохраняя порядок ключей, форму литералов, выравнивание меток и невидимые символы; шесть фикстур в internal/hae/testdata - internal/canon — общий дом канонической формы, полноты и хеша: числа читаются литералом через json.Number, округление до 12 значащих цифр - internal/hae — разбор секции metrics, вывод слоя по метрике, разделение схем сна, координаты интервалом; recover внутри Parse, фаззинг - миграция bucket и docs/database.md
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
-- +goose Up
|
||||
-- Часовой объект — единица хранения разобранных точек. Строка на точку дала бы
|
||||
-- десятки миллионов строк в год; час даёт ~260 тысяч на слой независимо от
|
||||
-- плотности потока.
|
||||
--
|
||||
-- Внутрь payload средствами SQL не заглянуть — это осознанная плата. Границы
|
||||
-- содержимого и счётчик вынесены колонками, чтобы каталог разрезов не разжимал
|
||||
-- каждый блоб ради диапазона.
|
||||
CREATE TABLE bucket (
|
||||
metric TEXT NOT NULL,
|
||||
-- Слой выводится из выравнивания меток, а не из заголовка доставки:
|
||||
-- sample / raw / minute / hour / day.
|
||||
layer TEXT NOT NULL,
|
||||
-- Начало часа в UTC, RFC 3339. Час берётся по НАЧАЛУ точки: интервал
|
||||
-- пересекает границы часов, и любой другой выбор сделал бы принадлежность
|
||||
-- объекту зависящей от длительности.
|
||||
hour_utc TEXT NOT NULL,
|
||||
|
||||
-- Единицы измерения живут на уровне метрики, внутри точки их нет (проверено
|
||||
-- на 89 доставках: поле units не встретилось ни разу). Без этой колонки
|
||||
-- единицы метрики, переставшей приходить, теряются навсегда.
|
||||
units TEXT NOT NULL DEFAULT '',
|
||||
|
||||
-- Точки часа: JSON-массив исходных байтов точек, сжатый gzip. Точки
|
||||
-- упорядочены по времени начала.
|
||||
payload BLOB NOT NULL,
|
||||
-- Хеш канонической формы содержимого: детектор изменений, а не ключ.
|
||||
-- Совпал — записи не происходит, и широкие проходы синхронизации
|
||||
-- обходятся даром.
|
||||
content_hash TEXT NOT NULL,
|
||||
|
||||
points INTEGER NOT NULL DEFAULT 0,
|
||||
-- Границы содержимого: первая и последняя метка начала, UTC RFC 3339.
|
||||
first_ts TEXT NOT NULL,
|
||||
last_ts TEXT NOT NULL,
|
||||
|
||||
-- Провенанс: доставка, создавшая объект. Нужен, чтобы разбирать слияния;
|
||||
-- у отдельной точки провенанса нет и не будет.
|
||||
first_delivery_id TEXT NOT NULL DEFAULT '',
|
||||
|
||||
-- Час, в который досчёт уже не ожидается. Правило перевода в sealed пока
|
||||
-- не определено — порог ставится по наблюдениям, которых нет; до тех пор
|
||||
-- признак остаётся невыставленным.
|
||||
sealed INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL,
|
||||
|
||||
PRIMARY KEY (metric, layer, hour_utc)
|
||||
) WITHOUT ROWID;
|
||||
|
||||
-- Каталог разрезов и Read API ходят «дай метрику за период»: метрика и слой
|
||||
-- уже в первичном ключе, но выборка по времени поверх всех метрик нужна
|
||||
-- ретеншену и проверке сходимости.
|
||||
CREATE INDEX bucket_hour_utc ON bucket (hour_utc);
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE bucket;
|
||||
Reference in New Issue
Block a user