Mangeur de cigogne Hébergement du site en PHP et Mysql par WDMédia-hébergement
Vous aussi adpotez les éléPHPants de Vincent Pontier !


Rechercher dans le forum

Mots-clés :

Trouver :
un de ces termes tous les termes

Depuis :
7 j 15 j 30 j


Retour à l'index du forum

Update from

Message original de Alph

Le : 18/11/2008 à 16:36:26

Dejà lu 392 fois avant vous

Bonjour,
Soit 2 tables (1 temporaire [10 champs] et 1 permanente [40champs dont les 10]) : Je souhaitais mettre à jour quotidiennement la permanente à l'aide de la temporaire.
Sachant qu'il y a plusieurs milliers d'enregistrements, je voulais automatiser ce transfert, sachant qu'il existe 2 cas :
1. l'enregistrement n'existe pas dans la permanente : insert into.
2. l'enregistrement existe deja dans la permanente : update from.

Outre le fait que je ne vois pas comment Mixer les 2 cas, j'ai tenté un début avec :

$requete="UPDATE [only] perma
SET perma.nom_contact = temp.nom_contact,
perma.adr1_contact = temp.adr1_contact,
perma.adr2_contact = temp.adr2_contact,
perma.adr3_contact = temp.adr3_contact,
perma.resp_contact = temp.resp_contact,
perma.type_contact = temp.type_contact,
perma.vend_contact = temp.vend_contact,
perma.pass_contact = temp.pass_contact,
perma.tel1_contact = temp.tel1_contact
FROM temp WHERE perma.id_contact = temp.id_contact";
$result = mysql_query($requete,$link)  or die ('Erreur : '.mysql_error() );



Question :
1. Pourquoi erreur de syntaxe il y a ?
2. Y'a t il un moyen de mixer les 2 requetes (insert si no exist et update si existe)

Merci

Re: Update from

Réponse de Maljuna Kris

Le : 18/11/2008 à 16:42:18

Saluton,
As-tu essayé INSERT ... ON DUPLICATE KEY UPDATE ?

Sinon il va falloir passer par un trigger.

Re: Update from

Réponse de Alph

Le : 18/11/2008 à 16:45:17

j'avoue ne pas connaitre DU TOUT ni le on duplicate, ni le trigger :( je m'en vais me documenter de ce pas.

Re: Update from

Réponse de Alph

Le : 18/11/2008 à 17:29:57

Re,

Après 45 min a dépioter le web, je conclus :
- que le ON Duplicate pourrait être approprié, mais que je ne vois pas comment le déclarer. (malgré des commentaires sur le web comme quoi bien pour peu de données).
- que les triggers, c'est pas encore pour moi.

Ce qui m'est le plus dur a comprendre est la facon de boucler une requete (while, foreach .... afin de repeter la requete sur tout mes enregistrements).

Merci tt de meme

Re: Update from

Réponse de Maljuna Kris

Le : 18/11/2008 à 18:58:01

Essaye ça (SGDMK)
<?php
$on_duplicate
="    ON DUPLICATE KEY UPDATE 
                            nom_contact = VALUES(nom_contact),
                            adr1_contact = VALUES(adr1_contact),
                            adr2_contact = VALUES(adr2_contact),
                            adr3_contact = VALUES(adr3_contact),
                            resp_contact = VALUES(resp_contact),
                            type_contact = VALUES(type_contact),
                            vend_contact = VALUES(vend_contact),
                            pass_contact = VALUES(pass_contact),
                            tel1_contact = VALUES(tel1_contact)"

$sql"SELECT * FROM temp";
$result=mysql_query($sql) or die(mysql_error()); // le or die devra être modifié en exploit
while($ligne=mysql_fetch_assoc($result)){    
    
$requete="INSERT INTO perma(id_contact,
                                nom_contact,
                                adr1_contact,
                                adr2_contact,
                                adr3_contact,
                                resp_contact,
                                type_contact,
                                vend_contact,
                                pass_contact,
                                tel1_contact) 
                            VALUES({$ligne['id_contact']},
                                   {$ligne['nom_contact']},
                                   {$ligne['adr1_contact']},
                                   {$ligne['adr2_contact']},
                                   {$ligne['adr3_contact']},
                                   {$ligne['resp_contact']},
                                   {$ligne['type_contact']},
                                   {$ligne['vend_contact']},
                                   {$ligne['pass_contact']},
                                   {$ligne['tel1_contact']})\n"
.$on_duplicate;
    
mysql_query($requete) or die(mysql_error().'<br />'.$requete); // le or die devra être modifié en exploit
    
}
?>

Mais je suis très inquiet puisque tu parles de plusieurs milliers d'enregistrements.

Re: Update from

Réponse de Alph

Le : 19/11/2008 à 09:07:25

Bien le Bonjour,

Je viens de tester ton code, mais je n'ai pas pu aller bien loin. En effet, il semblerait que certains de mes champs qui commencent par des caractères spéciaux embrouille le transfert.
J'ai tenté de mettre des addslashes() pour isoler, mais en vain.

