it-swarm.it

Quali problemi avrò creando un database per cliente?

Ricordo dai podcast stackoverflow che Fog Creek usa 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?
49
Rik Heywood

Questa soluzione è chiamata progettazione multi-tenant in cui ogni tenant (cliente) ha il proprio database. Detto questo, ci sono alcune 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. Ad esempio, 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 governarli 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 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.

42
Thomas

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 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.

14
eiefai

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 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.

9
Joe

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 dall'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.

MORAL OF THE STORY: 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.

7
RolandoMySQLDBA

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.

2
David Hall

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ò.

1
Sean Siegel