- tmp/research/fixtures.py собирает фикстуры из архива, вычищая измерения и сохраняя порядок ключей, форму литералов, выравнивание меток и невидимые символы; шесть фикстур в internal/hae/testdata - internal/canon — общий дом канонической формы, полноты и хеша: числа читаются литералом через json.Number, округление до 12 значащих цифр - internal/hae — разбор секции metrics, вывод слоя по метрике, разделение схем сна, координаты интервалом; recover внутри Parse, фаззинг - миграция bucket и docs/database.md
59 lines
3.6 KiB
SQL
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;
|