6
votes

Mysql: deux n: 1 relations, mais pas à la fois à la fois

Désolé pour le titre, il est difficile d'expliquer.

J'ai besoin d'un modèle de données similaire à celui-ci: text alt

Comme vous pouvez le constater, un ensemble peut appartenir à un utilisateur ou à une école. Mon problème: il ne devrait être autorisé qu'à un utilisateur ou à une école. Mais jamais tous les deux en même temps.

Comment puis-je résoudre ce problème?


4 commentaires

Qu'est-ce que vous avez utilisé pour faire le graphique?


Wow! C'est un long chemin depuis que je la dernier a essayé!


@basszero: exactement ce que je pensais aussi quand je l'ai installé :)


J'ai voté à la fois cette question et la réponse acceptée comme les deux sont excellentes. Cependant, la réponse acceptée, bien que excellente, est également un peu technique. Je comprends donc un lien ci-dessous avec une réponse moins technique pour d'autres personnes qui pourraient souhaiter la voir. Stackoverflow.com/questions/6790671/many-a- Deux relations / ...


3 Réponses :


1
votes

Vous devrez utiliser une gâchette pour appliquer cette règle d'entreprise, car MySQL n'a pas d'appliquer les contraintes de contrôle (sur aucun moteur).


0 commentaires

2
votes

Avec la mise en garde: ce n'est pas tout à fait clair ce qu'un ensemble est dans votre modèle de données.

Je suis en question de votre modèle de données.

Pourquoi les utilisateurs -> ensembles et scolaires -> sont à pointer vers la même table. Ce n'est pas plus normalisé si ce sont des ensembles de données vraiment indépendants. Ce n'est pas parce qu'ils partagent certaines similitudes dans les colonnes qu'ils suivent ne signifie pas qu'ils doivent être stockés dans la même table. Sont-ils logiquement la même chose?

Il suffit de créer des tables séparées pour les ensembles scolaires et des ensembles d'utilisateurs. Cela fera également des questions inverse plus facilement, car vous n'aurez pas à vérifier les relations nulles dans la table des ensembles pour savoir s'il s'agit vraiment d'un utilisateur ou d'un schoot.


4 commentaires

Merci pour l'indice. En fait, les ensembles (de nombreux vocabes font un ensemble) sont exactement les mêmes, ils peuvent simplement avoir des propriétaires différents, une école ou un utilisateur. Comme un ensemble ne sera jamais déplacé d'appartenance à une école à appartenir à un utilisateur ou inversement, je pourrais simplement créer deux types d'ensembles et copier les données sur l'autre table lorsque cela est nécessaire. Le problème de cette approche est que, alors j'aurai besoin de deux types de vocabes et je ne pense pas vraiment que cela aurait beaucoup de sens.


Vous pouvez probablement mettre une table de setowner entre les utilisateurs / les écoles et les ensembles. Ensuite, chacune des tables qui pourraient «posséder» un ensemble aurait une colonne FK à un SET_OWNER_ID. La table set aurait alors un set_owner_id aussi. Donc, fondamentalement, un utilisateur et une école ont une relation de 1: 1 avec Setowner et Setowner est de 1: M pour définir. Ensuite, tout a une intégrité référentielle exécutoire. Cela rendra cela assez difficile à aller de se mettre au propriétaire (logique) cependant.


Tu veux dire comme cela? i.imgur.com/dvrs9.png Je ne comprends pas vraiment comment cela résout le problème.


Ouais, comme ça. Il garantit qu'il n'y a qu'un seul point de constiré pour un utilisateur ou une école donnée. Il garantit également qu'un ensemble ne peut appartenir à un seul point de seigneur (ce qui signifie soit une école ou un utilisateur, mais pas à la fois). Cela fonctionnera si vous naviguez généralement de l'école ou de l'utilisateur aux ensembles.



8
votes

Votre conception actuelle est appelée Arcs exclusifs em> où la table code> a deux clés étrangères et nécessite exactement l'une d'entre elles pour être non nulle. Ceci est un moyen de mettre en œuvre des associations polymorphes, car une clé étrangère donnée ne peut faire référence à une seule table cible.

Une autre solution consiste à faire une "super-mesure" commune que les deux utilisateurs code> et écoles code> sont des références, puis utilisez-le comme le parent de définit code> . P>

SELECT COALESCE(u.name, sc.name) AS name 
FROM Sets s 
LEFT OUTER JOIN Users u ON s.SetOwner_id = u.id
LEFT OUTER JOIN Schools sc ON s.SetOwner_id = sc.id 
WHERE ...


5 commentaires

Merci pour l'excellente explication. L'approche avec la super-valise semble semblable à celle que Geofflane a proposé dans son commentaire. Je pense que je comprends le concept maintenant. Donc, le tableau septiker contient à la fois des utilisateurs et des écoliers, correct? Cela signifierait que je ne serais pas autorisé à avoir le même identifiant pour un utilisateur et une école. Comment puis-je exécuter cela?


Et un autre aspect: l'ERD ressemble actuellement à ce imgur.com/vd1ln.png . Si j'aimerais obtenir le type de propriétaire pour un ensemble, ai-je besoin d'un attribut de propriétaire dans ma table de set propriétaire? Ou y a-t-il une autre façon de le faire? Et si je veux obtenir le nom de l'école ou de l'utilisateur (quel que soit le type de type), puis-je faire cela avec une seule requête ou avez-vous besoin de deux questions (d'abord pour obtenir le type et seconde pour obtenir le nom)?


Awesome Edit, merci. C'est pourquoi j'aime Stackoverflow. Il n'y a qu'une seule question restante: puis-je utiliser en toute sécurité last_insert_id () dans un environnement multi-utilisateurs ou des requêtes et des insertions par d'autres utilisateurs interfèrent avec la requête en cours, de sorte que le last_insert_id change?


Désolé pour le quadruple commentaire: j'ai trouvé la réponse moi-même. "L'ID généré est maintenu sur le serveur sur une base de connexion." dev.mysql.com/doc/ Refman / 5.1 / FR / ...


Oui, cette fonction ne fournirait aucun avantage s'il était sensible aux conditions de course. Toutes les bases de données fournissent un moyen d'obtenir la dernière valeur de pseudopie générée dans votre connexion actuelle, même si d'autres clients génèrent également des valeurs de pseudovey.