en gros : Erreur de syntaxe près de 'valeurnomcontactpremierelignebdd' à la ligne xx
pour cet exemple :
nom_contact = ", nom" (oui, il y a une virgule tout devant, parfois même un # , un / ou un @) idem pour les adresses.
sinon, l'affichage de la requete donne bien : (les valeurXXXX sont là pour la confidentialité, mais j'ai bien les bonnes données).

INSERT INTO perma (id_contact, nom_contact, adr1_contact, adr2_contact, adr3_contact, resp_contact, type_contact, vend_contact, pass_contact, tel1_contact) VALUES(identifiant, valeurnom , valeuradresse1 , valeuradresse2 , valeuradresse3 , valeurreps , valeurtype, valeurvend, valeurpass, valeurtel) ON DUPLICATE KEY UPDATE nom_contact = VALUES(nom_contact), adr1_contact = VALUES(adr1_contact), adr2_contact = VALUES(adr2_contact), adr3_contact = VALUES(adr3_contact), resp_contact = VALUES(resp_contact), type_contact = VALUES(type_contact), vend_contact = VALUES(vend_contact), pass_contact = VALUES(pass_contact), tel1_contact = VALUES(tel1_contact)

Il semblerait donc que mes caractères spéciaux en début de champs font un peu planter la requête. Comment puis-je les isoler ? (comme mis plus haut, le addslashes() déclaré comme tel ne fonctionne pas)

$requete="INSERT INTO perma(id_contact,nom_contact,adr1_contact,....,tel1_contact) 
VALUES(addslashes({$ligne['id_contact']}),addslashes({$ligne['nom_contact']}),addslashes({$ligne['adr1_contact']}),...
               addslashes({$ligne['tel1_contact']}))\n".$on_duplicate;



En tout cas, merci beaucoup

Re: Update from

Réponse de Alph

Le : 19/11/2008 à 09:18:49

heu... je vais peut être dire une connerie, mais il faudrait pas un "id_contact = VALUES(id_contact),"

ON DUPLICATE KEY UPDATE
-----------------> ICI <------------------------
nom_contact = VALUES(nom_contact),


Sachant que id_contact n'est pas le champ ID en increment auto de la base, mais une valeur VARCHAR (7)

Re: Update from

Réponse de luce

Le : 19/11/2008 à 09:19:39

Salut,

La methode la plus simple si c'est un script qui doit s'executer régulièrement, c'est d'utiliser PDO, qui pour lui, ce style de chose ne sont pas vraiment un probleme.

Par contre, il te faut déjà PDO dans la config php, et si tu avais le driver mysql, ca serait encore plus simple, parce que PDO est assez rescent et peu utiliser, mais génial pour la compatibilité entre les différents type de base de donnée, et pour la sécurité (il s'occupe lui même de sécurisé les requetes, plus besoin de mysql_real_escape_string() !!!)

Re: Update from

Réponse de Alph

Le : 19/11/2008 à 09:31:43

luce !!! pourquoi tu es si brutale au réveil ??? déjà que j'avais du mal a suivre le MK, là je suis perdu ^^ hihihi...

Re: Update from

Réponse de Alph

Le : 19/11/2008 à 09:42:09

un peu de réflexion m'amène à envisager 4 solutions :

- Utiliser un INNERJOIN, mais ca m'arrange pas
- Débloquer le MKcode, malgré son inquietude suite à mes 8000 enregistrements (sur 10 champs)
- Tenter de comprendre le PDO - mais malgré des recherches sur le web, ca reste flou
- Tenter un REPLACE ou UPDATE champ apres champ du style :

UPDATE perma SET perma.nom_contact =
   (SELECT temp.nom_contact FROM temp WHERE perma.id_contact = temp.id_contact)
UPDATE perma SET perma.adr1_contact =   
   (SELECT temp.adr1_contact FROM temp WHERE perma.id_contact = temp.id_contact)
etc...


 NON !!! PAS TAPEEEEEE !! 

Re: Update from

Réponse de Maljuna Kris

Le : 19/11/2008 à 09:50:24

Alph>> Si id_contact n'est pas la PK, tu as raison.
Ceci dit je ne suis pas certain que ton serveur, s'il accepte au bout du compte cette syntaxe, n'explose pas devant une telle kyrielle de requêtes. Avec ou sans PDO >;))

Re: Update from

Réponse de luce

Le : 19/11/2008 à 10:02:06

Bon, je te le fais en douceur alors.

Tu vois, quand tu fais une requete, php envoi la requete a mysql en lui dissant 'demerde toi avec cette merde de requete' et mysql lui repond : ok c'est fait ou alors "hé, mais moi, je comprend rien à ta merde !!!" (je crois que tu es dans ce cas de figure"

