Un nuovo requisito è emerso su una vecchia base di codice, che sostanzialmente consente la comunicazione diretta (interna) tra due classi di utenti precedentemente non direttamente collegate (archiviate in tabelle diverse con schema completamente diverso e, purtroppo, il codice è a malapena consapevole di OO, molto meno progettato, quindi non esiste una classe genitore). Dato che siamo pronti a appendere un sacchetto su questa vecchia configurazione che non ha mai considerato questa funzionalità, non vi è alcuna garanzia che non vi siano collisioni PK - dato il set di dati in uso, è praticamente garantito che ci siano ARE.
Quindi, la soluzione sembra ovvia: uccidila con il fuoco e riscrivi l'intero disordine 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 se ci sono pro e contro che mi sono perso.
Per chiarire l'astrazione, considera tre gruppi di dati utente diversi: Professori, Amministrazione, Studenti (No, questo non è un compito da svolgere a casa. Prometti!)
Mappatura 1
(professor_id, admin_id e student_id sono chiavi esterne delle rispettive tabelle)
| mailing_id (KEY) | professor_id | admin_id | student_id |
-------------------------------------------------------
| 1001 | NULL | 87 | NULL |
| 1002 | 123 | NULL | NULL |
| 1003 | NULL | NULL | 123 |
Il +/- di questo approccio sembra piuttosto pesante contro:
- Due campi "sprecati" per riga
- Viola 2NF
- Vulnerabile per inserire / aggiornare anomalie (una riga con solo 0-1 campo impostato 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 la verità, nel mio istinto, questa idea non mi piace per niente.
Mappatura 2
(supponiamo che MSG_ * siano costanti definite, tipi di 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, il 3NF viene mantenuto e il codice dell'applicazione non deve verificare le anomalie I / U.
Il rovescio della medaglia, c'è una certa perdita di trasparenza nel determinare le tabelle di origine dell'utente che devono essere gestite al di fuori del DB, sostanzialmente equivalendo a una mappatura a livello di applicazione dei valori user_type sulle tabelle. In questo momento, sono (piuttosto fortemente) incline a questa seconda mappatura, poiché il rovescio della medaglia è piuttosto minore.
MA sono dolorosamente consapevole dei miei limiti e sono sicuro di aver probabilmente perso vantaggi o ostacoli in entrambe le direzioni, quindi mi rivolgo a menti più sagge delle mie.