2011-09-06 113 views
1

這實質上非常簡單,我剛剛對它進行了相當詳細的介紹。我的數據結構如我的帖子底部所示。我的目標是以簡單的電子表格格式組織數據,「平整」關係數據庫。例如:簡單的關係型數據庫 - 高效的查詢

Product1 URL 
Product2 URL URL URL 
Product3 URL 

我的初始方法如下。我尋找替代品的原因是我在產品表中有> 10,000行,每個產品平均有5個網址。這會產生大量的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 

網址

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

如果你已經閱讀過這篇文章,非常感謝你的耐心!我期待着閱讀你的回覆。那我該如何正確地做到這一點?

+0

你打算如何來表示CSV兩個層次結構? –

+0

@Marcelo Cantos:OP告訴我們,每個產品最多可以有五個URL;無論如何,他可以保存到csv'product; url 1; ...; url n'中,然後在檢索該文件時讀取產品,然後一次一個地址,直到行的末尾 – Marco

+0

最左列中的產品,根據需要列出右側的URL。電子表格中會有空格。 – IsisCode

回答

3

的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與空間。

$i = 0; 
$curr_id; 
while($product = mysql_fetch_array($products)) 
{ 
    $prods[$i]['name'] = $product['product_name']; 
    $prods[$i]['id'] = $product['id']; 

    if($product['id'] == $curr_id) 
    { 
     $prods[$i]['urls'] .= " ".$url['url']; 
    } 
    else 
    { 
     $prods[$i]['urls'] = $url['url']; 
    } 
    $i++; 
    $curr_id = $product['id']; 
} 

結果

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

     ) 
+0

非常全面的答案,最重要的是,對我有用!非常感謝。 – IsisCode

2

即使你想拉回來的URL的CSV您可以給拉了回來,準確的信息有一個查詢。

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將所有結果合併在一起。

+0

這是完美的解決方案:爲你+1! – Marco

+1

請注意,group_concat的默認最大長度爲1024,並且在託管公司時,他們通常不會允許您動態更改此服務器變量,或者根本不會授予您執行此操作的權限 – ajreal

1

您可以在一個查詢做到這一點:

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; 
}