Maintenant si tu as PDO, alors php réagit différament :
"Hé, PDO, j'ai une requete, demerde toi avec" <- (il ne dit pas que c'est une requete mysql)
PDO : "hmm, bon attend, ca ressemble à du mysql, est ce que je sais gerer ça (driver mysql doit etre installer sur le serveur, dans phpinfo() c'est PDO_MYSQL)
Puis PDO : "hmmm bon au toi grand mettre de php, oh toi que l'on nomme le grand C, peux tu me sécurisé la requete et prépare puis l'envoye la requete sur la premiere base de donnée que tu trouves"

En clair, PDO s'en fou de comment tu vas coder ta requete, il l'adapte automatiquement la requete au type de base de donnée que tu utilises, tout en demandant au language de programmation C (et pas php/mysql) de sécurisé la requete, donc ton probleme d'échappement, il n'existe plus

Je suis entrain d'apprendre à l'utiliser, et si ton script toi être permanent, je pense que perdre un peu de temps dessus, ca sera un grand atout, surtout que si il est installé sur le serveur (ou si tu peux l'installer), en dehors du fichier de connexion, tu n'as pas grand chose à modifier, les requetes normal fonctionnent d'après ce que j'ai testé.

Va voir : http://php.developpez.com/faq/?page=pdo

Re: Update from

Réponse de luce

Le : 19/11/2008 à 10:05:47

Ah mk a posté !

Pour PDO, ca n'aidera pas dans le cas des 8 000 requetes, mais ça corrigera toutes ces merdouilles de caractères speciaux, il n'aura pas a s'en occuper (donc pas de mysql_real.. htmlentities... et autre fonction) et je pense que C est surement plus rapide que PHP pour gerer ça (une question de logique :P)

Re: Update from

Réponse de Maljuna Kris

Le : 19/11/2008 à 10:15:26

Luce>>Les essais de performance entre MySQL, MySQLi et PDO, ne sont franchement pas en faveur de ce dernier.http://www.nexen.net/actualites/trucs/pdo,_mysql_et_mysqli.php

Re: Update from

Réponse de Alph

Le : 19/11/2008 à 10:18:50

Re,

en fait, je vais exposer mon objectif, peut etre que vous connaitrez une autre methode :

Je désire construire une base de ton mes contacts. Dans ces contacts, il y a 8 000 clients et 40 000 membres.
3 fois par jour, j'exporte d'un logiciel mes 8 000 clients (avec 10 champs) dans ma base temporaire. Jusque là, pas de soucis.

Dans la base permanente, il y a donc 8 000 + 40 000 contacts - avec 40 champs chacun.
Dans les 40 champs, il y en a 10 qui sont commun a ceux de la base temporaire.

Le but est de mettre a jour les 10 champs de mes 8 000 clients [ça change très souvent :( ] sans toucher au 30 autres champs de ces mêmes clients, et sans toucher non plus au 40 champs des 40 000 membres.

 PAS TAPEEEEEEEEEEEEEEEEEEEE !!!!!!            Bis repetita


Merci beaucoup à vous 2

Re: Update from

Réponse de Maljuna Kris

Le : 19/11/2008 à 10:35:12

Si j'ai bien suivi, il y a aussi parmi les 8 000, de nouveaux clients qui ne sont pas dans les 40 000.
40 000, qui peuvent donc très vite devenir 50 000, voire 60 000 etc...
D'où mes inquiétudes.

Re: Update from

Réponse de Alph

Le : 19/11/2008 à 10:50:03

Pour faire simple :
A = 8 000 clients (possibilité d'augmentation par migration des B ou par C)
B = 40 000 membres (possibilité d'augmentation par D uniquement)
C = Inconnu devenant client
D = Inconnu devenant membre

Un membre n'est pas client, sinon il devient client
Un client ne peut pas être membre.

Gnéé ??? je crois que je m'enfonce :s

Re: Update from

Réponse de luce

Le : 19/11/2008 à 11:24:57

Heu...

Bon, je crois que tu as TES serveurS dédiéS.

Franchement, c'est allucinant ce que tu essai de faire, sans compter la mémoire (j'ose pas te demander le contenu des 10 champs).

Mais, est-ce que tu ne préférais pas changer ton architecture, coté serveur, sa sera bien plus simple.

Je parle de créer une nouvelle table, avec ID (membre/client) puis les 10 champs, et les infos de cette table sont prioritaires sur la table à 40 champs, tu aurais plus besoin de transferer tes 8 000 rows toutes les 8 h, tu auras juste à supprimer/ajouter les nouveaux clients toutes les 8 h, ce qui sera LARGEMENT BEAUCOUP PLUS LEGER (et plus simple aussi).

Re: Update from

Réponse de luce

Le : 19/11/2008 à 11:30:53

oups,

MK, un petit PS :

Les tests ne sont pas fiable, donne moi le select qui a été utilisé ?

N'oublie pas que PDO, il sécurise au maximum le contenu de ta variable, et même avec mysql
si tu fais :
SELECT * FROM table WHERE id='17'
comparer à
$var = mysql_real_escape_string('17');
SELECT * FROM table WHERE id='$var'

Je suis sur que la 2eme sera bien plus lente que la premiere, et ca, c'est une des petites équivalence de ce que fait PDO, d'ailleur 0xB227 (c'est celui la je crois) il n'aura pas d'effet, alors que version mysql...

Donc ma question est : dans leurs tests, ont-ils bien comparer avec toutes les sécurités qui sont ajoutées ou pas...

Re: Update from

Réponse de Alph

Le : 19/11/2008 à 11:46:08

luce ! la table dont tu parles existe : il s'agit de la table "temp" actuelle.

Seul soucis, elle provient de l'export de mon logiciel, et ne comporte QUE 10 champs... or j'en ai besoin de 40.
les 30 champs en plus proviennent d'une saisie manuelle... donc je ne vais pas me les retaper a chaque fois.

Quand tu parles de prioritaire, je ne comprends pas très bien.
- cas n°1 : export avec champs identiques à base : pas de modif
- cas n°2 : export avec champs différent à base : modification
- cas n°3 : export avec clients en plus : création dans base principale PUIS création dans table secondaire (celle des 40champs)

je pense que je m'embrouille dans les explications , mais la structure actuelle est :
int(11)
id_contact varchar(7) }
nom_contact varchar(30) }
adr1_contact varchar(30) }
adr2_contact varchar(30) }
adr3_contact varchar(30) } DONNEES ISSUES
resp_contact varchar(25) } DE MON EXPORT SOFT
type_contact varchar(4) }
vend_contact varchar(3) }
pass_contact varchar(8) }
tel1_contact varchar(14) }
---------------------------------------------------------------------------------------
tel2_contact varchar(14)
tel3_contact varchar(14)
tel4_contact varchar(14)
tel5_contact varchar(14)
tel6_contact varchar(14)
tel7_contact varchar(14)
tel8_contact varchar(14)
tel9_contact varchar(14)
tel10_contact varchar(14)
fax1_contact varchar(14)
fax2_contact varchar(14)
numcde_contact varchar(3)
transp_contact varchar(3)
assist_contact varchar(25)
comment_web varchar(255)
comment_pim varchar(255)
codefact_contact varchar(7)
nom1_contact varchar(50)
nom2_contact varchar(50)
nom3_contact varchar(50)
nom4_contact varchar(50)
reseau_contact varchar(255)
equipmt_contact varchar(255)
kaltek_contact varchar(50)
kalgen_contact varchar(50)
nomail_contact smallint(1)
stopmail_contact smallint(1)
nbrelance_contact smallint(1)
mail1_contact varchar(255)
mail2_contact varchar(255)
mail3_contact varchar(255)

