MySQL => UPDATE à la place de INSERT ? possible ?

MySQL => UPDATE à la place de INSERT ? possible ? - SQL/NoSQL - Programmation

Marsh Posté le 18-01-2006 à 17:41:01    

Bonjour.  
Afin d'éviter les doublons je voudrais faire un update mais je me suis pris la tête avec des routines pas possibles du style  
"je compte le nombre d'enregistrements identiques à celui inséré"
"si il y a deja un enregistrement je passe mais je mets à jour"
"si il n'y a pas d'enregistrement j'ajoute"
 
C'est long et il faut à peu pres une heure pour trier ma base de données (20000 enr. environ)
 
Je voudrais savoir comment faire une sorte de "UPDATE" afin d'inserer les données SI ELLES N'EXISTENT PAS...
 
Z'auriez pas un exemple ?
Merci


Message édité par erwan83 le 20-01-2006 à 17:00:20

---------------
http://www.ypikay.com
Reply

Marsh Posté le 18-01-2006 à 17:41:01   

Reply

Marsh Posté le 18-01-2006 à 18:17:20    

Reply

Marsh Posté le 18-01-2006 à 18:54:30    

Yop... merci bien  
vais voir ça


---------------
http://www.ypikay.com
Reply

Marsh Posté le 18-01-2006 à 18:58:30    

Ouais pas mal...
 

Citation :

REPLACE fonctionne exactement comme INSERT, sauf que si une vieille ligne dans la table à la même valeur qu'une nouvelle pour un index UNIQUE ou une PRIMARY KEY, la vielle ligne sera effacée avant que la nouvelle ne soit insérée. See Section 13.1.4, « Syntaxe de INSERT ».


 
... mais je ne peux pas redefinir le champ voulu comme Primaire...


---------------
http://www.ypikay.com
Reply

Marsh Posté le 18-01-2006 à 19:13:15    

comme j'ai pas trop de détails concernant ce que tu veux faire, je vais te donner une piste pour un update/replace anti doublons
 
tu fais 2 tables
 
la première est une copie conforme de la table que tu va mettre à jour
 
la deuxième contient uniquement les données à modifier (donc lignes à mettre à jour et à insérer)
 
l'idée est la suivante
 
faire une requête SELECT qui jointe les 2 tables, en ne sortant que les lignes présentes dans la seconde (on va pas tout recopier hein :p) et la jointure sert à sortir les champs modifiés au lieu de ceux de la copie
 
en gros, ça te sort un tuple complet avec les infos à jour  
 
il reste juste à ajouter un REPLACE INTO ... avant cette requête pour que ces lignes soit insérées / remplacées dans la table d'origine
 
j'espère que c'est à peu près clair, sinon j'essaierais de filer un exemple précis
 
EDIT :en fait c'est pas clair du tout :pt1cable:


Message édité par Sh@rdar le 18-01-2006 à 19:13:52

---------------
La musique c'est comme la bouffe, tu te souviens du restaurant dans lequel t'as bien mangé 20 ans plus tôt, mais pas du sandwich d'il y a 5 minutes :o - Plugin pour winamp ©Harkonnen : http://harko.free.fr/soft
Reply

Marsh Posté le 18-01-2006 à 19:19:25    

Je te montre ce que je veux faire
 

Citation :

CREATE TABLE moteur (  `date` timestamp NOT NULL,  insertion text NOT NULL,  categorie text NOT NULL,  `type` text NOT NULL,
  navigateur text NOT NULL,  url text NOT NULL,  serveurenvoi text NOT NULL,  ipenvoi text NOT NULL,  motcle text NOT NULL,
  description text NOT NULL,  `match` text NOT NULL,  truc text NOT NULL,  cle bigint(20) NOT NULL,  PRIMARY KEY  (cle)) TYPE=MyISAM;


 
tu vois le type de structure ok ?  
j'ai une  clé unique sur "cle" qui est un auto increment
or je voudrais ajouter une clé sur "url" qui est, dans mon cas, le champ à verifier.
mais je veux garder mon auto increment sur "cle"...
Pas chiant le mec...


---------------
http://www.ypikay.com
Reply

Marsh Posté le 18-01-2006 à 19:24:36    

miam, tout en text en plus :) et y'a pas d'auto increment là mais c'est pas grave :D
 
je vais essayer d'illustrer mon truc
 
EDIT : de où elles sortent les lignes que tu va mettre à jour ?


Message édité par Sh@rdar le 18-01-2006 à 19:25:02

