Une nouvelle exigence est apparue sur une ancienne base de code, qui permet essentiellement une communication directe (interne) entre deux classes d'utilisateurs autrefois non directement liées (stockées dans des tables différentes avec un schéma complètement différent et, malheureusement, le code est à peine conscient de l'OO, beaucoup moins conçu, donc il n'y a pas de classe parent). Puisque nous sommes prêts à accrocher un sac à cette ancienne configuration qui n'a jamais considéré cette fonctionnalité, il n'y a aucune garantie qu'il n'y a pas de collisions PK - étant donné l'ensemble de données utilisé, il est pratiquement garanti qu'il y en a.
Donc, la solution semble évidente: tuez-la avec le feu et réécrivez tout le désordre Une table de mappage. J'ai obtenu deux directions pour les manières possibles de mettre en œuvre la carte, mais je ne suis pas un DBA, donc je ne sais pas s'il y a des avantages et des inconvénients que j'ai manqués.
Pour clarifier l'abstraction, considérons trois groupes de données utilisateur disparates: professeurs, administration, étudiants (non, ce n'est pas un devoir. Promesse!)
Cartographie 1
(professor_id, admin_id et student_id sont des clés étrangères à leurs tables respectives)
| mailing_id (KEY) | professor_id | admin_id | student_id |
-------------------------------------------------------
| 1001 | NULL | 87 | NULL |
| 1002 | 123 | NULL | NULL |
| 1003 | NULL | NULL | 123 |
Le +/- de cette approche semble assez lourd sur les inconvénients:
- Deux champs "perdus" par ligne
- Violent 2NF
- Vulnérable à l'insertion / mise à jour des anomalies (une ligne avec seulement 0-1 champ défini NULL, par exemple)
Les pros ne sont pas sans mérites, cependant:
- Le mappage peut être accompli avec une seule recherche
- Déterminez facilement les données "source" pour un utilisateur donné à partir du mailing_id
À vrai dire, dans mon instinct, je n'aime pas du tout cette idée.
Cartographie 2
(supposez que MSG_ * sont des constantes définies, des types d'énumération ou un autre identifiant approprié)
| mailing_id (KEY) | user_type (UNIQUE1) | internal_id (UNIQUE2)|
------------------------------------------------------------------
| 1001 | MSG_ADMIN | 87 |
| 1002 | MSG_PROF | 123 |
| 1003 | MSG_STUDENT | 123 |
Avec cette configuration et un index composite unique de {user_type, internal_id}, les choses deviennent beaucoup plus propres, 3NF est maintenu et le code d'application n'a pas à vérifier les anomalies d'E / S.
À la baisse, il y a un peu de transparence dans la détermination des tables source utilisateur qui doivent être gérées en dehors de la base de données, ce qui revient essentiellement à un mappage au niveau de l'application des valeurs user_type vers les tables. En ce moment, je penche (assez fortement) vers cette 2ème cartographie, car l'inconvénient est plutôt mineur.
MAIS je suis douloureusement conscient de mes propres limites, et je suis sûr que j'ai probablement manqué des avantages ou des pierres d'achoppement dans les deux sens, alors je me tourne vers des esprits plus sages que les miens.