P.S : n'ayant pas de prévisualisation, j'espere que ca restera correct

Re: Update from

Réponse de Alph

Le : 19/11/2008 à 14:04:04

re,
l'appetit ne porte pas conseil (ni la digestion d'ailleurs), mais afin de contourner mon problème (ça reste un contournement, je sais) comment pourrais je faire pour que, dans le cas où je ne passe pas par la table temporaire, je puisse faire un import de données dans ma base tel que :

Si id_contact existe ==> replace (avec les 10 champs)
sinon insert into (avec les 10 champs)

A moins que l'on ne trouve une autre solution,.... qu'en pensez vous ???

Merci bcp et bonne digestion à vous aussi;)

Re: Update from

Réponse de Maljuna Kris

Le : 19/11/2008 à 14:35:01

L'idée de luce est à explorer.
Scinder la table en 2, l'une avec les colonnes 1 à 10, l'autre avec les colonnes 11 à 40, les deux liées (relation 1:1) par le même identifiant en FOREIGN KEY dans la deuxième table.
Avantages, la table à UPDATER est beaucoup plus légère et, du même coup, REPLACE convient mieux que UPDATE.

Re: Update from

Réponse de Maljuna Kris

Le : 19/11/2008 à 14:37:08

De toutes façons, j'ai failli m'étrangler en voyant la structure de ta table.
Tu connais le modèle entités-relations ?
Tu sais ce que sont les formes normales ?

Re: Update from

Réponse de Alph

Le : 19/11/2008 à 15:28:32

non, je ne connais pas ce modele, ni ces formes.

Autodidacte, j'apprends peu a peu au fur et a mesure de mes besoins, et de vos precieux conseils.

Lorsque tu parles de scinder les tables en 2, je veux bien.
Mais comment,
1. les lier ???
2. si un nouveau client est créer, comment le créer dans la 2eme ? (a moins que la réponse a la 1ere question réponde à celle ci ...)...

MK, je te prie de m'excuser auprès de dame 4'in... je ne veux pas que tu t'étrangles prématurément (Alzé, c'est déjà pas mal)

Merci !

Re: Update from

Réponse de Maljuna Kris

Le : 19/11/2008 à 15:41:34

Il va te falloir faire quelques lectures saines et instructives.
Lorsque tu crées un client tu récupère l'id (PK AUTOINCREMENT) avec un truc genre mysql_last_insert_id(), c'est cet identifiant que tu mettras dans la deuxième table ou l'identifiant ne devra pas être en AUTOINCREMENT. Le lien se fera donc par jointure sur cette colonne UNIQUE dans les deux tables.
lectures:
http://cyril-gruau.developpez.com/merise/ et/ou http://sqlpro.developpez.com/cours/modelisation/merise/
http://sqlpro.developpez.com/cours/sqlaz/jointures/

Re: Update from

Réponse de luce

Le : 19/11/2008 à 15:43:30

Re,

Bon, pour commencer, c'est pas évident de te donner une bonne idée, vu que c'est toujours vague.

Alors, en regardant la structure de ta table, tu n'as aucun champs "client /membre"

Donc, le seul moyen d'identifier un client, c'est ça présence dans la table temporaire, c'est bien ça ?

Alors, voila, tu fais une requete sql sur la table temp, tu vérifies la présence d'un id,
Si il est présent, alors, tu fais join les 2 tables, mais en selectionnant les 10 champs temp :
SELECT temp.nom_contact ...
sinon, pas de jointure et tu prends les données de la table perma

Maintenant, franchement, je crois que tu devrais tout detruire et tout refaire, au meme, juste ajouter un champs TINY INT (1) avec comme valeur : 1 membre, 2 clients
Et au moins, tu sais quoi regarder.

Mais c'est difficile de repondre concretement, parce que comme dis mk, ton idée, c'est vraiment bourrin alors qu'il existait plein d'autres solutions si tu reprennais la table de a à z

Re: Update from

Réponse de Alph

Le : 19/11/2008 à 16:17:47

Luce, je ne suis vraiment pas contre tout refaire.

J'en suis justement au tout début, et je suis ouvert à toute idée.

J'ai concu la base comme tel car je l'imaginais comme ca, mais sans avoir le recul au niveau des requetes et des optimisations...

J'ai bien compris que je dois faire une table "statut": id (tinyint(1) et designation (varchar(20))
id - designation
1 - membre
2 - clientAvecAchat
3 - clientSansAchat

A coté de ça, j'ai ma table "gafac" qui comprends QUE les clients[8 000] avec 9 champs. Cette table est instruite avec l'export de mon soft. Avec la modif de la mini table, je rajoute 1 champ "statut".
[statut.nom.adresse1.adresse2.adresse3.resp.type.vend.pass.tel1]

Enfin, j'ai une table "membre" qui comprends QUE les membres[40 000] avec 10 champs. Cette table est issue d'une saisie statique : pas de maj auto - juste au cas par cas.
[statut.nom.adresse1.adresse2.adresse3.resp.tel.fax1.mail1.reseau.spe]

Dans les 40 champs, il y a donc les 9 champs de gafac ainsi que ceux qui ne sont pas communs aux 2
La liste des 40 champs étant au dessus, je ne vais pas la remettre.

Maintenant, et selon ta conception, quelle(s) table(s) manqueraient il ? quelles sont celles qui devraient etre modifier. Comment Articuler mes 30 autres champs ? Avec une mini table quand c'est possible (souvent les mêmes données).

Je sais que ca reste flou, mais je reste dispo pour tout détails...
Je galere, mais je vois où tu aimerais en venir.

Merci bcp a vous 2

Re: Update from

Réponse de luce

Le : 19/11/2008 à 21:12:20

Re,

Désolée de ne pas avoir répondu plus tot, j'ai recu mon nouveau casque audio USB, surround 5.1, et je me suis regardée quelques films avec :-P
Puis j'ai testé, c'est marrant, même pas besoin de carte son !!!!

Bref, mon idée, c'est que tu isoles carement "gafac", donc tu as une table à 30 champs et une à 10

Donc, par défaut si tu interroges la table principale (pas gafac) tout le monde est "membre", par contre, si tu JOIN GAFAC à la requete, tu as la liste des clients, et si tu veux la liste des membres qui n'ont jamais ete client, idem, tu JOIN GAFAC, mais tu ajoutes une clause WHERE un champs obligatoire IS NULL !

Ensuite, pour mettre à jour via ton logiciel, tu as plus a te prendre la tete, tu injectes directement GAFAC, si premiere commande, tu INSERT sinon UPDATE

Et tu as plus la prise de tete que tu essayais de faire, idem, tu ne vas pas rebalancer les 8000 à chaque fois, juste ceux qui ont ete modifie.

Re: Update from

Réponse de Alph

Le : 19/11/2008 à 22:22:21

hum.... petit soucis dans ta version : il me manque 10 champs (ceux des membres)
- ok , je garde ma table "gafac" avec les 10 champs pour les clients
- ok, je crée une table principale de 30 champs pour les détails (commun aux clients et aux membres)

**table "gafac" : export direct et tel quel de mon soft :
0.id en auto incrément
1.codeidentifiant
2.nom
3.adresse1
4.adresse2
5.adresse3
6.resp
7.type
8.vend
9.pass
10.tel1

**table "principale" : 30 champs théoriquement statiques et COMMUNS aux membres et clients
0.id en auto incrément
1.codeidentifiant (afin de pouvoir lier)
1.tel2_contact
2.tel3_contact
3.tel4_contact
..
..
39.mail2_contact varchar(255)
40.mail3_contact varchar(255)

