Quali problemi avrò creando un database per cliente?


49

Ricordo dai podcast stackoverflow che Fog Creek utilizza un database per cliente per Fogbugz . Presumo che ciò significhi che i server di Fogbugz On Demand hanno decine di migliaia di database.

Stiamo appena iniziando a sviluppare un'app Web e abbiamo un problema simile da risolvere (molti clienti con i loro dati isolati).

Quali problemi dovrei aspettarmi con l'uso di un database per cliente? Come posso risolverli?

I miei pensieri iniziali

Vantaggi di un database per cliente

  • Schema di database più semplice
  • Backup più semplici: è possibile eseguire il backup di ogni cliente a sua volta senza influire realmente sugli altri clienti.
  • Semplifica l'esportazione dei dati di un determinato cliente.
  • Migliori prestazioni della cache: una scrittura su una delle tabelle più attive influisce solo sul singolo cliente che ha eseguito la scrittura.
  • Più facile da scalare su hardware. Ad esempio, quando dobbiamo passare da 1 a 2 server, spostiamo solo metà dei nostri clienti sul nuovo server.

svantaggi

  • MySQL può far fronte a 5.000 database? Le prestazioni farebbero schifo?
  • Le modifiche allo schema possono essere difficili da replicare in tutti i database. Dovremmo davvero avere un piano automatizzato per questo, come il versioning dello schema e uno script che capisca come portare un database da una versione all'altra.
  • Fare qualsiasi cosa comune a tutti i nostri clienti potrebbe essere imbarazzante o impossibile
  • Simile al precedente, ma qualsiasi analisi che vogliamo eseguire su tutti i nostri clienti potrebbe essere impossibile. Come dovremmo tenere traccia dell'utilizzo tra tutti i clienti, ad esempio?

2
Ricorda che "database" significa cose diverse per persone diverse. Nel mondo Oracle, un database per utente sarebbe eccessivo. Ma in MySQL "database" è sinonimo di "schema".
Gaius,

Intendo nel senso mysql. USE CompanyData;
Rik Heywood,

1
Microsoft ha un articolo dettagliato sull'architettura dei dati multi-tenant .
Nick Chammas,

non direi che il controllo delle versioni dello schema sia uno svantaggio ... più lavoro, ma nel complesso migliore
Neil McGuigan,

Risposte:


41

Questa soluzione è chiamata progettazione multi-tenant in cui ogni tenant (cliente) ha il proprio database. Detto questo, ci sono altre considerazioni all'approccio alternativo che è un singolo database:

  1. Con un singolo database, tutti devono essere nella stessa versione, non importa quale. Non è possibile aggiornare alcuni clienti e non altri. Questo può essere problematico se un cliente desidera un aggiornamento rapido di un'applicazione che non è pronta per la versione estesa.
  2. Con un singolo database, quando si esegue un aggiornamento, ogni client è inattivo. Se qualcosa va storto, ogni cliente viene fregato.
  3. Con un singolo database, è molto più difficile limitare le risorse. Cioè, se un client sta martellando il database, è più difficile dare loro più risorse separate da tutti gli altri.
  4. È molto più difficile consentire agli utenti di ospitare le proprie versioni dell'applicazione. Se stai costruendo una soluzione che verrà utilizzata dalle grandi aziende, questo è spesso un antipasto. Il loro reparto IT vuole il controllo completo sull'accesso al sistema.
  5. Probabilmente è più economico ridimensionare i database piuttosto che ridimensionarli. Vale a dire, dover investire in hardware più veloce per ospitare un database per dominarli tutti è probabilmente più costoso della capacità di ridimensionare i clienti su server di database più piccoli e meno costosi. Non posso dirlo definitivamente perché dipende molto dal software del server. Se segui MySQL, questo è probabilmente vero perché i costi di licenza sono trascurabili. Tuttavia, se si passa ad SQL Server, ad esempio, il ridimensionamento diventa molto più costoso a meno che non si utilizzi un ambiente VPS e il vantaggio in termini di costi del ridimensionamento rispetto al ridimensionamento delle modifiche. Posso dire, tuttavia, che una volta che il database diventa molto grande, la gestione richiede livelli di competenza sempre maggiori. Database molto grandi richiedono di giocare con più filegroup e di inviare determinati indici a diversi mandrini per ottenere prestazioni migliori. In breve, possono complicarsi molto rapidamente.

