поменял все названия таблиц и полей в таблицах на стиль только маленькие буквы и разделение через "_"  . Все тесты проходят норм
This commit is contained in:
AidarKC
2026-01-06 01:49:26 +03:00
parent 93c007b2b9
commit 8fd7f4676b
16 changed files with 467 additions and 532 deletions
+188 -111
View File
@@ -1,132 +1,209 @@
1) Перечень таблиц и кратко о каждой
SHiNE — структура БД (актуальная версия)
solana_users — справочник пользователей: логин + ключ устройства + (опционально) Solana-ключ. База для FK почти во всех таблицах.
active_sessions — активные сессии авторизации/работы клиента: пароли сессии/хранилища, времена, push-данные, IP/инфо клиента.
users_params — “последние значения параметров” пользователя. Для каждого (login,param) хранится актуальная версия по time_ms (старые обновления игнорируются).
ip_geo_cache — кеш геолокации по IP, чтобы не дергать внешние сервисы постоянно.
blockchain_state — агрегатное состояние блокчейна по blockchainName: лимиты/размер, последний глобальный блок и последние блоки по линиям 0..7.
blocks — локальное хранилище блоков/сообщений: привязка к пользователю и блокчейну, номера/хэши, тип/подтип, тело блока (BLOB), и опциональная “ссылка на другой блок” через поля to*. (PK сейчас намеренно убран.)
2) Таблицы подробно: параметры по строкам
Перечень таблиц и назначение
solana_users
login — TEXT PK — уникальный логин пользователя.
deviceKey — TEXT NOT NULL — публичный ключ устройства (обычно Base64(32) или HEX(64)).
solanaKey — TEXT NULL — публичный ключ Solana-аккаунта (если используется).
Справочник пользователей: логин + ключ устройства + (опционально) Solana-ключ.
Базовая таблица, используется как FK почти везде.
active_sessions
sessionId — TEXT PK — идентификатор сессии (строка; по смыслу base64(32)).
login — TEXT NOT NULL, FK → solana_users(login) — владелец сессии.
sessionPwd — TEXT NOT NULL — пароль/секрет сессии (как хранится — строкой).
storagePwd — TEXT NOT NULL — пароль/секрет для storage (как хранится — строкой).
sessionCreatedAtMs — INTEGER NOT NULL — время создания сессии (Unix ms).
lastAuthirificatedAtMs — INTEGER NOT NULL — время последней авторизации/refresh (Unix ms).
pushEndpoint — TEXT NULL — endpoint для WebPush.
pushP256dhKey — TEXT NULL — p256dh ключ для WebPush.
pushAuthKey — TEXT NULL — auth ключ для WebPush.
clientIp — TEXT NULL — IP клиента на auth/refresh.
clientInfoFromClient — TEXT NULL — строка, присланная клиентом (PWA).
clientInfoFromRequest — TEXT NULL — строка, собранная сервером из запроса.
userLanguage — TEXT NULL — язык пользователя (например ru-RU).
Активные сессии авторизации/работы клиента: секреты, тайминги, WebPush-данные, IP и информация о клиенте.
users_params
login — TEXT NOT NULL, FK → solana_users(login) — владелец параметра.
param — TEXT NOT NULL — имя параметра (ключ).
time_ms — INTEGER NOT NULL — версия/время параметра (Unix ms), используется для “только если новее”.
value — TEXT NOT NULL — значение параметра.
device_key — TEXT NULL — каким ключом подписано (если используешь), строковый формат.
signature — TEXT NULL — подпись (если используешь), строковый формат.
Ограничение: UNIQUE(login, param) — один актуальный параметр на пару.
Хранилище актуальных параметров пользователя.
Для каждой пары (login, param) хранится только самая новая версия по time_ms.
ip_geo_cache
ip — TEXT PK — IP-адрес (строкой).
geo — TEXT NULL — гео-строка (Country/City или как договоритесь).
updated_at_ms — INTEGER NOT NULL — когда кеш обновлялся (Unix ms).
Кеш геолокации по IP для снижения нагрузки на внешние сервисы.
blockchain_state
blockchainName — TEXT PK — имя/ID блокчейна (уникальное).
login — TEXT NOT NULL, FK → solana_users(login) — владелец блокчейна.
blockchainKey — TEXT NOT NULL — публичный ключ блокчейна (по смыслу Base64(32)).
size_limit — INTEGER NOT NULL — лимит размера (по смыслу bytes; в Java это long).
file_size_bytes — INTEGER NOT NULL — текущий размер файла блокчейна в байтах.
last_global_number — INTEGER NOT NULL — последний глобальный номер блока (genesis = -1).
last_global_hash — TEXT NOT NULL — хэш последнего глобального блока (или пустая строка).
updated_at_ms — INTEGER NOT NULL — время обновления состояния (Unix ms).
Линии 0..7 (для каждой линии две колонки):
line0_last_number — INTEGER NOT NULL — последний номер в линии 0.
line0_last_hash — TEXT NOT NULL — последний хэш в линии 0.
line1_last_number — INTEGER NOT NULL — последний номер в линии 1.
line1_last_hash — TEXT NOT NULL — последний хэш в линии 1.
line2_last_number — INTEGER NOT NULL — последний номер в линии 2.
line2_last_hash — TEXT NOT NULL — последний хэш в линии 2.
line3_last_number — INTEGER NOT NULL — последний номер в линии 3.
line3_last_hash — TEXT NOT NULL — последний хэш в линии 3.
line4_last_number — INTEGER NOT NULL — последний номер в линии 4.
line4_last_hash — TEXT NOT NULL — последний хэш в линии 4.
line5_last_number — INTEGER NOT NULL — последний номер в линии 5.
line5_last_hash — TEXT NOT NULL — последний хэш в линии 5.
line6_last_number — INTEGER NOT NULL — последний номер в линии 6.
line6_last_hash — TEXT NOT NULL — последний хэш в линии 6.
line7_last_number — INTEGER NOT NULL — последний номер в линии 7.
line7_last_hash — TEXT NOT NULL — последний хэш в линии 7.
Агрегированное состояние блокчейна по blockchain_name:
лимиты, текущий размер, последний глобальный блок и состояние линий 0..7.
blocks
login — TEXT NOT NULL, FK → solana_users(login) — чей блок (логин).
bchName — TEXT NOT NULL, FK → blockchain_state(blockchainName) — к какому блокчейну относится блок.
blockGlobalNumber — INTEGER NOT NULL — глобальный номер блока.
blockGlobalPreHashe — TEXT NOT NULL — хэш предыдущего глобального блока.
blockLineIndex — INTEGER NOT NULL — индекс линии (0..7), по смыслу int16.
blockLineNumber — INTEGER NOT NULL — номер блока в линии.
blockLinePreHashe — TEXT NOT NULL — хэш предыдущего блока в линии.
msgType — INTEGER NOT NULL — общий тип сообщения/блока (по смыслу uint16).
msgSubType — INTEGER NOT NULL — подтип внутри msgType (по смыслу uint16).
blockByte — BLOB NULL — сырой байтовый блок/тело сообщения.
Ссылка на другой блок (nullable, для ответов/репостов/связей и т.п.):
to_login — TEXT NULL — логин “на кого/кому/с кем” (смысловая цель).
toBchName — TEXT NULL — целевой блокчейн.
toBlockGlobalNumber — INTEGER NULL — целевой глобальный номер.
toBlockHashe — TEXT NULL — хэш целевого блока.
Журнал всех блоков и сообщений.
Содержит историю событий: тексты, реакции, ответы, связи.
PRIMARY KEY намеренно отсутствует.
connections_state ⭐
Текущее состояние связей пользователя.
login — TEXT NOT NULL — владелец связи.
relType — INTEGER NOT NULL — тип связи:
10 = FRIEND, 20 = CONTACT, 30 = FOLLOW.
to_login — TEXT NOT NULL — с кем связь.
toBchName — TEXT NOT NULL — блокчейн цели.
toBlockGlobalNumber — INTEGER NULL — последний известный номер блока цели.
toBlockHashe — TEXT NULL — последний известный хэш блока цели.
Актуальное состояние связей между пользователями
(друг / контакт / подписка).
Обновляется автоматически на основе событий из blocks.
message_stats ⭐
Агрегированные счётчики лайков и ответов на конкретные сообщения.
Поддерживается триггерами из blocks.
Таблицы подробно
solana_users
login — TEXT PK — уникальный логин пользователя
device_key — TEXT NOT NULL — публичный ключ устройства (Base64(32) / HEX(64))
solana_key — TEXT NULL — публичный ключ Solana-аккаунта
active_sessions
session_id — TEXT PK — идентификатор сессии
login — TEXT NOT NULL, FK → solana_users(login)
session_pwd — TEXT NOT NULL — секрет сессии
storage_pwd — TEXT NOT NULL — секрет storage
session_created_at_ms — INTEGER NOT NULL
last_authirificated_at_ms — INTEGER NOT NULL
push_endpoint — TEXT NULL
push_p256dh_key — TEXT NULL
push_auth_key — TEXT NULL
client_ip — TEXT NULL
client_info_from_client — TEXT NULL
client_info_from_request — TEXT NULL
user_language — TEXT NULL
users_params
login — TEXT NOT NULL, FK → solana_users(login)
param — TEXT NOT NULL
time_ms — INTEGER NOT NULL
value — TEXT NOT NULL
device_key — TEXT NULL
signature — TEXT NULL
Ограничение:
UNIQUE(login, relType, to_login) — одно актуальное состояние связи.
UNIQUE(login, param)
3) Триггер логики связей
Логика:
обновление принимается только если excluded.time_ms > users_params.time_ms
Триггер trg_blocks_connection_state_ai срабатывает AFTER INSERT ON blocks:
если msgType = 3 (ConnectionBody)
msgSubType IN (10,20,30) →
добавить или обновить запись в connections_state
msgSubType IN (11,21,31) →
удалить соответствующую связь (10/20/30)
повторные добавления и удаления не вызывают ошибок
Таким образом:
ip_geo_cache
ip — TEXT PK
geo — TEXT NULL
updated_at_ms — INTEGER NOT NULL
blockchain_state
blockchain_name — TEXT PK
login — TEXT NOT NULL, FK → solana_users(login)
blockchain_key — TEXT NOT NULL
size_limit — INTEGER NOT NULL
file_size_bytes — INTEGER NOT NULL
last_global_number — INTEGER NOT NULL (-1 = genesis)
last_global_hash — TEXT NOT NULL
updated_at_ms — INTEGER NOT NULL
Линии 0..7:
для каждой линии:
lineX_last_number
lineX_last_hash
blocks
login — TEXT NOT NULL
bch_name — TEXT NOT NULL
block_global_number — INTEGER NOT NULL
block_global_pre_hash — TEXT NOT NULL
block_line_index — INTEGER NOT NULL
block_line_number — INTEGER NOT NULL
block_line_pre_hash — TEXT NOT NULL
msg_type — INTEGER NOT NULL
msg_sub_type — INTEGER NOT NULL
block_bytes — BLOB NULL
Ссылка на другой блок (nullable):
to_login
to_bch_name
to_block_global_number
to_block_hash
connections_state ⭐
Текущее агрегированное состояние связей.
login — TEXT NOT NULL
rel_type — INTEGER NOT NULL
10 = FRIEND
20 = CONTACT
30 = FOLLOW
to_login — TEXT NOT NULL
to_bch_name — TEXT NOT NULL
to_block_global_number — INTEGER NULL
to_block_hash — TEXT NULL
Ограничение:
UNIQUE(login, rel_type, to_login)
message_stats ⭐
Счётчики активности по целевому сообщению.
to_login — TEXT NOT NULL
to_bch_name — TEXT NOT NULL
to_block_global_number — INTEGER NOT NULL
to_block_hash — TEXT NOT NULL
likes_count — INTEGER NOT NULL DEFAULT 0
replies_count — INTEGER NOT NULL DEFAULT 0
UNIQUE:
(to_login, to_bch_name, to_block_global_number, to_block_hash)
Триггеры БД (полная логика)
3.1 Связи пользователей
trg_blocks_connection_state_ai
AFTER INSERT ON blocks
Условие:
msg_type = 3 (connection)
Добавление / обновление связи
msg_sub_type IN (10,20,30)
выполняется UPSERT в connections_state
Удаление связи
msg_sub_type IN (11,21,31)
удаляется соответствующая связь:
11 → 10
21 → 20
31 → 30
Итог:
blocks — журнал событий
connections_state — всегда актуальное состояние
Индексы (кратко, чтобы было понятно зачем)
idx_solana_users_login(login) — быстрый поиск по логину.
idx_active_sessions_login(login) — быстро получить сессии пользователя.
idx_users_params_login(login) — быстро получить параметры пользователя.
idx_ip_geo_cache_updated_at(updated_at_ms) — чистка старых записей.
idx_blockchain_state_login(login) — блокчейны пользователя.
idx_blockchain_state_updated_at(updated_at_ms) — выборки/обслуживание по “свежести”.
idx_blocks_chain_global(login,bchName,blockGlobalNumber) — выборки блоков по цепочке.
idx_blocks_to_target(to_login,toBchName,toBlockGlobalNumber) — быстрые выборки “по ссылке”.
3.2 Подсчёт лайков ⭐
trg_blocks_message_stats_like_ai
AFTER INSERT ON blocks
Условие:
msg_type = 2 (reaction)
msg_sub_type = 1 (like)
Действие:
определяется цель по to_bch_name, to_block_global_number, to_block_hash
to_login вычисляется как
substr(to_bch_name, 1, length(to_bch_name) - 3)
выполняется UPSERT в message_stats
likes_count += 1
3.3 Подсчёт ответов ⭐
trg_blocks_message_stats_reply_ai
AFTER INSERT ON blocks
Условие:
msg_type = 1 (text)
msg_sub_type = 2 (reply)
Действие:
цель определяется аналогично лайкам
выполняется UPSERT в message_stats
replies_count += 1
Индексы (смысл)
idx_solana_users_login — поиск пользователя
idx_active_sessions_login — сессии пользователя
idx_users_params_login — параметры пользователя
idx_ip_geo_cache_updated_at — чистка кеша
idx_blockchain_state_login — блокчейны пользователя
idx_blockchain_state_updated_at — обслуживание
idx_blocks_chain_global — чтение цепочки
idx_blocks_to_target — реакции / ответы
idx_message_stats_target — быстрый доступ к счётчикам
Итоговая модель мышления
blocks — неизменяемый журнал событий
connections_state — проекция связей
message_stats — проекция активности
всё вычисляется детерминированно через триггеры