** nécessité de créer une table "membre" : 10 champs [dont certains déjà présent dans principale]
0.id en auto incrément
1.codeidentifiant (afin de pouvoir lier) [faudra qu'il soit générer automatiquement]
2.nom
3.adresse1
4.adresse2
5.resp
6.tel
7.fax1 <--- mais déjà dans table principale
8.mail1 <--- mais déjà dans table principale
9.reseau <--- mais déjà dans table principale
10.spe

Qu'en penses-tu ? Que faire avec mes champs 'doubles' ? Pourras tu me donner un exemple de liaison ?

Merci luce ! Bonne soirée, et profite bien de ton casque ;)

Re: Update from

Réponse de Maljuna Kris

Le : 19/11/2008 à 23:12:05

Tout cela n'est vraiment pas très propre et loin d'être en formes normales.
On ne modélise pas comme ça sur un coin de table et un sous-verre à bière.
As-tu pris le temps d'étudier les liens que je t'ai fournis ? J'en doute à la lecture de ces hérésies.

Re: Update from

Réponse de Alph

Le : 20/11/2008 à 08:42:30

oups... vraiment dsl MK, je n'avais pas vu ton post. Mais heu.. j'avais eu l'impression de réfléchir pour la conception.

Bon ben j'm'en vais faire un peu de ménage dans ma conception "pas très propre" ;)

Re: Update from

Réponse de Maljuna Kris

Le : 20/11/2008 à 10:55:43

Tu n'as pas à être désolé, c'est toi que ça regarde.
Je ne fais que te conseiller, après, de toutes façons c'est toi qui décideras et assumeras.

Re: Update from

Réponse de Alph

Le : 20/11/2008 à 11:36:43

Voila, un peu de réflexion m'a amené à la structure suivante :
screenshot de la structure : ---> http://www.alnoss.info/bug/structure.gif <---

**La table "gafac" est donc indépendante, tout comme la table prospect.
**La table "reseau" est liée aux 2 tables "gafac" et "prospect" : cela afin de simplifier que 1 client ou 1 membre peuvent appartenir à 1 ou plusieurs réseaux (je doute un peu de ma structure de la table reseau). Relation de 1 - oo
**La table "Détail" n'est lié qu'a la table "gafac" dans une relation de 1 - 1.

Cela vous semble t il plus correct ?

Pour rappel :
- table "gafac" direct issue de l'export d'un soft - maj tt les 4h.
- table "prospect" direct issue d'une bdd access - statique.
- table "reseau" : liste de tt les réseaux possibles (mais je vois pas comment le lier)
- table "detail" : direct issue d'une bdd access - statique - a priori aucun problème pour la liaison.

@MK : ma désolation provient du respect que j'ai pour le temps que tu prends à me répondre.

Merci en tt cas pour vos conseils.

Re: Update from

Réponse de Maljuna Kris

Le : 20/11/2008 à 13:30:10

La table réseau doit avoir pour clé unique une combinaison des clés étrangéres des tables GAFAC et Prospect
Ou un GAFAC est en reseau avec un Prospect (et réciproquement) ou pas.
Donc, toute relation entre un GAFAC et un Prospect doit être, au plus, unique.
L'indentifiant propre de la table Réseau est superfétatoire.

Re: Update from

Réponse de Alph

Le : 20/11/2008 à 14:22:16

si je comprends bien ta remarque, cela me conduit à :
==> http://www.alnoss.info/bug/structure_1.gif <==

Mais dans ce cas, comment se fait le "remplissage" des champs réseau dans gafac et dans prospect, car un membre (ou un client) peut faire partir d'un ou plusieurs réseaux.

Merci bcp

Re: Update from

Réponse de Maljuna Kris

Le : 20/11/2008 à 15:03:24

Je viens de comprendre un truc, la table réseau n'est pas qu'une interface entre GAFAC et Prospect.
C'est une entité à part entière. Et un GAFAC et/ou un Prospect appartiennent à zéro ou plusieurs réseaux.
Tu dois donc créer une autre table, une interface, qui contiendra trois colonnes, l'identifiant du réseau, l'identifiant du GAFAC (ou du Prospect) et un booléen qui dira s'il s'agit d'un GAFAC ou d'un Prospect.
La clé primaire de cette table doit être la concaténation de ses trois colonnes NOT NULL toutes les trois

Re: Update from

Réponse de Alph

Le : 20/11/2008 à 15:32:24

Alors :
- OUI ==> un GAFAC et/ou un Prospect appartiennent à zéro ou plusieurs réseaux.

Nouvelle table : "interface"
id (auto increment)
identifiant_reseau (varchar)
identifiant_commun(client ou prospect) (varchar)

Par contre, a quoi ça me sert le booléen ???
Le but étant a terme d'avoir l'option de sortir une liste de tout ceux (client ou prospect) qui font parti de ce réseau.
Afin de simplifier les choses, mes identifiants client commence par C et mes identifiants prospect par P. Je peux donc facilement savoir de quel table ils sont issus.

