Aide pour optimiser mon code => insert bdd

Aide pour optimiser mon code => insert bdd - PHP - Programmation

Marsh Posté le 06-12-2007 à 12:39:56    

Bonjour,
J'ai un probleme de temps de traitement.
 
Le perimetre :
1 fichier de 4MO typé CSV (',').
Chaque ligne de ce fichier est à insérer dans une base Mysql.
 
La problématique :
Pour chaque enregistrement (chaque ligne), je dois tester la présence de chaque éléments dans la base avant de l'insérer (5 requetes pa ligne).
 
Le souhait:
Paralléliser les tests de présence dans la base par lot de ligne.
 
Genre:
Je lis 100 lignes => execute pour chaque ligne une fonction (en mode simultané, pas 1 par 1).
 
Environnement:
Je lis mon fichier ligne par ligne avec fgetcsv.
 
 
Avez vous des idées ?


Message édité par hornetmen le 06-12-2007 à 17:16:43
Reply

Marsh Posté le 06-12-2007 à 12:39:56   

Reply

Marsh Posté le 06-12-2007 à 13:18:32    

tu créés une table temporaire ( keyword: temporary) en pensant aux indexs nécessaires.
Tu fais un load data infile dans la dite table de ton fichier csv.
Tu fais tes requêtes de comparaison entre ta table temporaire et ta table destination, puis les insertions.

Reply

Marsh Posté le 06-12-2007 à 14:25:57    

Oui c'est une solution.
Mais je souhaite etudier l'idée de requetage // à partir des lignes dans mon fichier ;)

Reply

Marsh Posté le 06-12-2007 à 14:32:49    

bin fais comme tu veux ... [:spamafote]
Mais ensuite tu vas te rendre compte que c'est lent, lourd et qu'il va falloir le refaire correctement :o

Reply

Marsh Posté le 06-12-2007 à 14:40:34    

Ok,
 
Le soucy c'est que j'ai 4 tables pour les recherches et update.....
Et je suis pas un AS en sql je dirais.

Reply

Marsh Posté le 06-12-2007 à 15:27:31    

commence à faire ton truc et reviens poser tes questions sqls quand tu bloques :)

Reply

Marsh Posté le 06-12-2007 à 17:08:59    

Voici le shéma de la base :