---------------
La musique c'est comme la bouffe, tu te souviens du restaurant dans lequel t'as bien mangé 20 ans plus tôt, mais pas du sandwich d'il y a 5 minutes :o - Plugin pour winamp ©Harkonnen : http://harko.free.fr/soft
Reply

Marsh Posté le 18-01-2006 à 19:28:10    

d'un logiciel qui scanne... il me pond des lignes ... INSERT INTO...  
mais pourtant y'a un auto increment mais bizarre il apparait pas.
mais bon, pas grave. si je veux coller un index ou une clé primaire sur "url" je suis obligé de le redéfinir en VARCHAR non ?
le probleme c'est la limitation à 255 caractères...


---------------
http://www.ypikay.com
Reply

Marsh Posté le 18-01-2006 à 19:30:14    

justement j'ai du virer l'auto increment tu as raison car Mysql refuse de coller deux clés dans la meme table
à l'origine c'etait sur "cle"


---------------
http://www.ypikay.com
Reply

Marsh Posté le 18-01-2006 à 19:32:35    

mais si je cree une clé primaire sur "url" je ne peux plus définir "cle" comme auto-increment
 

Citation :

Incorrect table definition; there can be only one auto column and it must be defined as a key


 
 :pt1cable:  :pt1cable:  :pt1cable:


---------------
http://www.ypikay.com
Reply

Marsh Posté le 18-01-2006 à 19:32:35   

Reply

Marsh Posté le 18-01-2006 à 19:35:05    

alors, prenons la table suivante
 
| PK | Data | Blabla | Truc  
 
admettons que je veuille mettre à jour le champs Data sans toucher au reste, et que je n'ai que Data et Truc dans ma source de données (un fichier CSV au hasard)
 
manque de bol, c'est PK ma clef primaire, donc un REPLACE va me foutre le boxon :( :(
 
pas de panique, on peut tricher un peu le REPLACE :)
 
je crée une copie complète de cette table
 
je crée une table dans laquelle je vais stocker ma source de données
 
| DataM | TrucM |
 
alors, pour faire un REPLACE propre, je dois lire les infos que j'ai actuellement, en prenant les champs modifiés dans la seconde table fraichement créée
 
ça fait un SELECT tout bête, avec une jointure et une clause WHERE !ISNULL() sur mon champ de jointure (pour que le tuple sorti ne contienne que les lings à modifier et pas toute la table)
 
la requête me sort un tuple dans ce style là :
 
| PK | DataM | Blabla | TrucM
 
il "suffit" de faire un REPLACE .. SELECT pour lire ces lignes là, et les insérer  dans la table d'origine, et si PK est identique, les lignes seront remplacées
 
 
c'est plus clair là ?
 
 
perso j'utilise ça avec des tables HEAP pour mettre à jour un catalogue de prix en fonction de la référénce produit (alors que ma clef primaire est un entier standard), ça marche très bien :)


Message édité par Sh@rdar le 18-01-2006 à 19:36:30

---------------
La musique c'est comme la bouffe, tu te souviens du restaurant dans lequel t'as bien mangé 20 ans plus tôt, mais pas du sandwich d'il y a 5 minutes :o - Plugin pour winamp ©Harkonnen : http://harko.free.fr/soft
Reply

Marsh Posté le 18-01-2006 à 19:37:42    

Heu... ben oui... mais c'est ce que je faisais deja avant...
Mais P*tain que c'est looooooooooooooooong...
Merci en tout cas


---------------
http://www.ypikay.com
Reply

Marsh Posté le 18-01-2006 à 19:38:34    

vu la structure de ta table c'est pas étonnant :D
 
que des champs TEXT, pas d'index, faudrait peut être optimiser un peu tout ça non ?


---------------
La musique c'est comme la bouffe, tu te souviens du restaurant dans lequel t'as bien mangé 20 ans plus tôt, mais pas du sandwich d'il y a 5 minutes :o - Plugin pour winamp ©Harkonnen : http://harko.free.fr/soft
Reply

Marsh Posté le 18-01-2006 à 19:42:24    

admettons que je place un champ url de type VARCHAR... donc limité à 255... si un gazier me colle une entrée de 256 caractères, ca va me mettre la zone...
"insertion" correspond à une date rentrée par la machine, la longueur est toujours la meme. j'aurais peut etre interet à lui donner une longueur fixe... "ipenvoi" aussi...


---------------
http://www.ypikay.com
Reply

Marsh Posté le 18-01-2006 à 19:46:34    

une date ça se stocke dans un champ approprié
 
une IP c'est 15 caractères max
 
enfin bref, y'a vraiment moyen d'alléger le truc , tout TEXT c'est extra bourrin
 
