| Bonsoir,
Yohan, t'as raison.
J'ai créé des tables d'essai (avec des valeurs selon mon humeur):
# --------------------------------------
DROP TABLE IF EXISTS ccm_ARTICLES;
CREATE TABLE ccm_ARTICLES (
nom varchar(20),
serie integer,
prix decimal(6,2),
prix_editeur decimal(6,2),
primary key(nom)
) type=MyISAM comment='Table des articles';
INSERT INTO ccm_ARTICLES VALUES
('Article 1','1','5.50','6.67'),
('Article 2','5','7.90','8.01'),
('Article 3','9','5.80','6.98'),
('Article 4','7','5.50','6.67'),
('Article 5','3','8.10','8.46'),
('Article 6','1','5.40','6.48'),
('Article 7','4','6.30','6.42');
# --------------------------------------
DROP TABLE IF EXISTS ccm_SERIES;
CREATE TABLE ccm_SERIES (
id_serie integer not null auto_increment,
nom_serie varchar(20),
editeur varchar(25),
primary key(id_serie)
) type=MyISAM comment='Table des séries';
INSERT INTO ccm_SERIES VALUES
('1','Série 1','Plon'),
('2','Série 2','Eyrolles'),
('3','Série 3','O''Reilly'),
('4','Série 4','Apress'),
('5','Série 5','Campuspress'),
('6','Série 8','O''Reilly'),
('7','Série 10','Apress'),
('8','Série 11','Hachette'),
('9','Série 20','Eyrolles');
Puis j'ai essayé la commande suivante qui m'a donné l'erreur ci-dessous:
requête SQL:
UPDATE ccm_ARTICLES SET prix = '9.20', prix_editeur = '10.30'
WHERE ccm_SERIES.id_serie=ccm_ARTICLES.serie AND prix='5.50' AND editeur='Plon' ;
MySQL a répondu:
#1054 - Unknown column 'ccm_SERIES.id_serie' in 'where clause'
La commande suivante fonctionne et change deux enregistrements :
UPDATE ccm_ARTICLES SET prix='9.20', prix_editeur='10.30'
WHERE serie IN (SELECT id_serie FROM ccm_SERIES)
AND prix='5.50';
==> les anciens articles à 5.50 ont été mis à jour quelque soit le nom de l'éditeur, soit 2 enregs.
Ce qui revient à dire qu'on aurait pu taper simplement:
UPDATE ccm_ARTICLES SET prix='9.20', prix_editeur='10.30'
WHERE prix='5.50';
->La clause "serie IN(SELECT...FROM...)" ne semble pas avoir été prise en compte.
J'ai voulu tester en spécifiant un éditeur particulier avec cette commande:
UPDATE ccm_ARTICLES SET prix='9.20', prix_editeur='10.30'
WHERE serie IN (SELECT id_serie FROM ccm_SERIES)
AND 'Plon' IN (SELECT editeur FROM ccm_SERIES)
AND prix='5.50';
Elle ne produit pas d'erreur mais ne change aucun enregistrement (les prix ayant au préalable été remis à 5.50).
En dehors de cela: je n'ai évidemment pas la problématique de la gestion à effectuer et il est difficile à dire si les tables sont adaptées à la gestion mais il me semble qu'avec une bonne analyse, la mise à jour de deux tarifs devrait être beaucoup plus simple :
1. Les données ne doivent pas être redondantes. Si tel est le cas (ex: Eyrolles, O'Reilly), cela doit donner naissance à un objet (objet "Editeurs" avec son identifiant) en relation avec un autre objet
(ex: "[Article]-----(appartenir à)-----[Serie]-----(dépendre d'un)-----[Editeur]")
2. Y a-t-il un lien entre prix et prix_editeur. Si oui (ex: prix HT et prix TTC) et si l'un peut être déduit de l'autre, il ne sert à rien d'enregistrer les deux. Il suffit de faire le calcul ad hoc à partir de la valeur enregistrée. De plus si l'on doit gérer l'historique des tarifs en vue d'une comptabilité, "prix" ne doit pas être une propriété de l'objet "Articles" (car une propriété ne peut prendre qu'une valeur et une seule) mais devrait être une propriété portée par la relation "appartenir à".
3. Règle Merise n° 1. Chaque objet doit avoir un identifiant. L'objet "Articles" donnant naissance à la table ARTICLES a-t-il un identifiant ? Le champ nom serait-il clef primaire ?
4. Règle Merise n° 4. Toutes les propriétés autres que l'identifiant doivent dépendre pleinement et directement de l'identifiant
=> Si "nom" est l'identifiant de la table ARTICLES la propriété "prix" ne dépend pas pleinement QUE du champ "nom" (de l'identifiant). Pour dire ceci je me suis mis en tête que "nom" pouvait être le nom d'un livre (puisqu'on parle d'éditeur) auquel cas le prix d'un même texte publié chez des éditeurs différents n'est pas forcément le même. En revanche un prix donné peut être celui d'un livre donné dans une série donnée chez un éditeur donné. Le prix ne dépend donc pas QUE du "nom" (du titre) mais des trois éléments.
Mais ceci est dit a priori, sans vraiment connaître la problématique. Mais je sais seulement que des tables issues d'une analyse correcte de la gestion à effectuer ne posent quasiment jamais de difficulté pour insérer, modifier ou supprimer des enregistrements. Souvent même, la multiplicité des tables simplifie la gestion, même si cela rallonge parfois un peu l'écriture.
Bon, je vais au lit... :o) Peut-être à plus tard...
helico. Répondre à heliconius | 24 elpah, le 13 jan 2009 à 12:36:46Je pense que sa doit rendre mes tables plus claire
--
-- Structure de la table `series`
--
CREATE TABLE `series` (
`id_serie` int(10) unsigned NOT NULL auto_increment,
`nom_serie` varchar(255) NOT NULL default '',
`type` enum('type1','type2','type3') NOT NULL default 'type1',
`genre` varchar(70) NOT NULL default '',
`themes` varchar(255) NOT NULL default '',
`adulte` enum('OUI','NON') NOT NULL default 'NON',
`etat` enum('en cours','terminée','inachevée à ce jour','stoppée','') NOT NULL default 'en cours',
`pays` varchar(50) NOT NULL default '',
`nbre_total` int(10) unsigned NOT NULL default '0',
`nbre_parus` int(10) unsigned NOT NULL default '0',
`auteur` varchar(255) NOT NULL default '',
`dessinateur` varchar(255) NOT NULL default '',
`resume` longtext NOT NULL,
`texte_libre` longtext NOT NULL,
`editeur` varchar(255) NOT NULL default '',
PRIMARY KEY (`id_serie`),
KEY `adulte` (`adulte`),
KEY `auteur` (`auteur`),
KEY `dessinateur` (`dessinateur`),
KEY `editeur` (`editeur`),
KEY `etat` (`etat`),
KEY `genre` (`genre`),
KEY `id_serie` (`id_serie`),
KEY `nbre_parus` (`nbre_parus`),
KEY `nbre_total` (`nbre_total`),
KEY `nom_serie` (`nom_serie`),
KEY `pays` (`pays`),
KEY `themes` (`themes`),
KEY `type` (`type`)
) TYPE=MyISAM AUTO_INCREMENT=2191 ;
--
-- Structure de la table `articles`
--
CREATE TABLE `articles` (
`nom` varchar(255) NOT NULL default '',
`serie` int(10) unsigned NOT NULL default '0',
`coffret` enum('OUI','NON') NOT NULL default 'NON',
`prix` float NOT NULL default '0',
`date_sortie` date NOT NULL default '0000-00-00',
`prix_editeur` float unsigned NOT NULL default '0',
PRIMARY KEY (`nom`,`serie`),
KEY `coffret` (`coffret`),
KEY `date_sortie` (`date_sortie`),
KEY `nom` (`nom`),
KEY `prix` (`prix`),
KEY `prix_editeur` (`prix_editeur`),
KEY `serie` (`serie`)
) TYPE=MyISAM; Répondre à elpah |
|