Files
healthlog/internal/store/migrations/00003_bucket.sql
T
av 01d0de59df разбор метрик HAE: фикстуры, канонизация, парсер
- tmp/research/fixtures.py собирает фикстуры из архива, вычищая измерения и
  сохраняя порядок ключей, форму литералов, выравнивание меток и невидимые
  символы; шесть фикстур в internal/hae/testdata
- internal/canon — общий дом канонической формы, полноты и хеша: числа читаются
  литералом через json.Number, округление до 12 значащих цифр
- internal/hae — разбор секции metrics, вывод слоя по метрике, разделение схем
  сна, координаты интервалом; recover внутри Parse, фаззинг
- миграция bucket и docs/database.md
2026-08-01 17:31:41 +03:00

59 lines
3.6 KiB
SQL

-- +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;