2010-04-05 18 views
2

J'ai donc une base de données avec quelques tables.Gestion des clés étrangères

La première table contient l'ID utilisateur, le prénom et le nom.

La deuxième table contient l'ID utilisateur, ID d'intérêt et note d'intérêt.

Il y a une autre table qui a tous les intérêts ID de.

Pour chaque ID d'intérêt (même lorsque de nouveaux ID sont ajoutés), je dois m'assurer que chaque utilisateur possède une entrée pour cet ID d'intérêt (même s'il est vide ou contient des valeurs par défaut).

Est-ce que les clés étrangères aider à ce scénario? ou devrais-je utiliser PHP pour mettre à jour chaque enregistrement lorsque j'ajoute une nouvelle clé?

Répondre

0

Pour chaque ID d'intérêt (même lorsque de nouveaux les applications ajoutées), je dois vous assurer que chaque utilisateur dispose d'une entrée pour cet ID d'intérêt (même si son vide, ou a par défaut).

Il semble que vous avez besoin d'un OUTER JOIN (soit LEFT ou RIGHT) dans l'un de vos requêtes à la place.

Par exemple, si vous voulez obtenir le niveau d'intérêt une personne en particulier a pour chaque intérêt:

En supposant que vos tableaux ressemblent à ceci:
utilisateurs:
user_id PK
utilisateur

user_interests:
user_id PK FK
interest_id PK FK
interest_level

intérêts:
interest_id PK
intérêt

SELECT i.interest, ui.interest_level 
FROM interests i 
INNER JOIN user_interests ui USING (interest_id) 
LEFT JOIN users u USING (user_id) 
WHERE user_id = ? 

? est un espace réservé.

Notez que ui.interest_level sera nulle pour les intérêts avec aucune donnée.

1

clés étrangères sont une sorte de contrainte , de sorte qu'ils ne peuvent échouer lorsque vous essayez d'ajouter des enregistrements.

Vous pouvez accomplir ce que vous décriviez avec un déclencheur. Je ne sais pas la syntaxe MySql, mais dans SQL Server, il ressemblerait à quelque chose comme ceci:

CREATE TRIGGER TR_ensure_user_interest ON interest FOR INSERT, UPDATE AS 
BEGIN 
    INSERT user_interest (user_id, interest_id) 
    SELECT user_id, interest_id 
     FROM inserted 
      ,user 
    EXCEPT (SELECT user_id, interest_id) 
END 

Notez que cette approche est plutôt inefficace, mais il devrait couvrir la plupart des cas, vous êtes préoccupé par.

MISE À JOUR: Je suis d'accord avec les autres qui ont observé le design "odeur" ici. Si vous pouvez obtenir le résultat requis en utilisant des requêtes JOIN, ce serait une solution beaucoup plus efficace. Cependant, j'essayais de répondre à la question réellement posée. (De plus, je suis dans cette situation, où les dossiers physiques sont utiles aux autres utilisateurs de bases de données qui ne sont pas aptes à des requêtes composées.)

+0

Merci d'avoir pris le temps de répondre à ma question. C'est bon à savoir, mais je pense que je cherche quelque chose dans le sens de ce que OMG Unicorns a fourni. Je pense que le déclencheur finirait par être trop lourd. – jwzk

0

Il semble que vous obligez votre conception physique pour refléter votre conception logique trop serré.

Peut-être que ce serait une bonne idée de repenser exactement pourquoi vous avez besoin d'insérer une ligne pour chaque utilisateur dans la table physique. Ne pourriez-vous pas simplement écrire vos requêtes pour supposer la valeur par défaut pour un interestID s'il n'y a pas d'ID d'intérêt associé pour un utilisateur donné?

0

"Les clés étrangères aideront-elles dans ce scénario?"

n °

Votre contrainte est une sorte de contrainte « exhaustivité ». Cela implique que pour chaque nouvel intérêt ajouté, il doit y avoir autant de lignes ajoutées à la table USER_INTEREST que d'utilisateurs.

Aucun système SQL n'est capable de l'appliquer pour vous. C'est à vous de l'imposer par le code.