2011-09-06 5 views
1

Ceci est essentiellement très simple, je viens d'être plutôt verbeux à ce sujet. Mes données sont structurées comme indiqué au bas de mon message. Mon but est d'organiser les données dans un simple format de feuille de calcul, en «aplatissant» la base de données relationnelle. Quelque chose comme:Simple base de données relationnelle - Querying efficace

Product1 URL 
Product2 URL URL URL 
Product3 URL 

Mon approche initiale est comme ci-dessous. La raison pour laquelle je cherche une alternative est que j'ai> 10.000 lignes dans la table des produits et chaque produit a une moyenne de 5 URL. Cela génère une quantité énorme de requêtes MySQL (en fait, dépassant mes ressources d'hébergement partagé), il doit y avoir un meilleur moyen, non? Mon code a été simplifié pour distiller l'essence de ma question.

Mon approche

//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']; 
    } 
} 

Le résultat

Pour être clair, cela est le résultat escompté, la sortie était attendue. J'ai juste besoin d'un moyen plus efficace de passer des tables de base de données brutes à ce tableau multidimensionnel. Je pense qu'il existe des moyens plus efficaces d'interroger la base de données. Aussi, je comprends que ce tableau utilise beaucoup de mémoire lorsqu'il est mis à l'échelle jusqu'à la taille requise. Comme mon but est d'utiliser ce tableau pour exporter les données vers .csv, j'utiliserais XML (ou quelque chose) comme intermédiaire s'il est plus efficace. Alors n'hésitez pas à proposer une approche différente entièrement.

//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 
       ) 
     ) 
) 

Ma base de données du schéma

Produits

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 

liens URLs.product_id à products.id

Si vous avez lu ceci, merci pour votre patience incroyable! J'ai hâte de lire votre réponse. Alors, comment puis-je faire cela correctement?

+0

Comment comptez-vous pour représenter une hiérarchie à deux niveaux au format CSV? –

+0

@Marcelo Cantos: OP nous a dit que chaque produit pouvait avoir jusqu'à cinq URL; de toute façon, il pourrait enregistrer dans csv 'product; url 1; ...; url n' et quand récupère ce fichier lit le produit et ensuite, un à la fois, urls jusqu'à la fin de la ligne – Marco

+0

Produits dans la colonne la plus à gauche , Les URL dans les colonnes à droite autant que nécessaire. Il y aura des espaces vides dans la feuille de calcul. – IsisCode

Répondre

3

Le SQL

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

code PHP à "aplatir" les urls, je viens de les urls avec seperated un espace.

$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']; 
} 

Le résultat

[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

Réponse très complète et surtout, utile pour moi! Merci beaucoup. – IsisCode

2

Vous êtes en mesure de retirer cette information exacte avec une seule requête, même si vous voulez retirer le csv de urls.

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 

Et puis vous avez une requête à votre base de données qui ramène ce dont vous avez besoin.

Ou l'approche plus propre est comment bruce suggéré, puis laissez PHP fusionner tous les résultats ensemble.

+0

Voilà la solution parfaite: +1 pour vous! – Marco

+1

Prenez note de la longueur maximale par défaut pour group_concat est 1024, et normalement, en hébergement, ils ne vous permettront pas de changer dynamiquement cette variable serveur ou ne vous donneront pas les privilèges pour le faire – ajreal

1

Vous pouvez accomplir cela dans une requête:

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

pseudocode:

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