ta cle en bigint(20), même pas unsigned c'est de l'artillerie lourde pour 20 000 lignes
 
tu peux aussi faire des tables de jonction avec des références numériques etc etc, un MCD ça sert :)


Message édité par Sh@rdar le 18-01-2006 à 19:48:14

---------------
La musique c'est comme la bouffe, tu te souviens du restaurant dans lequel t'as bien mangé 20 ans plus tôt, mais pas du sandwich d'il y a 5 minutes :o - Plugin pour winamp ©Harkonnen : http://harko.free.fr/soft
Reply

Marsh Posté le 18-01-2006 à 20:17:43    

MCD ? Kezako ?
oui j'ai allégé l'adresse ip en 15 caractères et je vais bloquer les mots clés à 100 caractères... y'en a qui mettent plus de 1000 caractères dans les mots clés faut voir ça...
mais je dois tout re-injecter, je suis entrain de verifier toutes les adresses de la base... deja 5000 scannées... lol
Z'auriez pas un processeur et un peu de bande passante ???
Bon suffit les bétises...
Qu'est ce donc qu'un MCD ?


---------------
http://www.ypikay.com
Reply

Marsh Posté le 18-01-2006 à 20:18:42    

Modèle Conceptuel de Données


---------------
La musique c'est comme la bouffe, tu te souviens du restaurant dans lequel t'as bien mangé 20 ans plus tôt, mais pas du sandwich d'il y a 5 minutes :o - Plugin pour winamp ©Harkonnen : http://harko.free.fr/soft
Reply

Marsh Posté le 18-01-2006 à 22:09:30    

Bon j'en reste là pour ce soir mais je pense que je vais relancer le topic demain...
Merci à tous !!!


---------------
http://www.ypikay.com
Reply

Marsh Posté le 19-01-2006 à 07:38:46    

Ah haaaa...  :)  
 

Citation :

CREATE TABLE moteur (
  `date` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  insertion varchar(19) NOT NULL default '',
  categorie text NOT NULL,
  `type` varchar(25) NOT NULL default '',
  url varchar(255) NOT NULL default '',
  ipenvoi varchar(15) NOT NULL default '',
  motcle varchar(110) NOT NULL default '',
  description varchar(175) NOT NULL default '',
  `match` varchar(110) NOT NULL default '',
  truc text NOT NULL,
  cle bigint(7) NOT NULL auto_increment,
  PRIMARY KEY  (cle))


 
là deja ca booste un peu plus... surtout, j'ai pu "brasser les données" et virer les sites avec une description de 250... pages. idem pour les mots clés... record trouvé : 2500 mots clés... faut le faire !
Bon c'est pas tout mais je vais bosser moi !


---------------
http://www.ypikay.com
Reply

Marsh Posté le 19-01-2006 à 11:44:11    

Comment on fait pour faire une base de données quand on ne sait pas ce que c'est qu'un MCD? :??:  
 
(cherche Merise - MCD sur google)

Reply

Marsh Posté le 19-01-2006 à 12:09:34    

on réfléchit à l'architecture de la base et on en fait un sans le savoir :D


---------------
La musique c'est comme la bouffe, tu te souviens du restaurant dans lequel t'as bien mangé 20 ans plus tôt, mais pas du sandwich d'il y a 5 minutes :o - Plugin pour winamp ©Harkonnen : http://harko.free.fr/soft
Reply

Marsh Posté le 19-01-2006 à 12:09:51    

Bon soyons serieux trente secondes lol


Message édité par erwan83 le 19-01-2006 à 17:15:24

---------------
http://www.ypikay.com
Reply

Marsh Posté le 19-01-2006 à 17:23:18    

MCD oui ok j'ai vu...
Pour le moment je reste avec un projet simple...
Pas encore besoin de telle prise de tête...
mais ca viendra sans doute


---------------
http://www.ypikay.com
Reply

Marsh Posté le 19-01-2006 à 17:28:07    

Bon en tout cas un grand merci à tous...
En effet en redéfinissant le champ url en index, ca m'a permis de virer tous les doublons...


---------------
http://www.ypikay.com
Reply

Marsh Posté le 19-01-2006 à 20:53:01    

plutôt que de chercher des solutions de kosovar, pkoi ne pas utiliser les nouveautés de MySQL ? Vous savez, les trucs que tous les autres SGBD savent faire depuis 10 ans... Et qui servent justement à faire des trucs propres et complexes...
 
Un trigger "on before insert" ça me semble pas mal...

Reply

Marsh Posté le 19-01-2006 à 20:54:37    

Vous auriez un exemple SVP ?


---------------
http://www.ypikay.com
Reply

