500 database o 1 database con 500 tabelle o solo 1 tabella con tutti i record? [duplicare]

15

Attualmente ho un'applicazione che viene utilizzata da un singolo cliente finale. Per facilità di discussione, supponiamo che l'applicazione abbia bisogno di una sola tabella di database per tutti i record. Ora devo supportare la multi-tenancy e quindi in futuro avrò circa 500 clienti che utilizzano lo stesso server di database.

1) Una possibile soluzione è avere un database separato per ogni cliente. Poiché ci saranno circa 500 clienti che significa avere MySQL / SQL Server / Oracle / etc ... ospitare 500 database separati. Sembra un eccesso per un server di database in esecuzione su un server medio basato su cloud.

2) Un'altra soluzione è quella di restare con il singolo database che ho già, ma di avere 500 tabelle diverse, una per ogni cliente finale. Ogni cliente calcola in media circa 2000 record nella propria tabella. È facile da implementare e suppongo che semplifichi la migrazione del cliente a un altro server, semplicemente spostando i dati dell'intera tabella.

3) Infine, potrei limitarmi a utilizzare una singola tabella nel singolo database. Invece aggiungo una colonna aggiuntiva che identifica il cliente a cui appartiene il record. Ma poi il tavolo finisce con circa 1.000.000 di record, che è l'aggregato di tutti i 500 clienti che in media 2.000 ciascuno.

Non ne so abbastanza sulle prestazioni e sul ridimensionamento per sapere che 1, 2, 3 darà le migliori prestazioni. Qualche idea?

    
posta Phil Wright 24.10.2014 - 05:33
fonte

7 risposte

14

Personalmente, sceglierei l'opzione 3 perché:

  • È normalizzato e semplice
  • Facile query per rapporti
  • Facile backup (solo 1 database di cui preoccuparsi)
  • Se indicizzi bene la tabella, le prestazioni non dovrebbero essere un problema

Inoltre, Prestazioni a parte, ecco alcuni motivi per cui vorrai evitare le opzioni 1 e 2.

Contro se vai con 500 database, 1 per ogni cliente:

  • I backup del database saranno noiosamente noiosi e noiosi
  • Le query del database incrociato sono normalmente un lusso dei server di database aziendali, in altre parole, generare report dei clienti sarà un problema perché non è possibile avere una singola query per estrarre tutte le informazioni sui clienti rilevanti nel database
  • inelegante

Contro se vai con 500 tabelle in 1 database, 1 tabella per cliente:

  • Il tuo database è orribilmente denormalizzato, molte informazioni sulla colonna vengono duplicate ovunque
  • Anche se è più facile interrogare molte tabelle che eseguire query da diversi database, dovresti comunque eseguire la stessa query su dio solo quante tabelle invece di una sola query
risposta data 24.10.2014 - 05:55
fonte
4

C'è molto altro da valutare oltre alla semplice prestazione quando si considera la multitenancy. Ti consiglio di leggere questo articolo MSDN per ulteriori dettagli.

In generale, devi considerare questi fattori prima di stabilirti su un particolare approccio.

  • Costi di amministrazione del sistema
  • Costi del server di database (ovvero hardware)
  • Costi di licenza del database (ovvero software)
  • Complessità coinvolte nella scrittura del codice
  • Complessità coinvolte nella gestione del codice
  • Convalida della separazione di sicurezza e ambiente
  • Prestazioni e SLA attesi
  • Utilizzo client e aggregato dei dati

E come hai notato, ci sono essenzialmente tre approcci da considerare:

  1. Database dedicati per ogni cliente
  2. Database condiviso, schemi separati
  3. Database condiviso, schema condiviso

E un breve riassunto di pro e contro:

Database dedicato per ogni cliente

Costi più elevati su tutta la linea, ma codice più semplice e più facile da convalidare dal punto di vista della sicurezza. Trivial per aggiornare un particolare ambiente all'aumentare dell'utilizzo dei dati del client.

Database condiviso, schemi separati

Riduzione dei costi rispetto all'approccio database dedicato, ma al compromesso di una maggiore complessità del codice. E dovrai essere più diligente per assicurarti che gli schemi rimangano separati. Potresti avere qui un codice più ripetitivo poiché a volte dovrai copiare / incollare le cose su base client. Di nuovo, relativamente banale per migrare un client se il loro uso dei dati giustifica un aggiornamento.

Database condiviso, schema condiviso

Ha anche diminuito i costi, ma la complessità del codice diventa maggiore al fine di garantire che le cose rimangano sicure. Esegui un rischio maggiore di esposizione involontaria ai dati se commetti un errore nel livello di accesso di sicurezza. D'altra parte, avrai codice meno ripetitivo in quanto non stai duplicando le cose attraverso gli schemi. Uno svantaggio è che questo approccio presenta il percorso di migrazione più complicato quando l'utilizzo dei dati di un client supera le capacità dell'ambiente esistente.