Avere database separati significa che devi costruire un meccanismo di aggiornamento che corrisponda alla versione del database con la versione dell'applicazione / del sito. Tuttavia, database separati forniscono un isolamento superiore dei dati e IMO ha un costo di hosting inferiore. Non è una soluzione per tutti gli scenari. Se il tuo sistema non sarebbe mai stato ospitato al di fuori del tuo hosting e avesse bisogno di espandersi rapidamente tra i clienti e avere tutti gli utenti sulla stessa versione dell'applicazione e dello schema del database era desiderabile, sicuramente avere un solo database è un approccio migliore.


2
Eseguo servizi Web sia con il database condiviso che con configurazioni di database separate multi-tenant. Ci sono momenti in cui entrambi sono la scelta giusta. Nell'app in cui ho un database separato per cliente, ho incontrato esattamente gli stessi 5 motivi per cui era la scelta giusta per quell'app.
Dan Grossman,

Il recente database cloud serverless Aurora di Amazon presumibilmente fornisce automaticamente più risorse quando necessario per un carico maggiore e sembrano incoraggiare la progettazione di un singolo database. Ma non lo capisco del tutto. Penso che andrò con un singolo DB, tuttavia, con tabelle separate per ogni utente. Ciò potrebbe rendere più semplice suddividerli in DB separati, se necessario, e semplificare l'esecuzione di query aggregate su tutti i dati degli utenti.
Buttle Butkus,

Solo qualcosa a cui fare attenzione: ho tutti i miei clienti in un unico db e utilizzo un livello di codice db che assicura che ogni query includa criteri specifici del cliente. La parte pericolosa è quando devi uscire dal livello del database per fare qualcosa di molto specifico, come una terribile e complicata query in cui i dati possono fuoriuscire da un luogo inaspettato.
Enigma Plus,

14

Nella mia esperienza non dovresti creare un database per cliente. Lasciate che vi faccia un esempio:

L'anno scorso ho lavorato con 70 database (molto meno di 5000), ciascuno con lo stesso schema e tutti. In teoria, le cose andrebbero come previsto (come menzionate nella sezione vantaggi), ma in realtà non così tanto. Abbiamo avuto molti problemi con l'aggiornamento degli schemi, il supporto utente, l'aggiornamento del software, tu lo chiami. È stato terribile.

Abbiamo usato Firebird e sono stato assunto molto dopo la spedizione del prodotto, ma questo mi ha dato la conoscenza di non lavorare mai con database separati.

Non sto dicendo che non puoi farcela, sto dicendo che le cose possono andare molto male e, ad essere onesti, la tua lista dei vantaggi non sembrava abbastanza allettante da correre il rischio. La maggior parte di essi può essere realizzata con un unico database.


Abbiamo implementato un database di elenchi multipli che serve diversi clienti. Siamo finiti in una situazione in cui i clienti hanno iniziato a desiderare risultati personalizzati. Per risolvere questo problema, abbiamo clonato i proc memorizzati e fornito loro prefissi univoci per i nomi dei clienti e poi li abbiamo chiamati all'interno dell'applicazione. D'altra parte abbiamo venduto 150 negozi web ciascuno con il proprio database separato (il 97% lo stesso). Quindi entrambi possono essere fatti, dipende dalla situazione.
Michael Riley - AKA Gunny,

Bello. Non sto dicendo che non si può fare, solo che non è così facile come sembra, buono per te Gunny.
eiefai,

1
Sarebbe bello se potessi dare esempi di cosa è andato storto. Certo è più difficile mantenere aggiornati tutti i database, ma per decidere dobbiamo essere in grado di misurare i pro contro i contro.
Boris Callens,

9

Probabilmente vorrai mantenere un altro database per tenere traccia della versione di ciascun cliente, in modo da poter tenere traccia di quali sono state o non hanno subito l'ultimo ciclo di modifiche.

Scrivere script sugli aggiornamenti non sarebbe così difficile ... potresti scrivere qualcosa che analizza il catalogo dei database e applica le modifiche necessarie per portare ciascun database all'ultima versione, saltando quelli che non dovrebbero essere aggiornati per qualche motivo.

Dato che i "database" mysql sono solo schemi, come ha sottolineato Gaius, se è tutto in esecuzione dalla stessa istanza del server, puoi semplicemente qualificare il nome delle tabelle che stai cercando di modificare o ottenere informazioni da:

alter schema.table ...
select ... from schema.table

...

Se inizi a suddividere le cose su più server, puoi comunque eseguire lo script di qualcosa che effettua connessioni a più server in modo da poter applicare tutte le modifiche; per l'analisi, ancora una volta, potresti impostare un mucchio di collegamenti al database usando le tabelle federate nel tuo database principale per accedere ai dati da un posto, come avresti appena letto dalle tabelle.