Code :
  1. CREATE TABLE `job_db_copy` (
  2.   `job_id` bigint(20) NOT NULL auto_increment,
  3.   `job_name_id` bigint(100) NOT NULL,
  4.   `job_start` datetime NOT NULL default '0000-00-00 00:00:00',
  5.   `job_end` datetime NOT NULL default '0000-00-00 00:00:00',
  6.   `job_duration` time NOT NULL default '00:00:00',
  7.   `job_status` varchar(15) NOT NULL,
  8.   `job_log` varchar(100) NOT NULL,
  9.   `server_id` bigint(20) NOT NULL default '0',
  10.   UNIQUE KEY `id` USING BTREE (`job_id`,`job_name_id`,`server_id`),
  11.   KEY `job_id` (`job_id`,`job_start`,`job_log`,`job_end`)
  12. ) ENGINE=MyISAM AUTO_INCREMENT=229727 DEFAULT CHARSET=utf8;
  13. CREATE TABLE `job_ref` (
  14.   `job_name_id` bigint(20) NOT NULL auto_increment,
  15.   `server_id` bigint(20) default NULL,
  16.   `job_name` varchar(100) default NULL,
  17.   `job_desc` varchar(200) default NULL,
  18.   `job_dep` varchar(300) default NULL,
  19.   UNIQUE KEY `id` (`job_name_id`,`server_id`,`job_name`),
  20.   KEY `job_name` (`job_name`,`job_desc`,`job_dep`(255))
  21. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  22. CREATE TABLE `srv_ref` (
  23.   `server_id` bigint(20) NOT NULL auto_increment,
  24.   `server_name` varbinary(20) NOT NULL,
  25.   PRIMARY KEY  (`server_id`,`server_name`)
  26. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Mon fichier a traiter ressemble à ca:
 
 

Code :
  1. ELCLP_BAT_34234_J_6I_1,2007-12-05  22:51:01,2007-12-05  22:51:15,00:00:14,COMPLETE,/replogs/log/ELCLP_BAT_34234_J_6I_1,SRVUS0001
  2. IVB6P_JOT_34234_J_RI_1,2007-12-01  07:50:11,2007-12-01  07:52:17,00:02:06,COMPLETE,/replogs/log/IVB6P_JOT_34234_J_RI_1,SRVUS0001
  3. ELCLP_ANT_34234_J_2E_1,2007-12-01  00:38:25,2007-12-01  00:38:39,00:00:14,COMPLETE,/replogs/log/ELCLP_ANT_34234_J_2E_1,SRVUS0001
  4. IVB6P_JWT_34234_J_JI_1,2007-12-01  08:13:49,2007-12-01  08:14:56,00:01:07,COMPLETE,/replogs/log/IVB6P_JWT_34234_J_JI_1,SRVUS0001
  5. IVEMP_JUT_34234_J_2E_1,2007-12-01  07:59:32,2007-12-01  08:02:35,00:03:03,COMPLETE,/replogs/log/IVEMP_JUT_34234_J_2E_1,SRVUS0001
  6. ELCLP_BBT_34234_J_2E_1,2007-12-05  22:51:26,2007-12-05  22:52:15,00:00:49,COMPLETE,/replogs/log/ELCLP_BBT_34234_J_2E_1,SRVUS0001
  7. IVB6P_JPT_34234_J_JI_1,2007-12-01  07:58:20,2007-12-01  07:59:25,00:01:05,COMPLETE,/replogs/log/IVB6P_JPT_34234_J_JI_1,SRVUS0001
  8. IVEMP_JOT_34234_J_PI_1,2007-12-01  07:21:48,2007-12-01  07:22:59,00:01:11,COMPLETE,/replogs/log/IVEMP_JOT_34234_J_PI_1,SRVUS0001
  9. IVE0P_BHI_34234_J_AI_1,2007-12-01  13:50:36,2007-12-01  13:51:56,00:01:20,COMPLETE,/replogs/log/IVE0P_BHI_34234_J_AI_1,SRVUS0001
  10. IVE0P_BJI_34234_J_4I_1,2007-12-05  23:18:31,2007-12-05  23:19:36,00:01:05,COMPLETE,/replogs/log/IVE0P_BJI_34234_J_4I_1,SRVUS0001
  11. IVB6P_JWT_34234_J_HI_1,2007-12-01  08:16:48,2007-12-01  08:18:01,00:01:13,COMPLETE,/replogs/log/IVB6P_JWT_34234_J_HI_1,SRVUS0001
  12. IVEMP_JPT_34234_J_HE_1,2007-12-01  07:52:24,2007-12-01  07:53:29,00:01:05,COMPLETE,/replogs/log/IVEMP_JPT_34234_J_HE_1,SRVUS0001
  13. IVEMP_JOT_34234_J_RI_1,2007-12-01  07:26:19,2007-12-01  07:27:35,00:01:16,COMPLETE,/replogs/log/IVEMP_JOT_34234_J_RI_1,SRVUS0001
  14. IVE0P_BBI_34234_J_CI_1,2007-12-05  23:24:14,2007-12-05  23:25:18,00:01:04,COMPLETE,/replogs/log/IVE0P_BBI_34234_J_CI_1,SRVUS0001
  15. ELCLP_AOT_34234_J_6I_1,2007-12-01  08:57:36,2007-12-01  08:57:58,00:00:22,COMPLETE,/replogs/log/ELCLP_AOT_34234_J_6I_1,SRVUS0001


 
 
A présent je lance un script php avec le nom du fichier a traiter en parametre qui fait ca:
 

Code :
  1. <?php
  2. include ("../inc/insert.inc" );
  3. //if(isset($_GET['file']))
  4. if(isset($argv[1]))
  5. {
  6. $file = $argv[1];
  7. $dest_dossier = 'd:\\exploit\\www\\myjobsearcher\\pages\\upload\\';
  8. $myfile = "$dest_dossier$file";
  9. $archdossier = 'd:\\exploit\\www\\myjobsearcher\\pages\\upload\\archives\\';
  10. $archfile = "$archdossier$file";
  11. $ligne = 1;
  12. $id_fichier = fopen ("$myfile","r" );
  13.    while ($tableau = fgetcsv($id_fichier, 1024, "," ))
  14.    {
  15.  $nb = count($tableau);
  16.  //echo "<h3>$nb champs dans la ligne $ligne: </h3>";
  17.  $ligne++;
  18.  $job_name=$tableau[0];
  19.  $job_start=$tableau[1];
  20.  $job_end=$tableau[2];
  21.  $job_duration=$tableau[3];
  22.  $job_status=$tableau[4];
  23.  $job_log=$tableau[5];
  24.  $server_name=$tableau[6];
  25.  //print ("$job_name $job_log" );
  26.  $server_name = strtoupper($server_name);
  27.      
  28.  // teste si le serveur existe
  29.  if ($ligne == "2" ) { print ("Insert is running (Please wait for \"Insert COMPLETE\" message before close this windows.<BR>" );}
  30.  $server_name_indb = exist_server($server_name);
  31.          
  32.          
  33.          
  34.  //print ("server_name_indb = $server_name_indb and server_name=$server_name<BR>" );
  35.  //Si le serveur existe pas, on le cree
  36.  if (is_null($server_name_indb))
  37.  {
  38.   //print ("Server $server_name don't exist in the database, we need to create it before !<BR>" );
  39.   create_server ($server_name);
  40.   //print ("Executing => $create_server_sql<BR><BR>" );
  41.  }
  42.  //on recupere l'id du serveur
  43.  $server_id = get_server_id($server_name);
  44.  //print ("Found : $server_id<BR>" );
  45.  //teste si le job est reference la table job_ref
  46.  $job_info = exist_job_name ($server_id,$job_name);
  47.  // si il existe pas, on le cree
  48.  if (is_null($job_info[0]))
  49.  {
  50.   //print ("Job $job_name pour le serveur $server_name non trouvé dans la ref<BR>" );
  51.   $job_name_create = create_job_name($job_name,$server_id);
  52.   ++$count_create_job;
  53.  }
  54.  else
  55.  {
  56.   //print ("Job $job_name pour le serveur $server_name trouvé dans la ref (job_id = $job_info[0])<BR>" );
  57.  }
  58.  //teste si le job a inserer existe dans la table job_db_copy, pour eviter les doublons
  59.  //$jobdb_id = get_jobdb_name_idold ($server_id,$job_name,$job_start,"$job_log",$job_status,$job_duration);
  60.  $jobdb_id = get_jobdb_name_id1 ($server_id,$job_name,$job_start);
  61.  //si il n'existe pas, on le cree
  62.  if (is_null($jobdb_id))
  63.  {
  64.   $job_name_id = get_job_name_with_job_id ($job_name,$server_id);
  65.   $insert_new_job = insert_new_job($server_id,$job_name_id,$job_start,$job_end,"$job_log",$job_status,$job_duration);
  66.   //print (" job $job_name est bon a inséerer<BR>" );
  67.   $insertme_status='OK';
  68.   ++$count_insert_job;
  69.  }
  70.  //si le job existe
  71.  else
  72.  {
  73.   //on teste si job_end,job_log,job_status,job_duration sont les même
  74.   //print ("<BR>Job $job_name on $server_name starting at $job_start in $job_status status is already present in the db. (New Function)<BR>" );
  75.   $job_log = ereg_replace("//","/",$job_log) ;
  76.   $jobdb_id = get_jobdb_name_id2 ($server_id,$job_name,$job_start,"$job_log",$job_status,$job_duration,$job_end);
  77.   //print ("$job_id<BR>" );
  78.   //si au moins un champs est different, on update la ligne avec les nouvelles donnees
  79.   if (is_null($jobdb_id))
  80.   {
  81.    $jobdb_id = get_jobdb_name_id1 ($server_id,$job_name,$job_start);
  82.    //print ("Line is different, need an update for this line => job_id $jobdb_id<BR>" );
  83.    $job_log = ereg_replace("//","/",$job_log) ;
  84.    $update_doublon = update_jobdb_doublon ($job_start,"$job_log",$job_status,$job_duration,$job_end,$jobdb_id,$job_status);
  85.    $insertme_status='OK';
  86.   ++$count_update_job;
  87.   }
  88.   //si c'est tous ces champs sont les memes, on passe
  89.   else
  90.   {
  91.    //print ("job_id find => $jobdb_id => nothing to do<BR>" );
  92.    ++$count_skipped_job;
  93.   }
  94.   //print ("Job $job_name on $server_name starting at $job_start in $job_status status is already present in the db. Zapingg :)<BR>" );
  95.  }
  96.            
  97.    }
  98.  
  99. //tous le jobs ont ete inserer, on rend la main
  100. if (isset($insertme_status))
  101. {
  102.  print ("Insert = $count_insert_job.<BR>" );
  103.  print ("Update = $count_update_job.<BR>" );
  104.  print ("Create = $count_create_job.<BR>" );
  105.  print ("Skip = $count_skipped_job.<BR>" );
  106.  print ("Insert is COMPLETE.<BR>" );
  107.  fclose ($id_fichier);
  108.  copy("upload/$file", "upload/archives/$file" );
  109.  unlink("upload/$file" );
  110. }
  111. }
  112. //si le fichier d'entree n'a pas ete trouve, on alerte
  113. else
  114. {
  115. print ("Don't find file : $file" );
  116. }
  117. ?>


 
 
 
Voila, aujourd"hui ce code fonctionne parfaitement.
Le problème c'est que c'est long car il fait ligne par ligne......Je suis à 10 requetes par secondes car il fait environ 2 lignes par secondes........(et 5 requetes par ligne).......
 
Sachant que le fichier à insérer contient généralement 20% d'update,10% d'insertion et 70% de doublons, je suis bloqué à ce niveau là.
 
 :jap:

Reply

Marsh Posté le 06-12-2007 à 17:51:09    

oui et il est où le problème?
Ce qui est amusant c'est que tu es exactement dans ma 2eme remarque [:dawak]

Reply

Marsh Posté le 06-12-2007 à 17:56:30    

Le pb est que :
 
1 => il lit 1 ligne et requete 5 fois pour savoir ce qu'il doit faire (insert/update/nothing).
2 => il attends que la ligne 1 soit passé pour attaquer la ligne 2
 
Donc c'est chiant sur des milliers de lignes.
Je voudrait bien qu'il lise par exemple 300 lignes, execute en même temps les 300 requetes en même temps, et passe aux suivantes.
 
Le coup de loader dans une table temporaire, je veux bien, ce sera certainement le plus rapide......
Je sais avoir une table à l'image de mon CSV.
 
Je ne sais pas comment gérer mes insert/update/notthing apres en sql......

Reply

Marsh Posté le 07-12-2007 à 11:44:42    

Bon,
J'ai créé une table temporaire, et insérer mon fichier CSV brut dedans.
 
Le shéma:
 
CREATE TABLE `tmp2` (
  `job_name` varchar(100) NOT NULL,
  `job_start` datetime NOT NULL,
  `job_end` datetime NOT NULL,
  `job_duration` time NOT NULL,
  `job_status` varchar(15) NOT NULL,
  `job_log` varchar(500) NOT NULL,
  `server_name` varchar(45) NOT NULL,
  `job_id` bigint(20) NOT NULL auto_increment,
  PRIMARY KEY  (`job_id`),
  UNIQUE KEY `job_name` (`job_id`,`job_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
 
Je suis un peu perdu avec le sql maintenant.


Message édité par hornetmen le 13-12-2007 à 14:50:18
Reply

Marsh Posté le 07-12-2007 à 11:44:42   

Reply

Marsh Posté le 07-12-2007 à 14:32:44    

Dans quel cas tu va choisir de faire un update ou rien :??:
 
Je suis presque sur que tout est faisable en quasiment une seule requête par ligne à coup de IGNORE et de ON DUPLICATE KEY UPDATE. Reste ma question à traiter :)

Reply

Marsh Posté le 07-12-2007 à 15:01:14    

ce qui est sur c'est qu'il est dommage que mysql ne supporte pas "merge ... into" car il est sur que ça se faisait en 1 requête ;)
edit: et +1 sur la question précédente


Message édité par anapajari le 07-12-2007 à 15:01:27
Reply

Marsh Posté le 07-12-2007 à 15:09:32    

Ok, donc le cas ou je fais un update :
 
job_name_id/job_start sont pareil mais un des autre champs est différent => update de toutes les colones.
 
les inserts:
- si le server_name est pas présent dans srv_ref => update avant insertion pour avoir un server_name_id a renseigner dans job_db_copy
- si job_name n'est pas présent dans job_ref => update avant insertion pour avoir job_name_id a renseigner dans job_db_copy
 
:)

Reply

Marsh Posté le 07-12-2007 à 15:35:55    

Je suis pas sur d'avoir compris, donc tu peux avoir qu'un couple (job_name_id,job_start) mais dont les valeurs peuvent changer :??:
=>Update systématique car mysql le passera à la trappe si pas besoin
 
Je comprends pas tes inserts où tu parles d'update alors que j'ai l'impression que tu veux faire une insertion avant?
=> trigger

Reply

Marsh Posté le 07-12-2007 à 15:43:47    

car dans la table job_db_copy, il y a server_id (ref vers table srv_ref) et job_name_id (ref ver job_ref) ;)

Reply

Marsh Posté le 07-12-2007 à 17:08:42    

Donc tu inserts dans ces tables pour avoir les valeurs dans la table job_db_copy :??: Donc tu insères avant de faire l'update :??:

Reply

Marsh Posté le 07-12-2007 à 17:21:48    

PAr l'exemple : :)
 
J'ai un ligne
 
EXPDX84E,2007-01-30  23:50:30,2007-01-30  23:50:30,00:00:00,COMPLETE,/unicenter/log/EXE0PDX8.EXPDX84E.0001.20070130-235030,freo0092
 
Je teste si le nom de serveur est connu dans srv_ref :
Non => je cré le nom de serveur dans srv_ref et recupere son id pour l'ulitiser dans la table job_db_copy.
Donc oui, avant l'insert.
 
Je teste si le nom du job est connu dans job_ref :
Non => je cré le nom du job dans job_ref et recupere son id pour l'ulitiser dans la table job_db_copy.
Donc oui, avant l'insert.
 
 
 
Oui => je teste la présence du couple job_name et job_start dans la table job_db_copy
- Non Présent : je peux donc insérer ma ligne dans job_db_copy, car je suis sur que ce n'est pas un doublon ou un doublon a mettre a jour.
- Présent : update dans job_db_copy de ligne a mettre a jour.
 
Sachant que quand j'insere dans job_db_copy, je dois trouver un server_name_id et un job_name_id a la place des vrais valeurs (histoire que ce soit plus facile a administrer)
 
Voili, je sais pas si c'est clair....
 
En gros , pour chaque enregistrement server_name et job_name, ils doivent etre impérativement reférencés dans les tables job_ref et srv_ref (eh oui, comme ca j'ai un id ;))


Message édité par hornetmen le 07-12-2007 à 17:24:10
Reply

Marsh Posté le 07-12-2007 à 17:42:13    

Donc utilises les triggers pour tes enregistrements dans les tables de références :)
 
Colle un index unique sur ce qui doit l'être, te pose pas de question et fait un insert on duplicate key update: si y'a rien à faire il le fera pas, si y'a duplication de la clé il update ce que tu veux :)
 
Fais une requête préparée avec un insert de masse et ça devrait passer bien plus rapidement :)

Reply

Marsh Posté le 07-12-2007 à 17:47:09    

Oui ca me semble bien plus simple comme ca.
Dans la pratique, je n'ai pas les connaissances pour le faire. .....  :jap:

Reply

Marsh Posté le 09-12-2007 à 12:41:56    

Commence par les inserts, rejouter un index unique c'est rien, au pire utilise phpmyadmin y'a qu'à cliquer.
 
http://dev.mysql.com/doc/refman/5. [...] index.html
 
Pour le on duplicate key, suffit de faire ton insert normal et de rajouter "on duplicate key update col=valeur" tout simplement.
 
Pour le trigger, ça va être le plus dur mais au final rien de bien insurmontable :) L'avantage c'est que ta logique applicative est déportée sur le sgbd donc plus besoin de s'en occuper et l'intégrité est garantie.
 
http://dev.mysql.com/doc/refman/5. [...] ggers.html
http://maximilian.developpez.com/m [...] mysql5/#LB

Reply

Marsh Posté le 09-12-2007 à 13:39:08    

A mon avis tu devrais utiliser des tableaux associatifs de PHP.
 
Tu fais 4 grosses select sur tes tables de references et tu stock tout dans des tableaux associatifs qui fond correspondre nom => cle.
 
Ensuite tu boucles sur ton fichier et tu fais
 

Code :
  1. foreach($lignes as $ligne) {
  2.   $info = $ligne[2];
  3.   $mon_serveur = $ligne[4];
  4.   if(!array_key_exists($mon_serveur, $serveurs)) {
  5.     mysql_query('INSERT INTO serveur .........', $conn);
  6.     $serveurs[$mon_serveur] = mysql_insert_id($conn); 
  7.   }
  8.   mysql_query('INSERT INTO lignes (info, serveur) VALUES (\''.$info.'\', '.$serveurs[$mon_serveur].');', $conn);
  9. }


 
De cette manière tu fais grossir tes tableaux de cle etrangere à la volée sans besoin de faire du SQL pour récupérer les cles.
 

Reply

Marsh Posté le 09-12-2007 à 23:58:58    

Ou comment sortir la moissonneuse pour récupérer 2kg de blé...
Surtout que ça change rien au problème de base: vérifier et agir en conséquence ;)

Reply

Marsh Posté le 10-12-2007 à 16:43:28    

leflos5 => Si ta réflexion s'adresse à ma proposition, je ne vois pas en quoi mon idée est plus couteuse dans la mesure ou il y aura une insert pour chaque ligne de chaque table et les consultations se feront via des tableaux phps donc accès mémoire et non fichiers.
 
Alors explique moi en quoi c'est contraignant ?

Reply

Marsh Posté le 10-12-2007 à 18:13:16    

dans un cas tu laisses le sgbd (dont c'est le métier) s'en occuper.
Dans l'autre tu laisses le soin au developpeur de se débrouiller pour gérer correctement des tableaux monstrueux ( enfin qui peuvent l'être s'il y a beaucoup d'enregistrement à faire).
 
 

Reply

Marsh Posté le 11-12-2007 à 13:59:18    

+1  
sans parler du coût en mémoire et en traitement :)
Alors que le sgbd lui mutualisera les ressources utilisées, pas le script :)
 
Si c'est une machine dédiée juste pour ça, juste pour quelques fois, je suis d'accord qu'on peut sortir le tractopelle pour un gravier, ça va plus vite que de chercher la balayette qu'on sait plus où elle peut se trouver et faire perdre 2h :D
Mais faut penser aussi au coût ne serait ce en temps pour les MAJ si doit y en avoir souvent ;)
 
 
L'avantage de déplacer la logique applicative sur la base c'est qu'après t'as plus besoin de te soucier de quoi que ça soit à ce niveau et donc plus de bug de donnée.

Reply

Marsh Posté le 11-12-2007 à 16:30:30    

Vos concepts sont exacts mais s'adapte a des applications pas à des scripts de transitions ou de conversion.
 
En l'occurence entre générer des SELECT à la volée pour faire des tests de cohérence et la consultation d'un Array, j'opterai pour le Array, d'autant que tu n'as à modifier ta configuration serveur en utilisant ini_set et set_time_limit.

Reply

Marsh Posté le 11-12-2007 à 17:53:06    

nan mais le truc que t'as pas compris c'est qu'on ne recommande pas non plus de génèrer  "DES" selects, mais qu''une seule requête gère l'insertion/mise a jour ( voir de deux si une seule est trop compliquée à écrire).
 
Et même pour des scripts de transitions ou de conversion, ce que tu recommandes n'est que rarement utilisable.
Il y a quelques semaines, on devait importer le fichier Insee des entreprise dans une base ( 220K lignes pour environ 250Mo) et bien je te garantis qu'en utilisant ta méthode le serveur aurait lentement succombé...
Et pourtant c'était bien un script de transition/conversion.  [:spamafote]

Reply

Marsh Posté le 12-12-2007 à 02:28:03    

D'où ma réponse: si c'est pour faire une moulinette foireuse pour une fois ça sera plus rapide à mettre en oeuvre de faire un truc foireux (maintenant un bug au milieu et zou la cohérence d'où l'importance d'avoir une base qui gère le plus possible la cohérence) pour une fois je suis d'accord.
 
Mais comme le dis anapajari, ça dépend aussi du volume, des performances du système, du temps qu'on a à accorder à la MAJ, de l'impact résonnable que l'on peut s'autoriser...
 
 
Bref si c'est pas pour une fois pour quelques milliers de tuples on vire vite au drame en encourageant qui que ça soit à aller dans le sens du script vilain pour "dépanner" qui mettra à genoux les machines avec leurs utilisateurs :)
 
Enfin on sait pas vraiment le contexte et les contraintes de temps/disponibilité donc :spamafote:

Reply

Marsh Posté le 12-12-2007 à 11:20:02    

Il a un fichier de 4Mo et les array qui sont créée à la volés sont la pr gérer l'unicité des clef étrangères donc à priori ne devrait pas grossir des masses :s  
Le contexte m'as semblé permettre l'utilisation de cette moulinette qui n'est pas "foireuse".
J'admet qu'elle fait le boulot qui ne lui est théoriquement pas donné à faire mais elle ne le fera pas mal.
 
Maintenant ce que j'ai pris en compte cette personne à l'air peu familière avec le SQL et j'essaiyai donc de lui expliquer une autre vision du problème.
 
Pour le SQL sinon l'aspect de faire de l'INSERT IGNORE sur un champ UNIQUE est peut être un procédé un peu compliqué, je te conseillerai dans un premier temps de bien apréhender la différence entre INSERT et REPLACE que mysql propose.
 

Reply

Marsh Posté le 12-12-2007 à 11:23:56    

Attention avec REPLACE. Ca revient à faire un delete (basé sur la clé primaire de la table) suivit d'un insert. Si t'as d'autres tables qui utilisent les id de celle ci alors il ne faut surtout pas faire de REPLACE sous peine de ne plus avoir la moindre cohérence entre ta table et les autres.

Reply

Marsh Posté le 12-12-2007 à 11:26:19    

C'est pas de l'autoincrement ici

Reply

Marsh Posté le 12-12-2007 à 11:47:10    

yellu > Regarde mieux les structures des tables qu'il utilise, moi je vois bien un autoincrément dans job_db_copy, job_ref et srv_ref. Ta remarque est donc fausse. Par contre, vu la structure de sa base, mon intervention est hors sujet vu qu'il ne peut pas faire de replace vu que sa clé primaire contient entre autre la colonne "auto-incrémenté". S'il voulait faire un replace dans ces conditions, alors il faudrait d'abord qu'il cherche les id de la colonne auto-incrémenté et dans ce cas autant faire ensuite un replace classique.
 
PS : Quelqu'un voit un intérêt à la création d'une clé primaire qui contient à la fois une colonne autoincrément et d'autres colonnes?


Message édité par omega2 le 12-12-2007 à 11:48:39
Reply

Marsh Posté le 12-12-2007 à 13:45:35    

Je parle des référent pas de la table principal dans laquelle il n'y aura que des insertions.
 
Il inserre des objets dans une table cette objet a une clef etrangere, il se demande si il doit créer une ligne pour cette objet etranger ou non, il peut faire un REPLACE dans la table de cet objet étrangère en forçant le primary key avec la valeur qu'il avais dans la table principale.

Reply

Marsh Posté le 13-12-2007 à 10:30:45    

Bonjour :)
 
Je vois qu'il y a matiere.
Le contexte est le suivant :
 
J'ai un serveur disponible et qui ne sert uniquement à heberger la base Mysql et la partie Apache/PHP.
Je peux etre gourmant donc, pas de haute dispo rien du tout.
 
Je tente actuellement d'ecrire les requetes qui me permettent de faire les INSERT/UPDATE à partir des données injectées dans la table temporaire mais j'en suis encore......dans le néant :)
 

Reply

Marsh Posté le 13-12-2007 à 22:42:12    

En ce qui me concerne, je maintiens ma proposition pour une seule chose: faire propre et aussi aller là où on maitrise pas pour tester et savoir faire après!
 
Si ça presse fais le vilain tableau... Ou ta méthode requête par requête pour chaque ligne :spamafote:
 
Toutes les solutions marcheront, la plus intéressante intellectuellement étant de se servir du sgbd et ses contraintes d'intégrité + trigger (et pourquoi pas une procédure stockée :D ), ce qui est son boulot, pas besoin de réinventer la roue carrée ( :whistle: )

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed