modélisation BD classe étendue

Mammouth du PHP | 514 Messages

23 avr. 2008, 10:36

Bonjour,

je me demandais quelle était la meilleure solution pour modéliser les héritages de classes dans ma base de données ...


Exemple :
class personne {

}
class secretaire extends personne {

}
class directeur extends personne {

}
Il est préférable d'avoir une table, plusieurs tables avec l'id de la table parente ?

Quelle solution proposez vous ?

Merci de votre aide.

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

23 avr. 2008, 11:01

En fait, je pense que tu prends le problème à l'envers.

Il faut tout d'abord commencer par la modélisation de ta base de données, comment est-ce que tu comptes enregistrer et agencer tes données.
Et une fois que tu as terminé cette modélisation, tu pourras passer à la conception de tes classes métiers.
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Mammouth du PHP | 514 Messages

23 avr. 2008, 11:11

En fait, j'ai déjà fait un diagramme de classes. Dans ce diagramme, j'ai plusieurs classes qui héritent d'une classe mère.

Il me semble qu'un diagramme de classes doit pouvoir m'aider à modéliser ma base de données, simplement en utilisant des techniques connues pour des cas connus dans mon diagramme ...

En fait, je préfère éviter de faire de l'uml ET du merise.

Donc, finalement, comment je modélise ça dans ma base de données ?

Administrateur PHPfrance
Administrateur PHPfrance | 3131 Messages

23 avr. 2008, 13:11

Une solution simple et qui a l'avantage de respecter le concept d'héritage, c'est bien l'utilisation d'une clé étrangère vers ta table mère.

Prenons un exemple assez simple avec une table des "users" et une table des "clients", un client étant un user particulier (et donc naturellement client hérite de user).

Tables :
t_user (id, username, password, email)
t_client (id, user_id --> user.id, contract_number, address)
Classes :
interface Persistant {
  public function load($id); // load from database
  public function save(); // save to database
  public function delete(); // delete from database
  public function isNew(); // is a loaded object or a freshly created one ?
}

class User implements Persistant {
  public function load($id) { /* interroge t_user */ }
  public function save() { /* insère (ou update, selon isNew()) dans t_user */ }
  public function delete() { /* supprime dans t_user */ }

  public function getUsername() { ... }
  public function setUsername() { ... }
  public function getPassword() { ... }
  public function setPassword() { ... }
  public function getEmail() { ... }
  public function setEmail() { ... }
}

class Client extends User {
  public function load($id) { /* interroge t_client en jointure avec t_user */ }
  public function save() { /* insère (ou update, selon isNew()) dans t_user, puis dans t_client */ }
  public function delete() { /* supprime dans t_client, puis dans t_user, sauf si on a du ONDELETE=Cascade géré directement par la bdd */ }

  public function getContractNumber() { ... }
  public function setContractNumber() { ... }
}
Les avantages sont multiples, l'inconvénient est de "couper" les données en deux. Cet inconvénient n'en est un que lorsqu'on utilise PhpMyAdmin en guise de back-office au lieu d'en faire un vrai :)

Note : quand on fait ce genre de modélisation, au niveau de l'implémentation il vaudra mieux choisir InnoDB qui permet d'imposer le respect des contraintes de clés étrangères et d'utiliser du "OnDelete = Cascade" très utile pour éviter de se soucier de ce genre de détails au niveau applicatif (ça économise moultes requêtes, et savoir que la cohérence des données est assurée au niveau le plus bas c'est drôlement rassurant).

Mammouth du PHP | 514 Messages

23 avr. 2008, 14:34

Merci de ta réponse, je pense que je vais suivre tes conseils.

Sujet clos