suppose que j'ai un schéma comme: Je n'aime pas cette représentation, mais je me lance de trouver un meilleur. P> Les deux alternatives J'ai pensé être: p> (mais c'est mauvais parce que je ne peux plus avoir plus de clés étrangères) p> et: p > entity
------
id
group
-----
entity_id
site
----
entity_id
link_entity_id (optional)
person
------
entity_id
link_entity_id (optional)
device
------
entity_id
link_entity_id
3 Réponses :
Il s'agit d'une situation de type typique / sous-type. Votre deuxième option est meilleure et vous pourriez en faire un pas plus loin. Pensez en termes de programmation OO si vous connaissez plus ces concepts.
C'est la façon dont je vais classer vos entités. Les entités "abstraites" sont entre crochets. P>
(Owner) Device
|
+-----------+
| |
(Afffiliation) Person
|
+-------+
| |
Group Site
Comment traduire cela en tableaux: p>
Maintenant que vous pourrait em> coller à votre première option. MySQL ne prend pas en charge la syntaxe check () code> pour déclarer des contraintes arbitraires, mais le même effet peut être obtenu grâce à l'utilisation de déclencheurs, cependant, la syntaxe est encombrante et la performance est douteuse. P > p>
La structure MySQL suivante doit normaliser tout simplement bien. Il rendra vos questions un peu plus compliquées à écrire depuis quelques occasions, mais cela rendra la demande plus puissante et capable de croître de manière exponentielle sans prendre un coup sur la performance. Nous avons une grande base de données MySQL avec de nombreuses racines de relatifs qui contiennent des clés étrangères pour les personnes à divers entretiens, notes et autres données qui fonctionne formidable! Une note est que si vous utilisez le groupe comme nom de table, rappelez-vous d'utiliser `` marques comme: de cette façon, MySQL n'essaie pas d'invalider un groupe de jointure intérieure Démo en ligne: http://www.sqlfiddle.com/#!2/e9e94/2/0 p> Voici la structure de table MySQL proposée avec la plus petite quantité de données à rendre compte d'un instance de chaque cas nécessaire de votre question: Copiez et collez dans le fichier .SQL et l'importation pour vider la base de données à l'aide de phpmyadmin P> Voici une requête pour trouver tous les appareils enfants de chaque groupe . p> et voici une requête pour obtenir tous les périphériques et leur parent direct. p> Vous pouvez en outre obtenir le Dispositifs sur (foo = bar) code> et attendez-vous groupe par code>. Vous devrez également mettre des contraintes à l'avant de votre application qui empêcherait un périphérique en cours d'ajout sans parent si c'est le but souhaité. Mais ce n'est pas trop difficile à faire. Quoi qu'il en soit, regardez les exemples et amusez-vous à expérimenter / à programmer! P>
Je serais intéressé par votre opinion sur ma réponse. Je vais ré-accepter votre réponse à la fin de la semaine. Stackoverflow.com/a/19153449/129805
Une autre façon d'approcher ceci est de scinder des tables en plusieurs tables et de les syndicaliser ensemble.
Ceci est légèrement plus complexe, mais permet une garantie beaucoup plus complexe. P>
(J'ai inaccepté la réponse de @ Amaster507 pendant une semaine, d'avoir des opinions sur cette solution.) P>
Exigences: p>
group ----- id site ---- id group_id (optional) person_in_group --------------- id group_id person_at_site -------------- id site_id device_in_group --------------- id group_id device_at_site -------------- id site_id device_with_person ------------------ id person_id
P.s. J'ai découvert que l'héritage de la table de Postgresql pourrait faire disparaître le problème. Le seul problème est que vous ne pouvez pas ajouter des index (uniques) à travers les tables (parent et enfant), mais ce n'est pas un casse-briseur. Il prend même en charge l'utilisation d'une séquence unique partagée pour les identifiants AutoIncrement.
Je ne connais pas l'héritage de la table de PostgreSQL. Cette réponse est toutefois très très similaire à ma réponse avec les différences de ne pas avoir de tables séparées pour les personnes, les périphériques, les sites et les tables pivot ayant des noms différents. Je crois que mon chemin serait toujours plus normalisé, mais les deux pourraient très bien travailler pour vos besoins. Si vous stockez d'autres informations sur les personnes et les appareils tels que le nom, l'âge, le modèle, etc., les tables distinctes vous aideront, car vous n'aurez pas à dupliquer des données dans la base de données. (suite)
(suite) Si vous ne vous souciez que de l'ID pour les personnes et les appareils, et si un site ne peut être que dans un groupe, et si les appareils et les personnes n'ont pas souvent besoin de changer de sites et de groupes, cela pourrait très bien être meilleur. Si l'une de ces trois déclarations précédentes est fausse, alors mon chemin serait toujours meilleur.
@ Amaster507 Merci pour vos commentaires, oui, je suis d'accord que votre solution est meilleure dans le cas général. Cette solution est spécialisée pour les associations relativement statiques (c'est-à-dire des mois ou des années). Changer une association exige qu'un enregistrement soit supprimé et inséré dans une table différente. Je creuse plus profondément dans PostgreSQL, car ce n'est que désavantage (comparé à MySQL) semble être que je ne l'ai pas beaucoup utilisé.
Je supprimerais l'identifiant de
périphérique CODE> et créer trois linktables distincts surGroupe code>,Site code> etpersonne code>. De manière relative, c'est à moi la bonne façon de le faire.@Lieven Keersmaekers qui rendrait des requêtes plus complexes et plus lentes - quel est le bénéfice?
Il est normalisé de cette façon et explicite à quiconque. J'ai commencé à travailler en maintenance il y a un an et demi et je peux vous assurer qu'en cas de connaissances de domaine préalable, toutes les autres solutions sont plus difficiles à obtenir une prise en main sur les nouveaux arrivants. Avoir des tables séparées me dit immédiatement qu'un appareil appartient à un groupe, au site ou à une personne, mais pas plus. Avoir tous les identifiants d'une table ne me dis pas facilement.
Quant à la ralentissement de la ralentissement: je serais fortement pressé que vous verriez une performance notable frappée.