Questa domanda riguarda come dovrei progettare un database, può essere database relazionale / nosql, a seconda di quale sarà la soluzione migliore
Dato un requisito in cui è necessario creare un sistema che coinvolga un database per tracciare "Società" e "Utente". Un singolo utente appartiene sempre a una sola società
- Un utente può appartenere a una sola società
- Una società può avere molti utenti
Il design per la tabella "Company" è abbastanza semplice. La società avrà i seguenti attributi / colonne: (manteniamola semplice)
ID, COMPANY_NAME, CREATED_ON
Primo scenario
Semplice e amp; in modo diretto, tutti gli utenti hanno lo stesso attributo, quindi questo può essere fatto facilmente in stile relazionale, tabella utente:
ID, COMPANY_ID, FIRST_NAME, LAST_NAME, EMAIL, CREATED_ON
Secondo scenario
Che succede se aziende diverse vogliono archiviare un attributo di profilo diverso per il loro utente. Ogni azienda avrà un insieme definito di attributi che si applicherebbe a tutti gli utenti di tale azienda.
Ad esempio:
- La società A vuole memorizzare: LIKE_MOVIE (booleano), LIKE_MUSIC (booleano)
- La società B vuole memorizzare: FAV_CUISINE (String)
- La società C vuole memorizzare: OWN_DOG (booleano), DOG_COUNT (int)
Approccio 1
il metodo della forza bruta consiste nel disporre di un singolo schema per l'utente e lasciare che siano nulli quando non appartengono alla società:
ID, COMPANY_ID, FIRST_NAME, LAST_NAME, EMAIL, LIKE_MOVIE, LIKE_MUSIC, FAV_CUISINE, OWN_DOG, DOG_COUNT, CREATED_ON
Che è un po 'brutto perché ti ritroverai con un sacco di NULL e righe utente che hanno colonne irrilevanti per loro (per esempio tutti gli utenti appartenenti alla Compagnia A hanno valori NULL per FAV_CUISINE, OWN_DOG, DOG_COUNT)
Approccio 2
un secondo approccio, è quello di avere "campo modulo libero":
ID, COMPANY_ID, FIRST_NAME, LAST_NAME, EMAIL, CUSTOM_1, CUSTOM_2, CUSTOM_3, CREATED_ON
Che sarebbe brutto da solo dato che non hai idea di quali siano i campi personalizzati, il tipo di dati non rifletterà i valori memorizzati (ad esempio, memorizzeremo il valore int come VARCHAR).
Approccio 3
Ho esaminato il campo JSON PostgreSQL, nel qual caso avremo:
ID, COMPANY_ID, FIRST_NAME, LAST_NAME, EMAIL, CUSTOM_PROFILE_JSON, CREATED_ON
In questo caso, come saresti in grado di applicare schemi diversi a un utente? Un utente con la società A avrà uno schema simile a
{"LIKE_MOVIE":"boolean", "LIKE_MUSIC": "boolean"}
Mentre un utente con Company C avrà uno schema diverso:
{"OWN_DOG ":"boolean", "DOG_COUNT": "int"}
Come dovrei risolvere questo problema? Come posso progettare correttamente il database per consentire questo schema flessibile per un singolo "oggetto" (Utente) basato sulla relazione che hanno (Azienda)?
soluzione relazionale? soluzione nosql?
Modifica: ho anche pensato a una tabella "CUSTOM_PROFILE" che essenzialmente memorizzerà gli attributi utente in righe anziché in colonne.
Ci sono 2 problemi con questo approccio:
1) I dati crescono per utente crescono come righe anziché come colonne - e questo significa che per ottenere un'immagine completa dell'utente, devono essere necessari molti join, più join per il " tabella profilo personalizzato "sui diversi attributi personalizzati
2) Il valore dei dati viene sempre memorizzato come VARCHAR per essere generico, anche se sappiamo che i dati dovrebbero essere interi o booleani ecc.