From 04959583bb825f00acad4aa8095132e20b5d20b2 Mon Sep 17 00:00:00 2001 From: Alexandr Mansurov Date: Thu, 22 Jan 2026 00:48:39 +0100 Subject: [PATCH] Update README --- README.md | 62 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 728d7fc..ddc8d07 100644 --- a/README.md +++ b/README.md @@ -73,27 +73,38 @@ log_ingest --threads 1 --from 2026/01/01 --to 2026/01/31 ... ## Database Schema +The schema uses normalized lookup tables to minimize disk usage for large datasets. + ```sql +-- Lookup tables for low-cardinality text columns +CREATE TABLE apps (id INTEGER PRIMARY KEY, name TEXT NOT NULL UNIQUE); +CREATE TABLE versions (id INTEGER PRIMARY KEY, name TEXT NOT NULL UNIQUE); +CREATE TABLE models (id INTEGER PRIMARY KEY, name TEXT NOT NULL UNIQUE); +CREATE TABLE devices (id INTEGER PRIMARY KEY, name TEXT NOT NULL UNIQUE); +CREATE TABLE os_versions (id INTEGER PRIMARY KEY, name TEXT NOT NULL UNIQUE); +CREATE TABLE app_names (id INTEGER PRIMARY KEY, name TEXT NOT NULL UNIQUE); + +-- Main table with foreign keys and millisecond timestamp CREATE TABLE signature_entries ( - id INTEGER PRIMARY KEY AUTOINCREMENT, session_id TEXT NOT NULL, - timestamp TEXT NOT NULL, - app TEXT NOT NULL, - version TEXT NOT NULL, - offline_login_usage INTEGER NOT NULL, - is_password_autofill_enabled INTEGER NOT NULL, - camera_roll_usage INTEGER NOT NULL, - os TEXT NOT NULL, - app_name TEXT NOT NULL, - touch_id INTEGER NOT NULL, - is_offline_login_enabled INTEGER NOT NULL, - model TEXT NOT NULL, - device TEXT NOT NULL, - password_autofill_usage INTEGER NOT NULL -); + timestamp_ms INTEGER NOT NULL, -- Unix epoch milliseconds + app_id INTEGER NOT NULL REFERENCES apps(id), + version_id INTEGER NOT NULL REFERENCES versions(id), + offline_login_usage INTEGER, + is_password_autofill_enabled INTEGER, + camera_roll_usage INTEGER, + os_id INTEGER REFERENCES os_versions(id), + app_name_id INTEGER REFERENCES app_names(id), + touch_id INTEGER, + is_offline_login_enabled INTEGER, + model_id INTEGER REFERENCES models(id), + device_id INTEGER REFERENCES devices(id), + password_autofill_usage INTEGER, + PRIMARY KEY (session_id, timestamp_ms) +) WITHOUT ROWID; CREATE INDEX idx_session_id ON signature_entries(session_id); -CREATE INDEX idx_version ON signature_entries(version); +CREATE INDEX idx_version ON signature_entries(version_id); ``` ## Example Queries @@ -105,15 +116,24 @@ SELECT FROM signature_entries; -- Count by app version -SELECT version, COUNT(*) as cnt -FROM signature_entries -GROUP BY version +SELECT v.name as version, COUNT(*) as cnt +FROM signature_entries se +JOIN versions v ON se.version_id = v.id +GROUP BY v.name ORDER BY cnt DESC; -- Device breakdown -SELECT device, COUNT(*) as cnt +SELECT d.name as device, COUNT(*) as cnt +FROM signature_entries se +JOIN devices d ON se.device_id = d.id +GROUP BY d.name; + +-- Convert timestamp_ms to readable datetime +SELECT + datetime(timestamp_ms / 1000, 'unixepoch') as timestamp, + session_id FROM signature_entries -GROUP BY device; +LIMIT 10; ``` ## Development