Progettazione di database multi-tenant

1

Il mio capo sta attualmente lavorando su un progetto di database per un sistema ERP / CRM con supporto multi-tenant, che avrà un back-end Sql Server.

Alcuni punti chiave del design:

  • Un'istanza del server ospiterà un database "condiviso" (modello univoco), più un database per azienda (stesso modello)
  • Il database "condiviso" ha tabelle come contatti, utenti, ecc. a cui fare riferimento altri database aziendali.
  • Il database "condiviso" ha trigger che controllano se i suoi dati possono essere cancellati in modo sicuro (se è utilizzato da qualsiasi azienda, l'operazione DELETE deve fallire)
  • Se, per motivi di sicurezza, un'azienda non deve utilizzare informazioni condivisibili, deve essere impostata sulla propria istanza del server, con il proprio database "condiviso" che, in effetti, sarà utilizzato solo da tale azienda.

Ed ecco un esempio di implementazione per un sistema:

ISTANZA SERVER 1:

  • DB condiviso
  • ACME
  • WayneEnterprises
  • KwikEMart

ISTANTANEO SERVER 2:

  • DB condiviso
  • Umbrella

Il mio capo tiene conto di questo disegno sui seguenti vantaggi:

  • Dato che c'è un db per società, le aziende più piccole come KwikEMart non soffriranno del peso di quelle più grandi.
  • L'accesso utente può essere definito su una strategia "per azienda". In questo modo, Apu può ottenere il privilegio di leggere la tabella Invoices di KwikEMart, ma non di ACME.

Anche se capisco questi benefici, i compromessi sull'integrità mi sembrano schiaccianti.

In primo luogo, c'è l'evidente interruzione dell'integrità tra le aziende db e il db condiviso. È impossibile creare chiavi esterne attraverso i limiti del database.

In secondo luogo, cosa succederebbe se il Joker rovinasse il database di WayneEnterprise così male che Batman dovrà ripristinare un backup di un giorno? Se ACME, lo stesso giorno, ha deciso di rimuovere un indirizzo Gotham condiviso che era ancora in uso nella vecchia versione di WayneEnterprise db, allora ogni documento che utilizzava quell'indirizzo non sarebbe più in grado di visualizzarlo. A meno che, naturalmente, non ci sia un backup db condiviso dalla stessa ora che può essere ripristinata. Ma ANCHE se ce ne fosse una, potrebbe portare a ancora più problemi sia per ACME che per KwikEMart.

E sono proprio questi due problemi che mi sono venuti in mente, probabilmente anche altri.

Quindi la mia domanda qui sarebbe: stiamo andando nella giusta direzione con questo? E inoltre, come viene normalmente costruito questo tipo di sistema?

Qualsiasi guida sarà molto apprezzata.

    
posta Crono 23.09.2015 - 17:33
fonte

1 risposta

7

Nei sistemi multi-tennent in cui ho lavorato come DBA e Developer abbiamo utilizzato 1 database per cliente. Quel database era completamente autonomo e non si basava su alcun database condiviso, nemmeno per cose come gli stati negli Stati Uniti.

Per creare un nuovo client, è stato creato un database di modelli che prevedeva la prepopolazione di tutti gli elementi come Stati.

Il motivo per cui non abbiamo archiviato gli indirizzi o altri dati comuni in un database condiviso è che ci ha permesso di spostare i database su diversi server per normalizzare il carico sui server che avevamo. Se un database necessitava di un SLA più elevato a causa di un aggiornamento del client, potevamo semplicemente fare un backup e ripristinare il database del client sul server appropriato e non preoccuparci se "l'indirizzo di Stark Industries" esisteva sul nuovo server.

La domanda ovvia è che cosa succede quando il cliente A aggiorna il numero di telefono o l'indirizzo di un cliente? Il cliente B dovrebbe vedere quel cambiamento? Non porterebbe a dati "duplicati" se ogni cosa è memorizzata in database separati?

Cosa succede se "Stark Industries" vuole che il tuo cliente A utilizzi un numero di telefono diverso dal tuo cliente B? Quindi dovrai avere un modo per mostrarlo e memorizzare i diversi numeri nel database del Cliente o spostare Client A e Client B in diverse istanze. Sono certo che mentre guardi nel tuo database condiviso troverai ulteriori istanze di questo problema su diversi client che desiderano utilizzare i dati in modo diverso.

Per gli aggiornamenti alle tabelle comuni, uno script che scorre in ogni database è piuttosto semplice da scrivere, un cursore su sys.databases e alcuni SQL dinamici si prendono cura di quella parte.

Nel complesso, mentre un database condiviso può sembrare buono dal punto di vista della normalizzazione, una volta che si iniziano a considerare diversi modi in cui i client utilizzano i diversi dati, un database condiviso potrebbe non avere più senso. Se hai intenzione di seguire il percorso di database separati per cliente, vai al massimo e diventi completamente separato senza dati condivisi.

    
risposta data 23.09.2015 - 23:54
fonte

Leggi altre domande sui tag