Questa domanda riguarda come dovrei progettare un database, può essere un database relazionale / nosql, a seconda di quale sarà la soluzione migliore
Dato un requisito in cui è necessario creare un sistema che coinvolgerà un database per tracciare "Azienda" e "Utente". Un singolo utente appartiene sempre a una sola azienda
- Un utente può appartenere a una sola società
- Una società può avere molti utenti
Il design per il tavolo "Azienda" è piuttosto semplice. La società avrà i seguenti attributi / colonne: (manteniamolo semplice)
ID, COMPANY_NAME, CREATED_ON
Primo scenario
Semplice e diretto, gli utenti hanno tutti lo stesso attributo, quindi questo può essere facilmente fatto in stile relazionale, tabella utente:
ID, COMPANY_ID, FIRST_NAME, LAST_NAME, EMAIL, CREATED_ON
Secondo scenario
Cosa succede se diverse aziende vogliono memorizzare attributi di profilo diversi per i loro utenti. Ogni azienda avrà un set definito di attributi che si applicherebbe a tutti gli utenti di quella società.
Per esempio:
- La società A vuole archiviare: LIKE_MOVIE (booleano), LIKE_MUSIC (booleano)
- La società B vuole archiviare: FAV_CUISINE (String)
- La società C vuole archiviare: OWN_DOG (booleano), DOG_COUNT (int)
Approccio 1
il modo della forza bruta è avere un singolo schema per l'utente e lasciare che abbiano valori 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
Il che è un po 'brutto perché finirai con un sacco di NULLS e righe utente che hanno colonne che sono irrilevanti per loro (cioè tutti gli utenti appartenenti alla Società A hanno valori NULL per FAV_CUISINE, OWN_DOG, DOG_COUNT)
Approccio 2
un secondo approccio, è avere "campo in forma libera":
ID, COMPANY_ID, FIRST_NAME, LAST_NAME, EMAIL, CUSTOM_1, CUSTOM_2, CUSTOM_3, CREATED_ON
Che sarebbe brutto da solo poiché non hai idea di quali campi personalizzati siano, il tipo di dati non rifletterà i valori memorizzati (ad esempio, memorizzeremo il valore int come VARCHAR).
Approccio 3
Ho esaminato il campo JSON di PostgreSQL, nel qual caso avrai:
ID, COMPANY_ID, FIRST_NAME, LAST_NAME, EMAIL, CUSTOM_PROFILE_JSON, CREATED_ON
In questo caso, come saresti in grado di applicare diversi schemi a un utente? Un utente con la società A avrà uno schema simile
{"LIKE_MOVIE":"boolean", "LIKE_MUSIC": "boolean"}
Mentre un utente con la società C avrà uno schema diverso:
{"OWN_DOG ":"boolean", "DOG_COUNT": "int"}
Come devo 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 dell'utente nelle righe anziché nelle 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 quadro completo dell'utente, è necessario eseguire molti join, più join alla tabella "profilo personalizzato" sui diversi attributi personalizzati
2) Il valore dei dati viene sempre archiviato come VARCHAR come generico, anche se sappiamo che i dati dovrebbero essere interi o booleani, ecc.