Marsh Posté le 19-01-2006 à 20:57:03    

Ben cherche dans le doc de MySQL 5, parceque moi je sais faire sous SQL Server, PostGre et Oracle, mais vu qu'entre les trois la syntaxe est à chaque fois différente, je doute que MySQL soit pareil.
 
En tout cas c'est ce qu'il y a de plus simple et de plus sûr. (mise à part désactivation manuelle du trigger, il se déclenchera à coup sûr à chaque tentative d'insertion dans la table)

Reply

Marsh Posté le 19-01-2006 à 20:57:52    

en gros, l'algo du trigger ce serait :
 
si newID déjà présent
   update ...
sinon
   insert ...
fsi
 
Et zou.
 
Après t'as plus qu'à faire des insert dans la table sans te soucier de savoir ce qu'il y a dedans


Message édité par Arjuna le 19-01-2006 à 20:58:28
Reply

Marsh Posté le 19-01-2006 à 20:58:14    

bon je vais chercher mais je crains que ce soit trop lourd quand même...
merci bien


---------------
http://www.ypikay.com
Reply

Marsh Posté le 19-01-2006 à 20:58:51    

c'est pourtant bête comme choux... surtout à l'utilisation par la suite

Reply

Marsh Posté le 19-01-2006 à 21:01:02    

ben c'est ce que je fais deja
 

Citation :

 $select = " SELECT count(cle) FROM `moteur` WHERE `url` LIKE '($url)' ";
  $result2 = mysql_query($select,$link)  or die ('Erreur8 : '.mysql_error() );
  $row = mysql_fetch_row($result2);
  $affic = $row[0];
  if ($affic == 0)    
  {  
  $droit="0";
  $sql = mysql_query("INSERT INTO `moteur2` (`categorie`, `type`, `insertion`, `url`, `description`, `match`, `truc`) VALUES ('$categorie', '$type', '$insertion', '$url', '$description', '$match', '$truc')" );
  }
  else    
  {    
  $droit="1";
  print("doublon pour ".$url."... " );
  print("<br>" );
  }    


 
Mais c'est longggggggggggg
très longggggggggggg
 
PS c'est dans du PHP


---------------
http://www.ypikay.com
Reply

Marsh Posté le 19-01-2006 à 21:03:22    

A priori, ça doit donner un truc du genre :
 

Code :
  1. CREATE TRIGGER testtg BEFORE INSERT ON tatable
  2.   FOR EACH ROW BEGIN
  3.     IF EXISTS(SELECT NULL from tatable WHERE ID = NEW.ID) BEGIN
  4.        UPDATE tatable SET val1 = NEW.val1, ... WHERE ID = NEW.ID;
  5.        DELETE NEW;
  6.     END;
  7.   END;

Reply

Marsh Posté le 19-01-2006 à 21:06:39    

AH AH... ca me parait etre un script tout a fait sympa...
Je vais voir ce que ca donne.
Merci du coup de main


---------------
http://www.ypikay.com
Reply

Marsh Posté le 19-01-2006 à 22:59:11    

en même temps balancer un trigger a une personne qui ne sait pas ce qu'est un MCD c'est totalement suicidaire :)


Message édité par Sh@rdar le 19-01-2006 à 22:59:28

---------------
La musique c'est comme la bouffe, tu te souviens du restaurant dans lequel t'as bien mangé 20 ans plus tôt, mais pas du sandwich d'il y a 5 minutes :o - Plugin pour winamp ©Harkonnen : http://harko.free.fr/soft
Reply

Marsh Posté le 19-01-2006 à 23:01:21    

Ohhhh tout de suite....
J'apprends vite tout de même...
:)  :hello:


---------------
http://www.ypikay.com
Reply

Marsh Posté le 19-01-2006 à 23:04:13    

le problème n'est pas là, c'est comme vouloir courir avant de savoir marcher :)


---------------
La musique c'est comme la bouffe, tu te souviens du restaurant dans lequel t'as bien mangé 20 ans plus tôt, mais pas du sandwich d'il y a 5 minutes :o - Plugin pour winamp ©Harkonnen : http://harko.free.fr/soft
Reply

Marsh Posté le 19-01-2006 à 23:07:27    

Ben p'tetre bien oui en effet. je dirais que le probleme est comme tout ce que l'on fait sur internet, on est vite confronté à des besoins de faire évoluer un système, ensuite pour mon cas le problème vient de la taille de la base de données. ce week end je vais la decouper en plusieurs morceaux parce que là, ca commence à etre enorme... mais je suis tout seul pour faire ce petit site et je bosse dur dessus... C'est mon passe temps...


