2009-06-04 10 views
2

J'écris un script PHP qui s'exécute sur un cron et extrait les données JSON d'une API [titre (texte), chemin (texte), visiteurs (entier)] et les stocke dans une base de données SQLite . Chaque fois qu'il s'exécute, s'il voit un titre existant, il doit ajouter le nombre de nouveaux visiteurs aux visiteurs existants. Si ce n'est pas le cas, les nouvelles données doivent être ajoutées en tant que nouvelle ligne.Fusion et ajout de données avec SQLite

Voici un aperçu simplifié ma boucle:

foreach($results as $printresults) { 

//this iterates though $title, $path and $visitors 

$existing_visitors = $db->query("SELECT SUM(visitors) FROM topten WHERE 
title='$title'"); 
while ($existing_vis_row = $existing_visitors->fetch(SQLITE_NUM)) { 


$dupe_enter = $db->query("UPDATE topten SET title='$title', path='$path', 
visitors='$existing_vis_row[0]' WHERE title='$title' "); 
    } 

$db->query("INSERT INTO topten (id,title,path,visitors,time) VALUES 
(NULL, '$title', '$path', '$visitors', '$time');"); 

} 

Je vais faire un SELECT pour tirer DISTINCT lignes commandées par les visiteurs et écrire à un fichier. Puisque la requête UPDATE ajoute tous les visiteurs à ces lignes, peu importe qu'il y ait tous les dupes. Sur un certain délai, je vais laisser tomber toute la table et recommencer à collectionner, donc le fichier ne devient pas trop lourd. Le problème est qu'il ajoute le nombre de visiteurs additionnés à chaque passage de la boucle, ce qui rend le compte des visiteurs totalement détraqué. Mais je ne pouvais pas trouver une meilleure façon d'ajouter simplement les données ensemble chaque fois que le script a été exécuté.

Répondre

1

pseudo-code:

for($json_records as $rec){ 
    $row = SELECT visitors FROM topten WHERE title = $rec['title'] 
    if($row) 
     //record exists, add visitors and update 
     $sum_visitors = $row['visitors'] + $rec['visitors'] 
     UPDATE topten SET visitors = $sum_visitors WHERE title = $rec['title'] 
    else 
     //record doesn't exist, insert new 
     INSERT topten (title, visitors) VALUES ($rec['title'], $rec['visitors']) 
} 

Peut-être?

0

éviter les dupes. définir une clé unique et utiliser INSERT OR REPLACE ... au lieu de le faire vous-même.

quelque chose comme CREATE UNIQUE INDEX 'title_path' ON topten (title, path). cela rendra impossible d'avoir deux enregistrements avec les mêmes champs de titre et de chemin. Donc, si vous faites juste un INSERT .... aveugle, vous obtiendrez une erreur de conflit si ce serait une dupe. Il suffit donc d'utiliser INSERT OR REPLACE .... pour vérifier tout indice unique et s'il y a déjà un enregistrement, il serait effacé, puis il ferait l'insertion. bien sûr, tout est atomique (donc les autres vérifications de processus ne verront pas l'enregistrement disparaître et réapparaître).

+0

pourriez-vous m'abaisser un peu? Je ne suis pas très bon avec SQL. également supprimé la mention de JSON. –