Ensuite, je comprends toujours pas la façon de remplir par la concaténation, mais j'ai toutefois modifié ma structure tel que :
==> http://www.alnoss.info/bug/structure_2.gif <==

Merci bcp

Re: Update from

Réponse de Maljuna Kris

Le : 20/11/2008 à 15:36:24

Le booléen servait à départager les éventuels identifiants identiques d'un GAFAC et d'un Prospect, sinon, on était obligé de faire deux tables d'interface.
Mais puisque le risque n'existe pas il suffit des deux clés étrangères couplées pour faire une PRIMARY KEY et pas besoin d'AUTOINCREMENT, pourquoi faire ?

Re: Update from

Réponse de Alph

Le : 20/11/2008 à 15:50:37

oui effectivement , les auto incrément ont été dégagés... (sur la structure en .gif). par contre, comment coupler les 2 clés ??
en fait, ca reste abstrait pour moi. J'ai tenté de comprendre avec un exemple, mais en vain.

Imaginons le client "CBLABLA", appartenant a 3 réseaux (A.B.C)
Dans la table réseau, imaginons 3 enregistrements :
1. groupeA
2. groupeB
3. groupeC

Alors, si j'ai bien suivi, l'id_reseau dans la table "interface" devra etre la concaténation des 3 id des réseaux présents dans la table reseau, ce qui me donnera comme enregistrement dans "interface"
CBLABLA (identifiant) et 123 (concatener(1;2;3))

Sauf qu'en tout logique, je vois déjà le bug (dans le cas d'un eventuel 123eme groupe dans reseau pour le cas present)..

C'est pas faute de vouloir trouver, mais je patauge :s . En attendant, merci beaucoup pour tes efforts à me faire comprendre.

Re: Update from

Réponse de Maljuna Kris

Le : 20/11/2008 à 15:52:17

Non, tu auras trois lignes dans la table d'interface, une par réseau. (Rappel MERISIEN, pas de données tabulaires, que des données scalaires)

Re: Update from

Réponse de Alph

Le : 20/11/2008 à 16:08:27

ok, je commence a mieux comprendre... Dans ce cas, dans la table interface, j'aurais N fois le code client selon le nombre N de groupe auquel il appartient.

CBLABLA : 1
CBLABLA : 2
CHOPHOP : 8
CBLABLA : 3
etc...

Maintenant, 2 questions (oui, encore) :
- Comment tout lié ensemble dans la requête ??? (je connaissais les inner join sur 1 niveau, mais là, ca va jusqu'à 3 niveaux ??)

je pensais à un :
$select= " SELECT reseau FROM table_reseau
INNER JOIN table_interface ON table_interface.id_reseau=table_reseau.reseau
INNER JOIN table_detail ON table_detail.codeclient=table_interface.codeclient
INNER JOIN table_gafac ON table_gafac.codeclient=table_detail.codeclient
WHERE table_gafac.codeclient='CBLABLA'"

Mais 1. je trouve ca trop "machine à gaz" et 2. je vois pas que ça pourrait me renvoyer les 3 réseaux

Je persévère !

Re: Update from

Réponse de Maljuna Kris

Le : 20/11/2008 à 16:53:37

Pourquoi fais-tu la jointure entre interface et detail et pas directement entre interface et gafac ?
Si tu veux récupérer d'une seul coup tous les réseaux d'un gafac tu peux passer par GROUP_CONCAT(id_reseau) avec un GROUP BY codeclient.

Re: Update from

Réponse de Alph

Le : 20/11/2008 à 17:17:48

ok pour le direct ==> http://www.alnoss.info/bug/structure_2.gif

Je vais m'essayer aux requêtes dés que j'aurais rempli mes tables ;)
Je repost dés que je sais ce qu'il en est

Merci bcp MK

Re: Update from

Réponse de Alph

Le : 20/11/2008 à 17:18:24

erratum : oublié de changer le numéro ==> http://www.alnoss.info/bug/structure_3.gif

Re: Update from

Réponse de Maljuna Kris

Le : 20/11/2008 à 17:24:11

Gxis, do.
Retour à l'index du forum


Ajouter une réponse

Nom :

Email :

Titre :

Message :

Combien font 3 + 2 ?

Mise en forme : gras = [b]...[/b], italic = [i]...[/i], souligné = [u]...[/u], citation = [quote]...[/quote], lien = [url]liens_externe[/url] ou [url nom=texte]liens_externe[/url], code source : [code]...[/code]

Recevoir les réponses par mail :
Oui Non

Mémoriser mon nom et mon email :
Oui Non

 

Charte des forums PHPDébutant

Bienvenue à vous,

Vous voici donc prêt à poster sur les forums de PHPDébutant. Avant toute chose, merci de prendre le temps de lire les quelques lignes qui suivent.

Attention, à partir du moment ou vous postez dans les forums, vous acceptez la présente charte. Si votre message est modéré ou supprimé, vous ne pourrez pas dire que vous n'étiez pas au courant des règles !

