web-dev-qa-db-fra.com

Une clé étrangère peut-elle agir comme clé primaire?

Je suis en train de concevoir une structure de base de données pour le projet de notre équipe. J'ai cette même question en tête actuellement: est-il possible d'avoir une clé étrangère comme clé primaire sur une autre table?

Voici quelques tableaux de la conception de la base de données de notre système:

user_accounts
students
guidance_counselors

Ce que je voulais, c'est que le user_accounts La table doit contenir les identifiants (supposément les informations d'identification de connexion au système) et les mots de passe des utilisateurs étudiants et des conseillers. En bref, les clés primaires des students et guidance_counselors table sont également la clé étrangère de user_accounts table. Mais je ne sais pas si c'est permis.

Une autre question est: un student_rec une table existe également, qui nécessite un student_number (qui est le user_id dans le user_accounts table) et un guidance_counsellor_id (qui est également le user_id dans le user_accounts) pour chacun de ses enregistrements. Si les pièces d'identité d'un étudiant et d'un conseiller d'orientation proviennent du user_accounts table, comment concevoir le student_rec table? Et pour référence future, comment l'écrire manuellement en tant que code SQL?

Cela me dérange et je ne trouve aucune réponse précise ou sûre à mes questions.

19
christianleroy

Bien sûr. Il s'agit d'une technique courante appelée supertyping tables. Comme dans votre exemple, l'idée est qu'une table contient un sur-ensemble d'entités et a des attributs communs décrivant une entité générale, et d'autres tables contiennent des sous-ensembles de ces entités avec des attributs spécifiques. Ce n'est pas différent d'une simple hiérarchie de classes dans la conception orientée objet.

Pour votre deuxième question, une table peut avoir deux colonnes qui sont des clés étrangères distinctes de la même autre table. Lorsque la base de données crée la requête, elle rejoint deux fois cette autre table. Pour illustrer une requête SQL (je ne suis pas sûr de la syntaxe MySQL, je ne l'ai pas utilisée depuis longtemps, il s'agit donc spécifiquement de la syntaxe MS SQL), vous donneriez à ce tableau deux alias distincts lors de la sélection des données. Quelque chose comme ça:

SELECT
    student_accounts.name AS student_name,
    counselor_accounts.name AS counselor_name
FROM
    student_rec
    INNER JOIN user_accounts AS student_accounts
      ON student_rec.student_number = student_accounts.user_id
    INNER JOIN user_accounts AS counselor_accounts
      ON student_rec.guidance_counselor_id = counselor_accounts.user_id

Cela prend essentiellement le student_rec table et la combine avec la user_accounts table deux fois, une fois sur chaque colonne, et assigne deux alias différents lors de leur combinaison afin de les différencier.

22
David

Oui, il ne devrait y avoir aucun problème. Les clés étrangères et les clés primaires sont orthogonales les unes aux autres, il est bon qu'une colonne ou un ensemble de colonnes soit à la fois la clé primaire de cette table (ce qui les oblige à être uniques) et également à être associée à une clé primaire/contrainte unique dans une autre table.

2
michel-slm