Banco de dados
@aicore-fivem/mysql, tabelas tipadas e ai-mysql para scripts de terceiros.
O AI Core tem seu próprio motor de banco de dados, o @aicore-fivem/mysql. Cada recurso ai-* que usa o banco de dados roda um pequeno pool no seu próprio processo (sem salto por export a cada consulta); o ai-mysql substitui o oxmysql, o mysql-async e o ghmattimysql, então scripts de terceiros mantêm sua API.
Tabelas
Um recurso guarda suas tabelas em sql/main.sql e as instala na inicialização:
createDatabaseTables(ResourceName, "sql/main.sql");Ele cria as tabelas que faltam e adiciona as colunas que faltam; nunca apaga nem altera as existentes. Cada tabela tem o prefixo do recurso (ai_<name>_...), uma chave primária e usa utf8mb4_unicode_ci.
Consultas
O build gera tipos de linha tipados (resource/server/tables.ts) a partir do SQL. As consultas simples os usam:
export const db = tables<Tables, TableInserts>();
const rows = await db.select("ai_garages_vehicles", ["id", "plate"], { owner }, { limit: 50 });Joins, intervalos, upserts e instruções em massa continuam em SQL puro com placeholders:
await mysql.query("UPDATE ai_x SET count = count - ? WHERE id = ? AND count >= ?", [n, id, n]);Regras
- Placeholders para cada valor; identificadores só de uma lista fixa.
- Dinheiro é um inteiro, horários são
DATETIMEem UTC, flags sãoTINYINT(1). - Os dados do jogador são lidos uma vez no carregamento e mantidos na memória; valores frequentes são gravados por um flush periódico, os críticos (dinheiro, itens) em uma única instrução condicional ou transação.
- Gravações em massa são uma instrução por lote, nunca uma por linha.
- Cada recurso que usa o banco de dados precisa de
add_convar_permission <resource> read mysql_connection_stringnoenv.cfg.