- STORAGE_ANALYSIS.md: сравнение email.md / Maildir / MBOX / notmuch по 7 критериям; рекомендация — остаться на email.md + добавить tags в frontmatter + опциональный экспорт в Maildir - README.md: ссылка на анализ в разделе «Оценка альтернатив» - Данные не изменены (4884 email.md до и после)
9.6 KiB
Анализ хранения писем: Файловая система vs Maildir
Дата: 2026-09-11 Статус: Анализ (не миграция). Данные не изменены. Мотивация: использовать локальную нейросеть (Qwen3:8b, Ollama) как инструмент в обычных скриптах — без облака и трат.
TL;DR / Рекомендация
Остаться на текущем формате (email.md + YAML-frontmatter + SQLite FTS5).
Он полностью закрывает сценарий «локальная LLM из скриптов», которым мотивирован
выбор файлового хранения. Maildir даёт стандартность, но для LLM-анализа хуже
(нужен разбор MIME) и не поддерживает произвольные тэги.
Эволюция вместо миграции:
- Добавить
tags: []в frontmatter (для веб-UI «назначенные тэги») - Держать Maildir-совместимость как опцию экспорта (не как базовое хранение)
notmuch— опция позже, если FTS5 станет тесным
Факты по текущему архиву (замер 2026-09-11)
| Метрика | Значение |
|---|---|
| Всего email.md | 4884 |
| Объём | 76 МБ |
| INBOX (вкл. подпапки) | 2674 |
| Archive | 876 |
| Отправленные | 790 |
| Sent | 544 |
| Размер mail_index.db (FTS5) | 5.4 MB |
| Структура | /<folder>/YYYY/MM/UID/email.md |
Frontmatter (пример):
id: 4
folder: INBOX/!Отчеты
subject: "FW: Справка о статусах..."
from: "Головлев Алексей Вячеславович <a.golovlev@vinogorod.ru>"
to: "Рыбкин Валентин Станиславович <v.rybkin@vinogorod.ru>"
date: "2025-08-22 21:50+03:00"
flags: ["Seen"]
Плюс в части файлов: Message-ID, References, In-Reply-To, Content-Type.
Тело — в том же файле после ---.
Сравнение форматов
| Критерий | Текущий (email.md + FTS5) | Maildir | MBOX | notmuch |
|---|---|---|---|---|
| Пригодность для LLM-скриптов | ★★★★★ — cat email.md | ollama напрямую: frontmatter + тело |
★★☆ — raw-MIME, нужен парсер (mail/munpack) |
★★☆ — mbox, нужен разбор | ★★★★ — поиск готов, но тело в Maildir |
| Человекочитаемость | ★★★★★ — YAML + Markdown, grep/obsidian | ★★☆ — имена файлов нечитаемы, MIME | ★★☆ | ★★★ |
| Производительность инкр. чтения | ★★★★ — скан случайных UID-папок | ★★★★★ — число файлов в new/ = новых писем |
★★☆ — весь файл на перезапись | ★★★★★ |
| Атомарность / устойчивость | ★★★★ — новая папка на письмо (но без fsync) | ★★★★★ — tmp→new→cur, эталон | ★★☆ — блокировки, частичная запись | ★★★★ |
| Флаги (Seen/Answered) | ★★★ — в frontmatter | ★★★★★ — в имени файла :2,RS |
★★★ | ★★★★ |
| Произвольные тэги (для UI) | ★★★★★ — добавить tags: [] |
★★☆ — только флаги, тэгов нет | ★★☆ | ★★★★★ — core-фича |
| Стандарт / совместимость с MUA | ★★☆ — свой, MUA не читают | ★★★★★ — mutt/neomutt/thunderbird/dovecot | ★★★★★ — legacy | ★★★★ (поверх Maildir) |
| Масштабируемость (10k–100k) | ★★★★ — но много маленьких файлов | ★★★★★ | ★★☆ | ★★★★★ |
| Бэкапы (Yandex Disk / git) | ★★★★★ — простой копией/grep | ★★★★ — тысячи файлов | ★★★★ | ★★★ (нужен индекс) |
Детали по каждому подходу
Текущий формат email.md (выбран)
Плюсы:
- Идеален для локальной LLM:
cat email.md | ollama run qwen3:8b "резюмируй"— тело уже очищено от MIME, frontmatter даёт атрибуты для фильтрации в скрипте - Прозрачность:
grep,find,jq, Obsidian, VS Code - Атомарность записи:
mail_archive.pyсоздаёт новую папкуUID/, не трогая существующие письма → устойчиво к сбою в любой момент - Бэкап = копирование директории (Yandex Disk FUSE)
Минусы:
- Нестандартный: ни один MUA (mutt/thunderbird) не читает напрямую
- Флаги в frontmatter, не в ФС-атрибутах → медленнее для MUA
- Нет встроенной семантики целостности Maildir (fsync) — но для архива это ок
- Дублирование с FTS5-индексом (mail_index.db) — два источника правды
- 4884 файла = 4884 маленьких файла → фирменных лимитов на inode нет, но на сотнях тысяч лучше Maildir
Maildir
Плюсы:
- Стандарт де-факто: mutt, neomutt, thunderbird, dovecot читают
- Эталон атомарности:
tmp/→new/→cur/, флаги в имени файла - Новые письма = файлы в
new/→ быстрый инкрементальный скан (нет SQL) - Надёжность при сбое: никогда не частичного файла
Минусы (критично для нас):
- Тело в raw-MIME: для LLM-анализа нужен парсер (email.message, munpack).
У нас аналогично 2674 письма, но LLM должен читать frontmatter за
cat - Имена файлов нечитаемы (
1700000000.12345.host:2,S) — grep по теме невозможен - Нет произвольных тэгов — только Seen/Answered/Flagged/Deleted. Для «назначенных тэгов» в веб-UI пришлось бы вести отдельный индекс (notmuch/SQLite)
- Не человекочитаем в Obsidian
MBOX
Исключается сразу: один большой файл на папку, перезапись при любом изменении, блокировки, плохо для инкрементального чтения и бэкапов по частям. Для LLM и бэкапов на Yandex Disk — худший выбор.
notmuch (поверх Maildir или email.md)
Плюсы: полнотекстовый поиск с тэгами — идеален для UI-тэгов.
Минусы: это индексный слой, не хранилище. Требует демона/индекса,
дублирует то, что уже делает FTS5. Дисквалифицирует простоту grep.
Гибридный путь (рекомендация)
Сохранить текущий email.md как каноническое хранилище (источник правды),
но:
- Добавить
tags: []в frontmatter при записи (для UI) — тривиально вmail_archive.py - Экспорт в Maildir как опция (для чтения в mutt/thunderbird при желании), не зеркало в реальном времени — по запросу
- FTS5 остаётся поисковым индексом; при росте >50k писем — оценить notmuch
Это даёт: LLM-удобство (текущий), стандартную совместимость (опция экспорта), UI-тэги (frontmatter), поиск (FTS5). Без потери данных и без миграции.
Влияние на веб-интерфейс (задача 1)
Текущий формат уже содержит всё для UI-списка:
date→ дата письмаfrom→ адресантsubject→ тема- (новое)
tags→ назначенные тэги folder→ текущая папка (для перемещения:mail_archive.pyили прямойmv+ обновить frontmatter + FTS5)
Maildir не дал бы тэгов без отдельного индекса. Текущий формат — оптимален.
Вывод
Текущий подход (email.md + FTS5) удобнее Maildir для заявленной цели
(локальная LLM из скриптов без облака). Maildir выигрывает только в
«стандартной совместимости с MUA» и «инкрементном скане без БД» — что не
критично для нашего сценария. Рекомендуется остаться на текущем + добавить
tags в frontmatter + опциональный экспорт в Maildir.