I secondi due approcci sono quelli che ho visto più comunemente usati a causa della diminuzione dei costi.
Le organizzazioni che hanno clienti con un utilizzo dei dati molto diverso tendono a utilizzare il secondo approccio.
Le organizzazioni con un utilizzo di dati costante e inferiore si appoggiano al terzo.

    
risposta data 24.10.2014 - 16:51
fonte
2

IMHO farà la differenza se progetterai una nuova applicazione da zero con multi-tenancy in mente, o se userai un'applicazione complessa e esistente che non è stata progettata per la multi-tenancy.

Per la prima situazione, l'approccio "un DB e una tabella" sarà probabilmente il migliore, come hanno scritto gli altri. Per il secondo, aggiungere successivamente la multi-tenancy all'applicazione può essere così difficile che l'utilizzo di diversi database può essere effettivamente l'alternativa migliore, poiché evita la necessità di modificare qualcosa nella propria applicazione. Naturalmente, "diversi database" comporta un overhead diverso quando si utilizza un sistema Oracle rispetto a un sistema MS SQL o un server MySQL. In un sistema Oracle, esiste anche l'opzione di "schemi diversi" e da Oracle 12c esiste un'opzione "Multitenant" specifica che consente di creare un DB contenitore contenente molti "database collegabili".

Fintanto che hai una sola tabella, mi aspetto che la tua applicazione non sia così complessa da non poter implementare la multi-tenancy in seguito, ma hai scritto

For ease of discussion assume the application only needs a single database table for all records.

quindi suppongo che la cosa reale abbia più tabelle e devi decidere quanto sia difficile apportare le modifiche rilevanti alla tua applicazione.

    
risposta data 24.10.2014 - 15:36
fonte
1

Immagino che parte di esso dipenda dalle preferenze personali.

Se gestisci più clienti nella stessa applicazione (cioè un programma che riceve richieste da più clienti), preferirei l'opzione 3. Gestire più clienti in questo caso è parte della logica dell'applicazione e progettato nel modello dati.

Se si esegue un'istanza separata dell'applicazione per ciascun cliente, inizialmente tenderei all'opzione 1, poiché ha il miglior isolamento tra i clienti.

Tuttavia, con diverse centinaia di clienti l'opzione 1 diventa piuttosto ingombrante dal momento che non si adatta bene e l'opzione 2 è un buon compromesso.

    
risposta data 24.10.2014 - 08:01
fonte
1

Il numero 1 è la migliore prestazione, il numero 3 è il peggiore. Ma in realtà, come hanno affermato molte altre risposte, questa è l'ultima cosa di cui devi preoccuparti, specialmente con la quantità di dati che hai inserito nella tua domanda.

Le cose di cui sarei preoccupato:

  • Chi possiede i dati e quanto è proprietario?
  • Ci saranno realisticamente cambiamenti nello schema e / o versioni live differenti?
  • Che tipo di manutenzione dovresti fare?
  • Qualsiasi aggregazione tra client è necessaria?
  • Qual è il budget qui?
  • Ci sono dei requisiti legali? Ci può essere in futuro?

Per espandere su ciascuno di questi:

Chi possiede i dati e quanto è proprietario?

Se questo è i tuoi dati, allora questo non dovrebbe essere un problema. Tuttavia, se si tratta di dati aziendali del cliente, o di qualsiasi tipo di dati personali, o di dati che non devono assolutamente perdere, il numero 3 è fuori questione. A meno che tu non abbia rinunciato alla magia per rendere illeggibile solo un sottoinsieme di righe , puoi consentire a qualsiasi client di accedere a qualsiasi altro dato dei clienti. I tuoi clienti potrebbero non apprezzarlo. Infatti, se sei un target succoso, le statistiche sul tempo di esecuzione o sulla tabella (come il numero di righe) forniscono già più informazioni di quelle che potresti voler esporre.

Il numero 2 è OK, purché le autorizzazioni e gli utenti siano corretti.

Ci saranno realisticamente cambiamenti nello schema e / o versioni live differenti?

La risposta a questa domanda è - ovviamente ci sono, prima o poi. A meno che tu non abbia solo 1 campo di testo nel tuo DB in cui metti tutto.

Ci sono modi per cambiare lo schema con garbo: assicurati che la nuova versione del codice funzioni sia con la versione precedente che con quella nuova dello schema, o viceversa. Dovrai anche assicurarti che tutti i clienti siano aggiornati tempestivamente. Tuttavia, ciò significa anche che devi forzare l'aggiornamento del client o estendere la modifica dello schema tra 2 aggiornamenti principali.