...

Inoltre, tieni presente che non utilizzano mySQL per lo scambio di stack, stanno utilizzando SQL Server.

E non ho idea di quale tipo di performance ci sarebbe in mysql su quella scala, non credo di aver mai superato i 30 "database" in mysql.


Perché non mantenere una tabella di informazioni sulla versione nel proprio db?
Boris Callens,

@Boris: perché è molto più una seccatura nel collegarsi a ciascun database per chiederne la versione quando hai dozzine o centinaia di database. Non è una cattiva idea per ognuno rintracciarsi, ma vale anche la pena avere un elenco principale per il DBA
Joe

7

Ho un client di hosting Web / DB che ha oltre 750 database di clienti con lo stesso numero di tabelle (162) e le stesse strutture di tabelle. Insieme, tutti i dati dei clienti del mio cliente ammontano a 524 GB (95% InnoDB)

Immagina tutti questi database in competizione per 13G di pool di buffer innodb su nove server DB tramite replica circolare. Scalare con quella configurazione hardware non era abbastanza. Immediatamente, abbiamo consigliato al cliente di ridimensionare.

Di recente abbiamo migrato questo client su 3 server DB con una potenza di gran lunga maggiore (A tutti i costi, state lontani da SSD in ambienti ad alta scrittura, SEMPRE !!!). Li abbiamo aggiornati da MySQL 5.0.90 a MySQL 5.5.9. Differenze drammatiche sono state osservate quasi all'istante.

Il ridimensionamento deve essere considerato anche perché se si dispone di centinaia di client che colpiscono la stessa memoria e le stesse risorse del disco, il ridimensionamento riduce il loro utilizzo in modo lineare (O (n)) dove n si basa sul numero di server DB in un ambiente multimaster.

Nel caso del mio cliente, la mia azienda lo sta riducendo da 9 server DB (Quad Code, 32GB RAM, 824G RAID10) a server DB più veloci (Dual HexaCore [esatto 12 CPU], 192GB RAM, 1.7TB RAID10) di MySQL 5.5 .9 (per usufruire della tabella è possibile utilizzare più CPU). Inoltre, immagina un pool di buffer innodb da 150 GB in 50 partizioni da 3 GB ciascuno (pool di buffer multipli InnoDB è una nuova funzionalità di MySQL 5.5). Una scala più piccola, ma enorme, aveva funzionato per l'infrastruttura unica del mio cliente.

MORALE DELLA STORIA : il ridimensionamento o il ridimensionamento non è sempre la soluzione se si dispone di tabelle mal progettate. Quello che voglio dire è questo: se le pagine degli indici hanno una popolazione di chiavi a sbalzo per gli indici a più colonne, la ricerca di chiavi dalle parti a sbalzo degli indici porta alla scansione della tabella dopo la scansione della tabella, o almeno agli indici che non vengono mai utilizzati a causa dell'esclusione dalla query MySQL Optimizer. Semplicemente non vi è alcun sostituto per la progettazione corretta.


2
So che questo è davvero vecchio, ma mi chiedo quale sia il ragionamento alla base del tuo commento sugli SSD in ambienti ad alta scrittura. Mi puoi illuminare?
elixenide,

4
@EdCottrell Immagino sia stato un avvertimento sulle scritture limitate di SSD. Ad un certo punto questo porta il disco al punto che non può più essere utilizzato, credo che negli ultimi anni il TRIM e altre tecnologie siano state integrate nei chip del controller SSD per alleviare questi problemi per la maggior parte, quindi l'SSD scrive non è un grosso problema, anche se sono sicuro che può essere ancora un problema.
Shaunhusain,

2

MySQL crea database in directory separate, quindi molto dipende dal sistema operativo sottostante e dal numero di cartelle / file che può gestire. Non dovrebbe essere un problema con i moderni sistemi operativi, ma è da lì che provengono molti colli di bottiglia.


1

Non c'è niente che dice che devi ospitare diverse versioni del database o dell'app. Cosa c'è di sbagliato nel isolare semplicemente i dati facendo un db per cliente e avendo una versione del database e dell'app? Ovviamente ogni cliente db dovrebbe essere clonato da un modello della versione di lavoro corrente. Dal punto di vista della sicurezza e dell'isolamento dei dati, penso che sia l'ideale.

L'unico aspetto negativo che posso vedere è che dovresti aggiornare manualmente ogni database durante la creazione di una nuova versione. Questo potrebbe essere facilmente automatizzato però.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.