JeuWeb - Crée ton jeu par navigateur

Version complète : Polymorphisme dans une BDD / clé étrangère vers plusieurs tables
Vous consultez actuellement la version basse qualité d’un document. Voir la version complète avec le bon formatage.
Bonjour,

N'ayant pas fait de BDD depuis longtemps, j'ai voulu m'y remettre.
Je me fait un diagramme de classe, et là, question : le polymorphisme dans une BDD ça donne quoi ?
Ma première réaction : QUOI ? On est en 2014 et les BDD ne gèrent toujours pas l'héritage !?
Ma seconde réaction : BDD relationnel signifie orienté relation, et non orienté objet pardi !

Pensons donc relation !

Mon besoin à travers un exemple :
Un Passager peut être dans un et un seul Véhicule.
Il y a plusieurs TypeDeVéhicule, qui ont chacun un nom et une description.
En Véhicule nous pouvons avoir des Voitures, des Camions, des Bateaux ...etc.
Chaque spécialisation a ses propres informations, et des informations en commun (une immatriculation par exemple).

C'est tout. Oui je bloque là dessus !

J'ai donc au moins une table Passager, avec une clé étrangère vers la table Véhicule j'imagine.

Du coup, après m'être renseigné sur ce forum et d'autres, je trouve 2 solutions possibles :

Numéro 1 (STI) : On concatène tous les attributs de toutes les spécialisations dans la même table Véhicule, avec une clé étrangère nommé type vers TypeDeVéhicule.
Désavantage : plein de NULL, cohérence à maintenir entre la clé étrangère type et les valeurs des attributs qu'elle conditionne.

Numéro 2 (MTI) : Chaque spécialisation a sa table, avec une clé étrangère vers Véhicule. Chaque instance de Véhicule doit avoir une clé étrangère vers TypeDeVéhicule ?
Désavantage : cohérence à maintenir entre une instance d'une spécialisation et le type de l'instance de véhicule pointé par celle-ci, et rien n'empêche plusieurs instances de spécialisation de pointer vers la même instance de Véhicule, on peut donc avoir un Véhicule qui est 3 fois une Voiture, 1 fois un Bateau et de type Camion.

(La numéro 3 (CTI) qui consiste à ce que chaque spécialisation a sa propre table avec duplication d'attributs n'est pas possible car l'absence de la classe générique Véhicule empêche d'avoir une clé étrangère vers celle-ci dans Passager).


J'ai vraiment l'impression de passer à coté de quelque chose. J'ai oublié quoi ?
Merci de m'aider !

PS: Contrainte supplémentaire importante, la BDD doit être facilement accessible et faire profiter au maximum des possibilités du framework CakePHP.
Pour être sûr de répondre au mieux : les voitures, camions et bateaux sont bien les noms de 3 lignes de la table des types de véhicules ?
Si oui, je partirais sur une table de véhicules qui a une foreign key vers ces types de véhicules. Et un passager n'a alors besoin que d'une foreign key vers la table des véhicules.
Oui, c'est bien ça ! Mais chaque type de véhicule a également des attributs qui lui sont propres, là est le soucis !
sc 1 : dans la table véhicule un champ stockant les valeurs sérialisées

sc 2 : dans la table véhicule n champs génériques de valeur. Chaque type utilisant à sa manière le champ générique 1, etc... il y aura un peu de null mais peu importe

sc 3 : une table supplémentaire : id véhicule / id param / valeur param
Je n'avais jamais vraiment pris la peine de me renseigner sur PostgreSQL, mais ça a l'air sympa !
Par rapport à MySQL c'est quoi en gros les avantages/inconvénients ?

Je lis que c'est plus strict sur l'intégrité de la BDD ce qui est bien, mais que c'est plus lourd et plus fait pour travailler sur des grosses BDD.

Malheureusement, concernant l'avantage que ça gère l'héritage :
"Une limitation sérieuse de la fonctionnalité d'héritage est que les index (incluant les contraintes uniques) et les contraintes de clés étrangères s'appliquent seulement à des tables seules, pas à leurs héritiers."
"Spécifier que la colonne d'une autre table REFERENCES villes(nom) autoriserait l'autre table à contenir les noms des villes mais pas les noms des capitales. Il n'existe pas de bons contournements pour ce cas."

Donc pas de polymorphisme pour les clés étrangères :/
Je ne peux pas avoir une clé étrangère dans Passager vers Véhicule qui contiendrait enfaite une instance de Voiture ou autre ... :/
Tu peux aussi utiliser un ORM comme doctrine par exemple qui répond parfaitement à ta question avec son système de "mapped superclasse" ou de "Single Table Inheritance".

L'avantage d'un ORM est qu'il va te cacher la partie concernant le SGBD et toi, côté utilisateur, tu manipuleras des objets (que tu as l'air d'apprécier).