Quanto sopra si riferisce alla tua situazione? Bene, nel numero 3, devi sincronizzare tutti gli aggiornamenti di tutti i client. Questo è un incubo per non dire altro. I numeri 1 e 2 sono più semplici in questo senso, dal momento che puoi fare i client problematici uno alla volta senza disattivarli.

Il numero 3 è anche un inferno nel caso in cui uno dei client richieda una versione più vecchia dell'app, perché quella nuova non li soddisfa.

Che tipo di manutenzione dovresti fare?

Il backup è la prima cosa che viene in mente. Qui l'opzione 3 mette in ombra tutto: basta scaricare il tavolo e il gioco è fatto! Il numero 2 è OK: un backup completo del DB non è troppo difficile. Il numero 1 è sbagliato: devi configurare un backup su OGNI DB. È incredibilmente facile dimenticare o fudge qualcosa. Tuttavia, fornendo un client un backup dei loro dati su richiesta è banale in 1 e 2, ma un po 'coinvolto in 3.

Quante volte hai bisogno di cambiare query al DB? Per il numero 3 saranno più complicati - o meglio - sono semplici, ma hanno un numero incredibile di posti che puoi rovinare perché hai dimenticato AND clientId = :clientId .

Qualunque aggregazione inter-cliente di cui hai bisogno?

Se si tratta del caso 1, è meglio sperare di avere un buon team di sviluppatori e un server aziendale. Non c'è modo di fare ciò che sia facile, affidabile e conveniente.

Il numero 2 è OK finché puoi generare correttamente le tue query.

Il numero 3 è il più semplice.

Dovresti porre la domanda al tuo dipartimento di analisi (se ne hai uno).

Qual è il budget qui?

Un sacco di DB potrebbe richiedere molte licenze. E molte porte aperte e possibilmente macchine virtuali. Questo dipende da cosa stai usando esattamente e da cosa lo ospita.

Ci sono dei requisiti legali? Ci può essere in futuro?

A volte ci sono requisiti legali su dove i dati possono fisicamente risiedere. Se tutti i tuoi clienti provengono da un paese che non dovrebbe essere un problema, dovresti farlo in tutto il mondo. Questo è particolarmente applicabile ai dati finanziari e personali.

Una domanda non menzionata qui - ci sono requisiti sulla latenza per il DB? Il tuo cliente australiano o russo potrebbe non essere molto contento delle loro domande che arrivano fino a New York (per esempio).

Un altro è la resilienza e DDoS: i servizi separati fisicamente per i client separati sono molto più difficili da rimuovere.

TL; DR

Tutto sommato - direi se lo si utilizza come piccola memoria principalmente per i dati non proprietari e non critici, e non aspettatevi una crescita eccessiva (come nella quantità di dati, non nella crescita dell'azienda) o modifica dei formati: utilizza Numero 3. Meno problemi, meno costi, meno amministratori coinvolti. Se questo si trasformerà in datastore adeguati con materiale potenzialmente permissivo in essi - usa il numero 1. Il numero 2 è da qualche parte nel mezzo.

    
risposta data 24.10.2014 - 17:32
fonte
0

Usa tutti e tre. Una taglia non va bene per tutti.

Il modello condiviso / server condiviso potrebbe essere utilizzato per piccole implementazioni o per quei clienti che desiderano la minima quantità di sicurezza dei dati. Probabilmente ha bisogno di chances applicativi per questo.

Costo: $

Il modello esclusivo / server condiviso consente di aumentare la segregazione dei dati ma il client condivide le stesse risorse (server).

Costo: $$$

Il modello esclusivo / modello esclusivo consente un silo unico.

Costo: $$$$$

Questo modello consente ai clienti di scegliere e scegliere il modello più adatto a loro (a seconda delle dimensioni e dei problemi di sicurezza). Basta capire quanto pagare per ciascuno per mantenere redditizio.

    
risposta data 24.10.2014 - 17:20
fonte
0

Tutto uguale, opzione # 3 - tutto in una tabella (o serie di tabelle).

Oltre ad alcune delle altre ragioni fornite - la manutenzione e le prestazioni più semplici non dovrebbero essere notevolmente diverse se correttamente indicizzate - c'è anche il problema delle prove future.

Considera la migrazione dei dati. Se vai con l'opzione 3, in futuro, è semplice trasferirla a 1 o 2 se è davvero necessario. Ad esempio, se un cliente ha bisogno di una personalizzazione significativa in modo tale da richiedere il proprio database. Puoi semplicemente spostare i dati in un nuovo tavolo, mantenendo gli ID uguali. D'altro canto, sarebbe molto più difficile passare da 1 o 2 all'opzione 3 se si scoprono i motivi per cui è necessario condividere tali dati. È sempre più facile suddividere i dati piuttosto che combinarli.

    
risposta data 24.10.2014 - 17:43
fonte

Leggi altre domande sui tag