Простая реляционная база данных - эффективные запросы - PullRequest
1 голос
/ 06 сентября 2011

Это, по сути, очень просто, я просто об этом довольно многословен. Мои данные структурированы так, как показано внизу моего поста. Моя цель состоит в том, чтобы организовать данные в простом формате электронных таблиц, «сгладив» реляционную базу данных. Что-то вроде:

Product1 URL
Product2 URL URL URL
Product3 URL

Мой первоначальный подход такой, как ниже. Причина, по которой я ищу альтернативу, состоит в том, что у меня> 10000 строк в таблице продуктов, и каждый продукт имеет в среднем 5 URL-адресов. Это генерирует огромное количество запросов MySQL (фактически превышающих мои ресурсы общего хостинга), должен быть лучший способ, верно? Мой код был упрощен, чтобы раскрыть суть моего вопроса.

Мой подход

//Query to get all products
$products = mysql_query("SELECT * FROM products");

$i = 0;
//Iterate through all products
while($product  = mysql_fetch_array($products)){

    $prods[$i]['name'] = $product['name'];
    $prods[$i]['id'] = $product['id'];

    //Query to get all URLs associated with this particular product
    $getUrls = mysql_query("SELECT * FROM urls WHERE product_id =".$product['id']);

    $n = 0;

    while($url = mysql_fetch_array($getUrls)){

        $prods[$i]['urls'][$n] = $url['url'];  
    }
}

Результат

Для ясности, это ожидаемый результат, ожидаемый результат. Мне просто нужен более эффективный способ перехода от необработанных таблиц базы данных к этому многомерному массиву. Я подозреваю, что есть более эффективные способы запроса базы данных. Кроме того, я понимаю, что этот массив использует много памяти, когда масштабируется до необходимого размера. Поскольку моя цель - использовать этот массив для экспорта данных в .csv, я бы посоветовал использовать XML (или что-то еще) в качестве посредника, если он более эффективен. Поэтому не стесняйтесь предлагать совершенно иной подход.

//The result from   print_r($prods);

Array
(
    [0] => Array
        (
            [name] => Swarovski Bracelet
            [id] => 1
            [urls] => Array
                (
                    [0] => http://foo-example-url.com/index.php?id=7327

                )
        )
    [1] => Array
        (
           [name] => The Stranger - Albert Camus
           [id] => 2
           [urls] => Array
               (
                   [0] => http://bar-example-url.com/index.php?id=9827
                   [1] => http://foo-foo-example-url.com/index.php?id=2317
                   [2] => http://baz-example-url.com/index.php?id=5644
                )
        )
)

Моя схема базы данных

Продукты

id  product_name

1   Swarovski Bracelet
2   The Stranger - Albert Camus
3   Finnegans Wake - James Joyce

URL-адресов

id  product_id  url                                                price

1   1           http://foo-example-url.com/index.php?id=7327       £16.95
2   2           http://bar-example-url.com/index.php?id=9827       £7.95
3   2           http://foo-foo-example-url.com/index.php?id=2317   £7.99
4   2           http://baz-example-url.com/index.php?id=5644       £6.00
5   3           http://bar-baz-example-url.com/index.php?id=9534   £11.50

URLs.product_id ссылки на products.id

Если вы читали это, спасибо за ваше невероятное терпение! Я с нетерпением жду вашего ответа. Так как я могу сделать это правильно?

Ответы [ 3 ]

3 голосов
/ 06 сентября 2011

SQL

 SELECT p.id, p.product_name, u.url 
 FROM products p, urls u 
 WHERE p.id = u.product_id ORDER BY p.id

PHP-код для «выравнивания» URL-адресов. Я только что разделил URL-адреса пробелом.

2 голосов
/ 06 сентября 2011

Вы можете получить эту точную информацию одним запросом, даже если вы хотите отозвать CSV из URL.

SELECT 
    p.id, p.product_name, 
    GROUP_CONCAT(u.url) AS URLS 
    FROM products p LEFT JOIN urls u 
    ON p.id = u.product_id 
    GROUP BY p.id, p.product_name

И тогда у вас есть 1 запрос к вашей базе данных, который возвращает то, что вам нужно.

Или более чистый подход заключается в том, как предложил Брюс, а затем позволит PHP объединить все результаты вместе.

1 голос
/ 06 сентября 2011

Вы можете сделать это одним запросом:

select * from products join urls on products.id = urls.product_id order by products.id

псевдокод:

while(query_result) {
     if (oldpid == pid) { print ", \"url\"" }
     else { print "pid, \"url\"" }
     oldpid = pid;
}
...