Продвинутая работа с MySQL в Pawn

Активный
Статус
Сообщения
516
Лайки
32

8

месяц на сайте

MySQL позволяет хранить данные надежно. Разберем продвинутые техники.

Транзакции
Код:
StartTransaction()
{
    mysql_query(g_SQL, "START TRANSACTION");
}

CommitTransaction()
{
    mysql_query(g_SQL, "COMMIT");
}

RollbackTransaction()
{
    mysql_query(g_SQL, "ROLLBACK");
}

// Использование
SavePlayerDataTransaction(playerid)
{
    StartTransaction();
    
    new query[256], name[MAX_PLAYER_NAME];
    GetPlayerName(playerid, name, sizeof(name));
    
    format(query, sizeof(query), "UPDATE players SET money = %d WHERE name = '%e'", 
        GetPlayerMoney(playerid), name);
    mysql_query(g_SQL, query);
    
    format(query, sizeof(query), "UPDATE players SET level = %d WHERE name = '%e'", 
        PlayerInfo[playerid][pLevel], name);
    mysql_query(g_SQL, query);
    
    if(mysql_errno(g_SQL) == 0)
    {
        CommitTransaction();
    }
    else
    {
        RollbackTransaction();
    }
}

Подготовленные запросы
Код:
// Кеширование подготовленных запросов
new Cache:playerDataCache;

public OnGameModeInit()
{
    playerDataCache = mysql_prepare(g_SQL, 
        "SELECT * FROM players WHERE name = ?");
    return 1;
}

LoadPlayerDataPrepared(playerid)
{
    new name[MAX_PLAYER_NAME];
    GetPlayerName(playerid, name, sizeof(name));
    
    mysql_bind(playerDataCache, 0, name);
    mysql_execute(playerDataCache, "OnPlayerDataLoaded", "i", playerid);
}

Пакетные запросы
Код:
SaveAllPlayersData()
{
    new query[512] = "INSERT INTO players (name, money, level) VALUES ";
    new count = 0;
    new first = 1;
    
    for(new i = 0; i < MAX_PLAYERS; i++)
    {
        if(IsPlayerConnected(i))
        {
            if(!first)
            {
                strcat(query, ", ");
            }
            first = 0;
            
            new name[MAX_PLAYER_NAME], values[128];
            GetPlayerName(i, name, sizeof(name));
            format(values, sizeof(values), "('%e', %d, %d)", 
                name, GetPlayerMoney(i), PlayerInfo[i][pLevel]);
            strcat(query, values);
            count++;
            
            if(count >= 50) // ограничение размера запроса
            {
                mysql_query(g_SQL, query);
                query = "INSERT INTO players (name, money, level) VALUES ";
                count = 0;
                first = 1;
            }
        }
    }
    
    if(count > 0)
    {
        mysql_query(g_SQL, query);
    }
}

Оптимизация запросов
Код:
// Использование индексов
mysql_query(g_SQL, "CREATE INDEX idx_name ON players(name)");
mysql_query(g_SQL, "CREATE INDEX idx_level ON players(level)");

// Оптимизированный запрос
LoadPlayerDataOptimized(playerid)
{
    new query[128], name[MAX_PLAYER_NAME];
    GetPlayerName(playerid, name, sizeof(name));
    
    // Использование LIMIT для быстрого поиска
    format(query, sizeof(query),
        "SELECT * FROM players WHERE name = '%e' LIMIT 1",
        name);
    
    mysql_tquery(g_SQL, query, "OnPlayerDataLoaded", "i", playerid);
}

Важные моменты:
- Используйте транзакции для сложных операций
- Оптимизируйте запросы
- Кешируйте часто используемые данные
- Обрабатывайте ошибки правильно

Продвинутая работа с MySQL улучшает производительность!
 

1 человек читают эту тему (Всего: 1, Пользователей: 0, Гостей: 1)

Сверху