PDA

Просмотр полной версии : [Вопрос] Вопросы по MySQL



Elrmrnt-Kritik
28.12.2018, 22:15
Много читал википедию по MySQL, довольно-таки долго пользуюсь самим MySQL. Но все-таки хотелось бы разобраться в функциях, которые я ранее не использовал... Возможно, они окажутся очень даже полезными для меня. Буду рад любой помощи.


1. В функции mysql_set_options есть параметр MULTI_STATEMENTS ("Allow/Disallow executing multiple SQL statements in one query"). Я правильно понял, это позволяет использовать запросы следующего вида? SELECT * FROM table; UPDATE table SET column = 1 Т.е. использовать несколько запросов в одной строке. Я когда-то пробовал так делать, но выполнялся только первый запрос (или не выполнялось ни одного - не помню уже, если честно).

2. mysql_tquery, mysql_pquery и mysql_query. Чтобы не было много текста, составил вот такую вот табличку. Все ли правильно в ней?



Функция
Кэширование
Обработка запроса
Обработка результата


mysql_query
+
отсутствует отдельный поток, сервер ждет ответа от MySQL
в той функции, где использовалась mysql_query


mysql_tquery
-
в отдельном потоке
в отдельной public-функции


mysql_pquery
+
в отдельных потоках, работающих параллельно
в отдельной public-функции



https://yadi.sk/i/af-mwB5Auq6BCw


3. Не понял что за функции cache_set_result и cache_get_result... Не могли бы, пожалуйста, прояснить их сущность?
4. Последнее связано с кэшированием.. Ранее моя регистрация имела следующую структуру:


1. По имени игрока получить его пароль.
2. Сверять полученный пароль с введенным.
3. Если пароли идентичны, загружать аккаунт полностью.


Сейчас же я перешел к кэшированию:


1. Получить всю информацию об игроке.
2. Из полученных данных записать сразу пароль игрока в переменную. Потом сохранить кэш: cache_save(gPlayer[playerid][pCache]).
3. После успешного ввода пароля использовать:

gPlayer[playerid][pCache] = cache_set_active(); // переключиться на другой (поток?)
// получить и сразу записать в переменные все данные игрока
cache_delete(gPlayer[playerid][pCache]); // очистить содержимое (потока?)
cache_unset_active(); // возвращаемся к первоначальному (основному) (потоку?)
_:gPlayer[playerid][pCache] = INVALID_CACHE_ID;// INVALID_CACHE_ID - моя константа со значением -1


Ну, и на всякий случай в OnPlayerDisconnect:

if(_:gPlayer[playerid][pCache] != INVAlID_CACHE_ID) cache_delete(gPlayer[playerid][pCache]);



Будет ли таковой код нормальный и не должны ли теоретически возникнуть с ним проблемы? Сколько тестировал, не замечал, но мало ли что-то работает на самом деле неправильно...

DeimoS
29.12.2018, 04:03
1) А как ты определял, что выполняется только первый запрос?
Да, параметр именно это и позволяет.

2) Не совсем верно. У плагина есть отдельный поток для запросов, в которые попадают запросы, отправленные через mysql_tquery. Соответственно, все отправленные запросы, грубо говоря, сначала будут "закэшированы" в памяти плагина, а после будут по очереди отправляться в базу, когда та освободиться. А mysql_pquery отправляет запрос немедленно, обходя "кэширование". Там механизм немного другой, как я помню, но общая суть такая.

3) Они как раз и нужны для переключения между результатами при отправке нескольких запросов в одной функции с параметром MULTI_STATEMENTS. Через них ты переключаешься между полученными результатами.
https://i.imgur.com/khaYYxP.png

4) Во-первых, это не поток, а кэш. То бишь, данные просто хранятся в памяти плагина.
Во-вторых, главное просто не забывать удалять сохранённый кэш, например, если игрок не авторизировался и вышел с сервера. В общем, во всех ситуациях, когда кэш уже не нужен. Иначе можно словить переполнение памяти и краш.
В-третьих, ты, видимо, опечатался, ибо кэш сохраняется через cache_save, а не через cache_set_active.
И тут можно всё через pVar сделать:

// Если аккаунт найден
SetPVarInt(playerid, "AccountCache", _:cache_save());

//При загрузке
new Cache:result = Cache:GetPVarInt(playerid, "AccountCache");
DeletePVar(playerid, "AccountCache");
cache_set_active(result);
// Загрузка данных
cache_delete(result);

//При выходе с сервера
if(GetPVarType(playerid, "AccountCache") && cache_is_valid(Cache:GetPVarInt(playerid, "AccountCache")))
{
cache_delete(Cache:GetPVarInt(playerid, "AccountCache"));
}

Elrmrnt-Kritik
29.12.2018, 15:56
То есть не следует переключаться на другой кэш через cache_unset_active?

DeimoS
29.12.2018, 18:10
Эмм, что?

Сохранение кэша - cache_save
Переключение на нужный кэш - cache_set_active
Удалить кэш - cache_delete
Прекратить работу с кэшем - cache_unset_active

Elrmrnt-Kritik
29.12.2018, 23:36
А, все, понял)