← Усі статті

Як стиснути словник з 3 ГБ SQLite до ~10 МБ: FST замість бази

Кейс tsk: finite state transducer у Rust, спільні суфікси фінської мови і чому FTS у SQLite був тимчасовим рішенням.

Як стиснути словник з 3 ГБ SQLite до ~10 МБ: FST замість бази
Зміст

Коротко

Розробник словника tsk замінив 3 ГБ SQLite на бінарник FST (finite state transducer) розміром порядку 10 МБ — приблизно в 300 разів менше на диску. Історія про те, що вибір структури даних важливіший за «просто підключити базу».

Що сталося

Проєкт — мобільний словник (фінсько-англійський). Спочатку пошук за префіксом будували на trie в пам’яті: для простих мов працювало, для фінської з багатою флексією — ні.

Тимчасовим рішенням став SQLite з повнотекстовим пошуком (FTS). Плюси: швидко впровадити, знайомий SQL. Мінуси: користувачам доводилося качати гігабайти даних — неприйнятно для слабких пристроїв.

Наступний крок — Rust і FST: автомат, який компактно кодує словник, використовуючи спільні суфікси та повторювані частини форм. Замість «плоского» масиву рядків структура стискає лексикон так, як це роблять морфологічні словники.

Підсумкова лінійка tsk v2 — порядку 20 МБ на диску замість багатогігабайтного дампу, із збереженням потрібного пошуку.

Чому це важливо

Не кожна задача «пошуку за словами» = SQLite чи Elasticsearch. Коли дані статичні, добре структуровані і читаються цілком у пам’ять або з диска одним шматком, спеціалізовані структури (trie, FST, суфіксні масиви) часто перемагають універсальну БД за розміром і латентністю.

Уроки для бекенду та тулінгу:

  • FTS у SQLite — відмінний прототип, поганий фінальний формат дистрибутива, якщо вага критична.
  • Морфологія та аглютинація ламають наївний trie; потрібні структури з урахуванням спільних закінчень.
  • Rust + нативні crate’и під FST — практичний шлях, якщо команда готова вийти за межі «все в Postgres».

На практиці

Якщо у вас схожа задача (глосарій, підказки, автодоповнення по статичному корпусу):

  1. Оцініть розмір дистрибутива так само суворо, як latency API.
  2. Прототипуйте на SQLite/Postgres, але закладіть експорт у read-only бінарник для продакшену.
  3. Подивіться FST / double-array trie і готові бібліотеки в екосистемі вашої мови.
  4. Заміряйте пам’ять на цільовому пристрої, а не лише на dev-машині.

Для веб-застосунків із частими оновленнями корпусу FST складніше інкрементувати — цей кейс про рідко оновлюваний словник.

Підсумок

Заміна SQLite на FST — не магія Rust, а правильна модель даних під домен: статичний словник, префіксний пошук, мінімальна вага. Має сенс читати оригінал, якщо проєктуєте власні довідники, підказки або офлайн-корпуси — особливо з багатою морфологією.