MySQL (F.A.Q.)

Всем привет.

Появилась нужна вернуть первый свободный ID в таблице с учётом того, что самые первые ID (1, 2, 3, etc...) могут быть пропущены (соответственно, если первые 3 ID пропущены, то вернуло бы 1).

Реализовать это в виде одного запроса не вышло, поэтому набросал функцию с двумя:
PHP Code:
stock GetFreeTableNumber(const tablename[20], const columnname[20])
{
    new 
query_string[106+(sizeof(columnname)*4)+(sizeof(tablename)*2)+1],
        
free_id;
        
    
format(query_stringsizeof(query_string), "SELECT MIN(%s) AS free_id FROM %s"columnnametablename);
    new 
Cache:result mysql_query(mysql_connect_IDquery_string);
    
cache_get_value_name_int(0"free_id"free_id);
    
cache_delete(result);
    
    if(
free_id != 1
        return 
1;
    else
    {
        
format(query_stringsizeof(query_string), "SELECT %s+1 AS free_id FROM %s AS a1 WHERE (SELECT 1 FROM %s AS a2 WHERE a2.%s=a1.%s+1) IS NULL ORDER BY a1.%s LIMIT 1"columnnametablenametablenamecolumnnamecolumnnamecolumnname);
        
result mysql_query(mysql_connect_IDquery_string);
        
cache_get_value_name_int(0"free_id"free_id);
        
cache_delete(result);
        return 
free_id;
    }

И всё, вроде, работает, но хотелось бы узнать, хороша ли реализация и если нет, как это всё можно реализовать лучше?
Reply

http://stackoverflow.com/a/5016969/4724730
еще вон как делают

а зачем?
Reply

Quote:
Originally Posted by Eims
View Post
И всё, вроде, работает, но хотелось бы узнать, хороша ли реализация и если нет, как это всё можно реализовать лучше?
Забыть об этом и никогда такое не делать и даже не думать делать!
НИКОГДА!

PS на хабре есть статья об этом, ей года 3, там было штук 5 реализация.
Reply

Quote:
Originally Posted by S4D
View Post
http://stackoverflow.com/a/5016969/4724730
еще вон как делают

а зачем?
Мой второй запрос делает то же самое: ищет первый разрыв между значениями и выдаёт его первый член. То бишь, если в таблице будут такие значения:
PHP Code:
2
3
4
5
7
8

Такой запрос выдаст 6, а не 1. В моём же случае это не то, что нужно.


Я пишу систему админки, которая полностью работает через БД (ну, точнее, не вся, а лишь настройки).
Имеется таблица, в которой будут хранится ранги для администраторов. В этой таблице есть отдельное поле (помимо поля с A_I), в котором хранится уровень админки, сопоставимый этому рангу (точнее, этот уровень просто нужен при сортировке рангов в списке на сервере, но не суть) . Для того, чтоб не забивать голову информацией о том, какие уровни свободны, я добавил возможность оставлять поле пустым, тем самым включая автоопределение свободного уровня. Там и нужна такая функция.

Quote:
Originally Posted by Stepashka
View Post
Забыть об этом и никогда такое не делать и даже не думать делать!
НИКОГДА!

PS на хабре есть статья об этом, ей года 3, там было штук 5 реализация.
Я знаю какие у этого могут быть последствия при больших таблицах. Но у меня таблица, в которой нужно производить манипуляции, будет содержать, от силы, 100 строк. Не думаю, что в этом случае будут какие-либо проблемы.
+ эти манипуляции будут происходить лишь в единичных случаях (при создании новых рангов/редактировании существующих).

Статью на хабре читал (если мы говорим об одной и той же статье) и даже второй запрос я, в своё время, взял впервые именно оттуда.
Reply

Может мой вопрос прозвучит тупо, но куда кидать файл базы данных к примеру players.sql чтобы плагин mysql его мог прочитать? А то куда его не кидаю в логе везде пишет connect database failed ?
Пробовал в корень папки сервера, в папку scriptfiles и в папку с плагинами. Нихрена не загружает!
Reply

Quote:
Originally Posted by Sidorovich12
View Post
Может мой вопрос прозвучит тупо, но куда кидать файл базы данных к примеру players.sql чтобы плагин mysql его мог прочитать? А то куда его не кидаю в логе везде пишет connect database failed ?
Пробовал в корень папки сервера, в папку scriptfiles и в папку с плагинами. Нихрена не загружает!
он импортируется через phpmyadmin
Reply

Quote:
Originally Posted by Sidorovich12
View Post
Может мой вопрос прозвучит тупо, но куда кидать файл базы данных к примеру players.sql чтобы плагин mysql его мог прочитать? А то куда его не кидаю в логе везде пишет connect database failed ?
Пробовал в корень папки сервера, в папку scriptfiles и в папку с плагинами. Нихрена не загружает!
Quote:
Originally Posted by Mcc
View Post
он импортируется через phpmyadmin
Или через команду в консоли:
Code:
mysql -u имя_пользователя_БД -p имя_базы_данных < players.sql
Reply

Quote:
Originally Posted by Bombo
View Post
Или через команду в консоли:
Code:
mysql -u имя_пользователя_БД -p имя_базы_данных < players.sql
Да я почитал уже по этому поводу инфу. Капеееец как там много заморочек. Отдельный хостинг под единственную базу. SQLite в этом плане намного проще и его по крайней мере можно размещать одним файлов в папке сервера. MYSQL нахрен не нужен с такими заморочками. Вообщем спасибо за ответ.
Reply

Интересно, какая нагрузка будет, если в сутки отправлять около 4000 запросов в базу INSERT INTO, учитывая что присутствует еще и прочие стандартные запросы?
Reply

в зависимости от частоты отправки, настройки бд
Reply

Quote:
Originally Posted by youngPimp
View Post
Интересно, какая нагрузка будет, если в сутки отправлять около 4000 запросов в базу INSERT INTO, учитывая что присутствует еще и прочие стандартные запросы?
У меня больше запросов в день и нагрузки нет. CPU 0%, нагрузки на винт особой нет.
Reply

Спасибо за ответы.


Еще вопросик, как бороться с тем, что в момент запроса база может подвиснуть, человек выходит, а результат уже получает игрок, который зашел на сервер?
Приходится в mysql query передавать его имя на сервере\айди аккаунта и при получение результата сверять эти данные.
Reply

Создать массив для всех игроков, допустим:
HTML Code:
new mysql_race[MAX_PLAYERS];
Увеличивать значение элемента при выходе/входе игрока и перед отправкой запроса, передавать как доп. параметр в кэллбек (mysql_pquery/mysql_tquery), а в самом кэллбеке проверять переданный параметр с mysql_race[playerid].
Reply

Приветствую. Столкнулся, как мне кажется, с довольно простой ситуацией, но что-то голова отказывается варить. В общем, есть две таблицы.

Структура первой такая:
PHP Code:
id command_name 
Структура второй такая:
PHP Code:
id account_id command_id 
В первой таблице перечислены имена команд, с которыми нужно работать впоследствии.
Во второй таблице содержатся записи о том, какие команды и у какого игрока "активированы" (то бишь, если у конкретного игрока есть запись во второй таблице с командой под ID 5, то она у него "активирована").

Собственно, нужно запросом вернуть весь список команд из первой таблицы (их имена) и, при этом, проверить, активирована ли команда, найдя данные во второй таблице ("id" из первой таблицы равносилен "command_id" из второй таблицы).
Если активирована - 1, а иначе - 0.

Растаскивать данную задачу на несколько запросов не хочется, ибо код тогда бессмысленно раздуется и усложнится, поэтому хотелось бы найти решение в виде одного запроса.
Я знаю как вытащить только "активированные" команды, а вот остальные как-то не получается пока.
Reply

Quote:
Originally Posted by Eims
View Post
Приветствую. Столкнулся, как мне кажется, с довольно простой ситуацией, но что-то голова отказывается варить. В общем, есть две таблицы.

Структура первой такая:
PHP Code:
id command_name 
Структура второй такая:
PHP Code:
id account_id command_id 
В первой таблице перечислены имена команд, с которыми нужно работать впоследствии.
Во второй таблице содержатся записи о том, какие команды и у какого игрока "активированы" (то бишь, если у конкретного игрока есть запись во второй таблице с командой под ID 5, то она у него "активирована").

Собственно, нужно запросом вернуть весь список команд из первой таблицы (их имена) и, при этом, проверить, активирована ли команда, найдя данные во второй таблице ("id" из первой таблицы равносилен "command_id" из второй таблицы).
Если активирована - 1, а иначе - 0.

Растаскивать данную задачу на несколько запросов не хочется, ибо код тогда бессмысленно раздуется и усложнится, поэтому хотелось бы найти решение в виде одного запроса.
Я знаю как вытащить только "активированные" команды, а вот остальные как-то не получается пока.
Выбирай любой:
PHP Code:
SELECT
    commands1
.id,
    
commands1.command_name,
    
commands2.command_id IS NOT NULL AS active
FROM commands1
LEFT JOIN commands2 ON commands1
.id commands2.command_id
GROUP BY commands1
.idcommands1.command_name 
PHP Code:
SELECT
    id
,
    
command_name,
    (
SELECT command_id FROM commands2 WHERE commands1.id command_id LIMIT 1IS NOT NULL AS active
FROM commands1

Я бы выбрал первый вариант.
Reply

Quote:
Originally Posted by Eims
View Post
Я знаю как вытащить только "активированные" команды, а вот остальные как-то не получается пока.
Как ты получаешь только "активированные" команды?
Reply

Quote:
Originally Posted by Johhnyllll
View Post
Как ты получаешь только "активированные" команды?
Просьба особо впечатлительных отойти от экрана, ибо мод не мой и приходится идти на некоторые велосипеды, дабы не переписывать большие куски кода.
А именно то, что в системе, которую нужно доработать, всё очень плохо с получением ID аккаунта игрока, для которого происходит выборка (работа идёт исключительно по нику), поэтому приходится обращаться к трем таблицам, чтоб сначала узнать ID аккаунта и потом уже сделать нужные дела

Как-то так:
PHP Code:
SELECT t1.command_name 
    FROM table_1 
AS t1table_2 AS t2table_3 AS t3 
        WHERE t3
.Name 'Ник' AND t2.account_id t3.id AND t1.id t2.command_id 
t1 - таблица с именами команд
t2 - таблица с перечислением активированных команд
t3 - таблица аккаунтов

Quote:
Originally Posted by ZiGGi
View Post
Выбирай любой:
PHP Code:
SELECT
    commands1
.id,
    
commands1.command_name,
    
commands2.command_id IS NOT NULL AS active
FROM commands1
LEFT JOIN commands2 ON commands1
.id commands2.command_id
GROUP BY commands1
.idcommands1.command_name 
PHP Code:
SELECT
    id
,
    
command_name,
    (
SELECT command_id FROM commands2 WHERE commands1.id command_id LIMIT 1IS NOT NULL AS active
FROM commands1

Я бы выбрал первый вариант.
Спасибо. Совсем забыл про JOIN. Сейчас попробую под свои нужды запрос написать
Reply

Как можно отловить ошибку при изменении поля с уникальным ключом?
Reply

Quote:
Originally Posted by pawnoholic
Посмотреть сообщение
Как можно отловить ошибку при изменении поля с уникальным ключом?
А какую ошибку пишет?
Reply

Quote:
Originally Posted by Stepashka
Посмотреть сообщение
А какую ошибку пишет?
Мне нужно записать электронную почту игрока, я не хочу перед этим запросом делать проверочный на существование, возможно ли на уровне Pawn отследить ошибку при записи значения в уникальное поле?

Вроде как, cache_num_rows() должен возвращать количество строк, которые были изменены?
Если будет 0, то можно считать, что операция не удалась и отображать игроку соответствующее сообщение?
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)