Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   forum.boolean.name > Веб-программирование > PHP / MySQL

PHP / MySQL Создание динамических Веб-ресурсов

Ответ
 
Опции темы
Старый 26.03.2013, 12:42   #1
pax
Unity/C# кодер
 
Аватар для pax
 
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений
(для 5,323 пользователей)
Возможно ли оптимизировать получение данных из двух таблиц

В общем есть две таблицы
user_items

и user_item_params


Получаю из них данные следующим образом:

public function items_getUserItems($user_id)
    {
        
$sth $this->dbh->prepare('SELECT * FROM user_items WHERE user = :user_id');
        
$sth->execute(array(
            
':user_id' => intval($user_id),
        ));

        
$items$sth->fetchAll(PDO::FETCH_ASSOC);

        
$sth $this->dbh->prepare('SELECT * FROM user_item_params WHERE item = :item_id');

        
$count count($items);
        for(
$i=0$i<$count$i++)
        {
            
$sth->execute(array(
                
':item_id' => intval($items[$i]['id']),
            ));
            
$items[$i]['params'] = $sth->fetchAll(PDO::FETCH_ASSOC);
        }

        return 
$items;
    } 
Возможно ли это оптимизировать и не делать для каждого юзер_итема запрос его параметров?
__________________
Blitz3d to Unity Wiki
(Offline)
 
Ответить с цитированием
Старый 26.03.2013, 12:59   #2
DStalk
Разработчик
 
Аватар для DStalk
 
Регистрация: 27.06.2009
Адрес: Рязань-Москва
Сообщений: 471
Написано 401 полезных сообщений
(для 1,072 пользователей)
Ответ: Возможно ли оптимизировать получение данных из двух таблиц

Я так понимаю тебе нужен JOIN? http://ru.wikipedia.org/wiki/Join_(SQL)
__________________
galaxies.su | dstalk.ru
(Offline)
 
Ответить с цитированием
Старый 26.03.2013, 13:14   #3
pax
Unity/C# кодер
 
Аватар для pax
 
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений
(для 5,323 пользователей)
Ответ: Возможно ли оптимизировать получение данных из двух таблиц

Мне надо передать на клиент результат в формате json, join мне даст одну таблицу, придется делать хитрый алгоритм для преобразования если я хочу, чтобы результат выглядел как сейчас.
__________________
Blitz3d to Unity Wiki
(Offline)
 
Ответить с цитированием
Старый 26.03.2013, 13:34   #4
DStalk
Разработчик
 
Аватар для DStalk
 
Регистрация: 27.06.2009
Адрес: Рязань-Москва
Сообщений: 471
Написано 401 полезных сообщений
(для 1,072 пользователей)
Ответ: Возможно ли оптимизировать получение данных из двух таблиц

оптимально все сделать одним запросом, а цикл потом для обработки все равно нужен, т.к. mysql в json может выбрать тока при EXPLAIN, и то с версии 5.6

вроде так:
SELECT FROM user_items LEFT JOIN user_item_params ON user_items.items=user_item_params.item WHERE user=userid 
__________________
galaxies.su | dstalk.ru
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
pax (26.03.2013)
Старый 26.03.2013, 14:08   #5
pax
Unity/C# кодер
 
Аватар для pax
 
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений
(для 5,323 пользователей)
Ответ: Возможно ли оптимизировать получение данных из двух таблиц

Посоветовали мне получить параметры итемов отдельно одним запросом и получилось следующее
public function items_getUserItems($user_id)
    {
        
$sth $this->dbh->prepare('SELECT * FROM user_items WHERE user = :user_id');
        
$sth->execute(array(
            
':user_id' => intval($user_id),
        ));
 
        
$items $sth->fetchAll(PDO::FETCH_ASSOC);
 
        
$count count($items);
 
        
$item_ids = array();
        
$item_index = array();
        for(
$i=0$i<$count$i++)
        {
            
$items[$i]['params'] = array();
            
$item $items[$i];
            
$item_ids[] = $item['id'];
            
$item_index[$item['id']] = $i;
        }
 
        
$sth $this->dbh->prepare('SELECT * FROM user_item_params WHERE item IN ('.implode(', '$item_ids).');');
        
$sth->execute();
        
$item_params $sth->fetchAll(PDO::FETCH_ASSOC);
 
        foreach(
$item_params as $item_pram)
        {
            
$item $item_pram['item'];
            unset(
$item_pram['item']);
            
$items[$item_index[$item]]['params'][] = $item_pram;
        }
 
        return 
$items;
    } 

А еще я обдумывал вариант с параметрами в поле первой таблицы в виде json строки...
__________________
Blitz3d to Unity Wiki
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
DStalk (26.03.2013)
Старый 26.03.2013, 15:06   #6
moka
.
 
Регистрация: 05.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений
(для 6,863 пользователей)
Ответ: Возможно ли оптимизировать получение данных из двух таблиц

Сразу подмечу, что если у тебя индексация в обоих таблицах хорошо настроина, то запросы будут весьма оптимальны даже при двух запросах.
Но. Тут важна суть не в запросах, а в том кто эти данные получает и что с ними делает.

Например если у тебя игра происходят матчами, и по геймплаю шмот менять можно только между матчами, то при старте матча ты получаешь эти данные один раз, что совсем не критично.
А если можно менять шмот (влиять на бд) во время матча, тогда загружай данные в начале матча, и храни в процессе что обсчитывает матч, и при изменениях - меняй игровые данные и посылай UPDATE в бд, но не перезагружай данные.
Тупой кеш в памяти.

Да и насчёт JSON'а, я тебе настоятельно рекомендую пересмотреть хотя бы на будущее представление о том как данные хранятся в БД. Ты используешь SQL базу данных, с таблицами, но преобразуешь в вложенные JSON документы.
Посмотри в сторону NoSQL баз данных, таких как MongoDB - легко ставиться, очень проста в использовании. Важный плюс в том что там нету таблиц, и всяких JOIN'ов (хотя это сильно влияет на то как данные хранятся, и не всегда подойдёт), зато есть сложные формы объектов, с вложенностями, массивами, хеш таблицами и т.п. Что как я вижу просто идеально подходит под то что ты пытаешься сделать в коде выше.
(Offline)
 
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо moka за это полезное сообщение:
pax (26.03.2013), Reizel (26.03.2013)
Старый 26.03.2013, 15:53   #7
pax
Unity/C# кодер
 
Аватар для pax
 
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений
(для 5,323 пользователей)
Ответ: Возможно ли оптимизировать получение данных из двух таблиц

Спасибо за советы. NoSQL в данном случае не подходит, т.к. я на хостинг ничего не могу поставить сам.

По поводу получения - данные меняться будут редко, и не во время боя. И я всетаки решил сделать все в первой таблице. Я создал в ней текстовое поле params и в виде json буду хранить там параметры.

В итоге получилось вот так:
public function items_getUserItems($user_id)
    {
        
$sth $this->dbh->prepare('SELECT * FROM user_items WHERE user = :user_id');
        
$sth->execute(array(
            
':user_id' => intval($user_id),
        ));

        
$items $sth->fetchAll(PDO::FETCH_ASSOC);

        
$count count($items);

        for(
$i=0$i<$count$i++)
        {
            
$items[$i]['params'] = json_decode($items[$i]['params'], true);
            if(
$items[$i]['params'] == null)
            {
                unset(
$items[$i]['params']);
            }
        }

        return 
$items;
    } 
__________________
Blitz3d to Unity Wiki
(Offline)
 
Ответить с цитированием
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Часовой пояс GMT +4, время: 03:48.


vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com