Pourquoi une charte

Le but de cette charte est simple : que ces forums restent cordiaux et que les personnes aidant les autres ne se sentent pas lésées, insultées, critiquées. Pour que ces forums fonctionnent, il faut des personnes qui répondent aux questions. Pour que celles ci restent sur le forum, il faut les traiter avec respect, et ne pas les confondre avec des bonnes poires, esclaves, etc...

Mesures de régulation

  • Un nouveau message ne disant pas bonjour, ou insultant, dont le titre est tout en majuscules, pourra être supprimé sans justification (raisons non limitatives).
  • Prenez le temps de vérifier que la question que vous allez poser n'a pas déjà été posée, à l'aide du formulaire de recherche.
  • Prenez également le temps de vérifier que la réponse à votre question ne se trouve pas dans les tutoriaux. Nous ne pouvons pas répeter pour chaque visiteur tous les cours, il sont écrits, profitez-en (dans l'ordre tant qu'à faire) !
  • Nous ne faisons pas de scripts tout prêts. Nous aidons et vous guidons pour que vous puissiez trouver vous même la réponse, ce qui est beaucoup plus formateur.
  • Si vous comptez poster un message publicitaire, abstenez-vous. Au mieux le message sera supprimé, au pire les habitués descendront votre service en flamme.
  • Pour tout message de recrutement, précisez bien votre demande. Inutile de poster pour trouver un développeur pour faire gratuitement votre site de webmastering qui vous rapportera plein de sous. Les seuls coups de mains donnés en développement sont pour des associations ou des sujets passionnant un développeur.
  • Toute personne tenant des propos racistes ou illicites sera bannie et pourra faire l'objet de poursuites.
  • L'humour étant très présent sur ces forums, ne réagissez pas violemment à des propos qui pourraient être à prendre au second degré et avec de l'humour.
  • Attention aux trolls ! Leur multiplication peut entraîner la mort des forums, et sans forum, plus d'aide !
  • Respectez les thèmes des forums. Pensez aussi à vérifier que votre message n'a pas été déplacé si vous le croyez effacé.

Conseils

  • N'oubliez pas que les personnes à qui vous vous adressez sont des bénévoles qui donnent de leur temps pour vous. Si vous êtes méchants avec eux, il n'aideront plus et vous n'aurez plus d'aide !
  • Ne soyez pas pressé. Nous avons une vie aussi, et nous ne sommes par forcément tout le temps disponibles.
  • N'oubliez pas que les smileys sont la pour faire comprendre l'humeur dans laquelle vous rédigez un message. Il est indispensable de mettre des smileys quand vous faites de l'humour, sinon le message pourrait être mal perçu (ca serait quand même idiot de plomber l'ambiance en faisant de l'humour !).
  • Surveillez votre orthographe, nous ne vous demandons pas d'être littéraire, mais que votre message soit au moins compréhensible. Evitez à tout prix le style SMS.
  • Expliquez clairement le problème, ce n'est pas toujours facile, mais mieux vaut essayer de le faire le plus possible.
  • Ne postez pas de questions trop vagues du genre "comment faire un forum". Cela ne sert à rien, cela ne s'explique pas sur un coin de forum.
  • Mettez un titre clair, correspondant au sujet que vous allez poster. A l'aide, au secours, etc... ne sont pas d'une grande utilité pour ceux qui vont vous aider. Parfois nous passons en coup de vent, et si nous ne savons pas ce que va contenir le message, nous ne le regarderons même pas.
  • Ne mettez par [URGENT] ou autre joyeuseté du genre dans vos titres de messages. Cela irrite les gens (il y'a plus urgent dans la vie, pensez aux gens qui meurent de faim ou ayant besoin des pompiers, ça c'est urgent), et vous n'aurez pas votre réponse plus vite pour autant.
  • Si vous connaissez déjà à quel domaine votre question d'adresse (par exemple mysql, html, php, javascript), n'hésitez pas à le marquer au début de votre message, avec un [html] par exemple (notez les minuscules).
  • Ne dites pas "ça marche pas". Il y a toujours des raisons. Je vous invite à consulter le tutorial "ça marche pas" qui vous aidera à mieux expliquer votre problème.
  • Ne postez pas 36000 lignes de code. Sur le forum, le code apparaît non coloré et sans indentation, ce qui est illisible. Au dessus de 5 lignes, plus personne ne lit et vous n'aurez pas de réponse. Utilisez le wall
  • En règle générale restez courtois et clair, n'oubliez pas que la politesse fait partie de la vie courante. Il est de bon ton de dire bonjour même pour une réponse, même plusieurs fois dans la journée (ceux qui vous lisent n'ont pas forcément lu vos autres messsages)

La Fin

Avec tout ces conseils vous augmenterez les chances de réponse, leur pertinence et leur rapidité

Voilà, ça sera tout, bonne écriture :)

Fermer les règles et poster un message


www.phpdebutant.org © 2009 - L'équipe de phpDebutant - Hébergement : WDMédia-hébergement