Base de datos
@aicore-fivem/mysql, tablas tipadas y ai-mysql para scripts de terceros.
AI Core tiene su propio motor de base de datos, @aicore-fivem/mysql. Cada recurso ai-* que usa la base de datos tiene un pequeño pool en su propio proceso (sin pasar por un export en cada consulta); ai-mysql sustituye a oxmysql, mysql-async y ghmattimysql para que los scripts de terceros conserven su API.
Tablas
Un recurso guarda sus tablas en sql/main.sql y las instala al iniciar:
createDatabaseTables(ResourceName, "sql/main.sql");Crea las tablas que faltan y añade las columnas que faltan; nunca borra ni cambia las existentes. Cada tabla lleva como prefijo el recurso (ai_<name>_...), tiene clave primaria y usa utf8mb4_unicode_ci.
Consultas
La compilación genera los tipos de fila (resource/server/tables.ts) a partir del SQL. Las consultas simples los usan:
export const db = tables<Tables, TableInserts>();
const rows = await db.select("ai_garages_vehicles", ["id", "plate"], { owner }, { limit: 50 });Los joins, rangos, upserts y sentencias masivas siguen siendo SQL normal con placeholders:
await mysql.query("UPDATE ai_x SET count = count - ? WHERE id = ? AND count >= ?", [n, id, n]);Reglas
- Placeholders para cada valor; identificadores solo de una lista fija.
- El dinero es un entero, las fechas y horas son
DATETIMEen UTC, los indicadores sonTINYINT(1). - Los datos del jugador se leen una vez al cargar y se mantienen en memoria; los valores frecuentes se escriben con un volcado periódico, los críticos (dinero, objetos) en una sola sentencia condicional o transacción.
- Las escrituras masivas son una sentencia por bloque, nunca una por fila.
- Cada recurso que usa la base de datos necesita
add_convar_permission <resource> read mysql_connection_stringenenv.cfg.