Un nuovo requisito è emerso su una vecchia base di codice, che fondamentalmente consente la comunicazione diretta (interna) tra due classi di utenti precedentemente non direttamente correlate (memorizzate in tabelle diverse con uno schema completamente diverso e, purtroppo, il codice è a malapena OO- consapevole, molto meno progettato, quindi non c'è una classe genitore). Dato che siamo fuori per appendere una borsa su questo vecchio setup che non ha mai considerato questa funzionalità, non c'è alcuna garanzia che non ci siano collisioni PK - dato il set di dati in uso, è praticamente garantito che ci siano.
Quindi, la soluzione sembra ovvia: uccidilo con il fuoco e riscrivi tutto il casino Una tabella di mappatura. Ho ottenuto due indicazioni per i possibili modi di implementare la mappa, ma non sono un DBA, quindi non sono sicuro che ci siano pro e contro che ho perso.
Per chiarire l'astrazione, considera tre gruppi di dati utente diversi: Professori, Amministrazione, Studenti (No, questo non è un compito a casa Promessa!)
Mappatura 1
(professor_id, admin_id e student_id sono chiavi esterne alle rispettive tabelle)
| mailing_id (KEY) | professor_id | admin_id | student_id |
-------------------------------------------------------
| 1001 | NULL | 87 | NULL |
| 1002 | 123 | NULL | NULL |
| 1003 | NULL | NULL | 123 |
I +/- a questo approccio sembrano piuttosto pesanti sugli aspetti negativi:
- Due campi "sprecati" per riga
- Violates 2NF
- Vulnerabile per inserire / aggiornare anomalie (una riga con solo 0-1 set di campi NULL, ad es.)
I professionisti non sono senza i loro meriti, però:
- La mappatura può essere eseguita con una singola ricerca
- Determina facilmente i dati "di origine" per un determinato utente da mailing_id
A dire il vero, nel mio intimo non mi piace affatto questa idea.
Mappatura 2
(supponiamo che MSG_ * siano costanti definite, tipi enum o un altro identificatore adatto)
| mailing_id (KEY) | user_type (UNIQUE1) | internal_id (UNIQUE2)|
------------------------------------------------------------------
| 1001 | MSG_ADMIN | 87 |
| 1002 | MSG_PROF | 123 |
| 1003 | MSG_STUDENT | 123 |
Con questa configurazione e un indice composito univoco di {user_type, internal_id} le cose diventano molto più pulite, 3NF viene mantenuto e il codice dell'applicazione non deve controllare le anomalie I / U.
Sul lato negativo, c'è una certa perdita di trasparenza nel determinare le tabelle di origine degli utenti che devono essere gestite al di fuori del DB, sostanzialmente equivalenti a un mapping a livello di applicazione dei valori user_type alle tabelle. In questo momento, sono (piuttosto strongmente) propenso a questa seconda mappatura, dal momento che il lato negativo è piuttosto minore.
MA Sono dolorosamente consapevole dei miei limiti e sono sicuro di aver probabilmente perso vantaggi o inciampi in entrambe le direzioni, quindi mi rivolgo a menti più sagge delle mie.