База данных
@aicore-fivem/mysql, типизированные таблицы и ai-mysql для сторонних скриптов.
У AI Core собственный движок базы данных, @aicore-fivem/mysql. Каждый ресурс ai-*, который использует базу, держит небольшой пул в своём процессе (без перехода через экспорт на каждый запрос); ai-mysql заменяет oxmysql, mysql-async и ghmattimysql, чтобы сторонние скрипты сохранили свой API.
Таблицы
Ресурс хранит свои таблицы в sql/main.sql и устанавливает их при старте:
createDatabaseTables(ResourceName, "sql/main.sql");Он создаёт недостающие таблицы и добавляет недостающие столбцы; существующие он никогда не удаляет и не меняет. У каждой таблицы есть префикс ресурса (ai_<name>_...) и первичный ключ, и каждая использует utf8mb4_unicode_ci.
Запросы
Сборка генерирует из SQL типы строк (resource/server/tables.ts). Простые запросы используют их:
export const db = tables<Tables, TableInserts>();
const rows = await db.select("ai_garages_vehicles", ["id", "plate"], { owner }, { limit: 50 });JOIN, диапазоны, upsert и массовые операции остаются обычным SQL с плейсхолдерами:
await mysql.query("UPDATE ai_x SET count = count - ? WHERE id = ? AND count >= ?", [n, id, n]);Правила
- Плейсхолдеры для каждого значения; идентификаторы только из фиксированного списка.
- Деньги хранятся целым числом, время в UTC
DATETIME, флаги вTINYINT(1). - Данные игрока читаются один раз при загрузке и хранятся в памяти; частые значения записываются периодическим сбросом, критичные (деньги, предметы) одним условным запросом или транзакцией.
- Массовая запись идёт одним запросом на порцию, никогда по запросу на строку.
- Каждому ресурсу, который использует базу, нужна строка
add_convar_permission <resource> read mysql_connection_stringвenv.cfg.