---------------
http://www.ypikay.com
Reply

Marsh Posté le 19-01-2006 à 23:08:47    

vi, mais concentre toi avant tout sur l'architecture de tes données, sépare les gros champs gourmands et peu utilisés en recherche pour alléger tes traitement  
 
y'a tout un processus d'optimisation à assimiler :)
 
une base de 5Mo qui rame, ce n'est pas normal, c'est un défaut de conception


Message édité par Sh@rdar le 19-01-2006 à 23:09:20

---------------
La musique c'est comme la bouffe, tu te souviens du restaurant dans lequel t'as bien mangé 20 ans plus tôt, mais pas du sandwich d'il y a 5 minutes :o - Plugin pour winamp ©Harkonnen : http://harko.free.fr/soft
Reply

Marsh Posté le 19-01-2006 à 23:29:57    

oui mais le type de requetes est compliqué et je suis parti sur une mauvaise base. en fait j'ai stocké la description le titre et les mots clés dans le champ "truc" (y va me tuer...) et je balance une seule requete sur ce champ pour eviter de faire trois requetes... faudrait peut etre que je fasse trois requetes tout de même... Un peu bourin...  
Mais toujours le même problème : j'ai 8 requetes differentes : j'inclus dans ma fenetre d'affichage un SWITCH (la je pars dans le PHP) et en fonction ...
 
a/ du nombre de mots : 1, 2, 3 ou 4
b/ du type de recherche : string complet ou chaque mot n'importe ou
 
j'integre une routine qui :
a/ calcule le nombre d'enregistrements contenant la requete
b/ les affiche
c/ enregistre la requete, le nombre de fois qu'elle a été demandée, le nombre de resultats trouvés pour la derniere demande dans une table à part avec un UPDATE, ça évite les plaisanteries de potaches)
ensuite je remets a plat la table requete (ya un petit malin une fois qui a balancé 500 fois la même requete ça m'a calmé)
 
Alors je me demandais...
A/ séparer les resultats en fonction du nom de domaine qui est deja un champ connu (.fr .com .lu .be .....)
===> je crée une table France, une table Luxembourg, une table Suisse, une table Belgique, une table .com
ça allegera deja les tailles des tables...
B/ lors de la requete, je fais un UNION entre les resultats de toutes ces tables, sachant que j'effectuerai une requete du style
 
SELECT 'les champs' FROM FranceTable WHERE Motcle REGEXP input OR Description REGEXP input OR Match REGEXP input  
UNION
SELECT 'les champs' FROM LuxembourgTable WHERE Motcle REGEXP input OR Description REGEXP input OR Match REGEXP input  
UNION
SELECT 'les champs' FROM SuisseTable WHERE Motcle REGEXP input OR Description REGEXP input OR Match REGEXP input  
UNION
SELECT 'les champs' FROM ComTable WHERE Motcle REGEXP input OR Description REGEXP input OR Match REGEXP input

 
Voila ou j'en suis


Message édité par erwan83 le 19-01-2006 à 23:32:04

---------------
http://www.ypikay.com
Reply

Marsh Posté le 19-01-2006 à 23:39:09    

Non, ce système sera pire.
 
Si j'ai bien compris, tu fais des recherche de mots (1 à 4) sur la description du site, c'est bien ça ?
 
Je vois le mot "match" dans ta requête, mais ça ne semble pas être le mot-clé de MySQL pour la recherche lexicale, mais plutôt le nom d'un champ. Je ne sais pas trop ce que sont ces "REGEXP", mais ça ressemble bien à du LIKE déguisé. Cherche pas plus loin, c'est ça le problème de ton système. Même pourrie, y'a pas de raison qu'avec 5 Mo ça ramme... Sauf avec l'utilisation de LIKE.
 
Concentre-toi donc en premier sur les fonction d'indexation de texte de MySQL, notamment le mot-clé "MATCH". Tu devrais trouver pas mal de doc sur le sujet, et des gens qui pourront t'aider ici.
 
En tout cas, ne splite pas tes tables en plusieurs, surtout si c'est pour faire un UNION dessus ensuite, y'a rien de pire.
 
Par contre, si t'as l'extension du DNS qui entre en jeu dans tes filtres, tu ferais bien de mettre cette info toute seule dans un champ, et l'indexer correctement, tu vas gagner beaucoup de temps.
 
En parlant d'indexation, vérifie que tes champs sont indexés correctement en fonction de tes filtres. Pour 5 Mo tu vas pas voir grand-chose, mais quand t'aura 5 Go, tu verras que c'est bien de concerver les mêmes perfs que quand elle faisait 5 Mo ;)

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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