Domanda

Sto lavorando ad un'applicazione PHP che intende facilitare il flusso di lavoro aziendale e la gestione dei progetti, diciamo qualcosa come Basecamp e GoPlan .

Non sono sicuro di quale sia l'approccio migliore, dal punto di vista del database. Dovrei usare un singolo database e aggiungere colonne specifiche del client a ciascuna delle tabelle o dovrei creare un database per ogni nuovo client? Un fattore importante è l'automazione: voglio che sia semplicissimo creare un nuovo client (e forse aprire la possibilità di registrarti da solo).

Possibili contro che posso pensare di usare un database:

  • Mancanza di estensibilità
  • Problemi di sicurezza (anche se i bug non dovrebbero essere presenti in primo luogo )

Cosa ne pensi di questo? Hai qualche idea sulla soluzione che le aziende di cui sopra hanno più probabilità di scegliere?

È stato utile?

Soluzione

Di solito aggiungo ClientID a tutte le tabelle e vado con un database. Ma poiché il database è di solito difficile da ridimensionare, renderò possibile anche l'esecuzione su diverse istanze di database per alcuni o tutti i client.

In questo modo puoi avere un sacco di piccoli client in un database e quelli grandi su server separati.

Un fattore chiave per la manutenibilità, tuttavia, è mantenere lo schema identico in tutti i database. Ci sarà abbastanza mal di testa per gestire il controllo delle versioni senza introdurre schemi specifici per client.

Altri suggerimenti

Ascolta il podcast StackOverflow in cui Joel e Jeff parlano della stessa domanda. Joel sta parlando della loro esperienza nell'offrire una versione ospitata del loro software. Sottolinea che l'aggiunta di ID client su tutto il DB complica la progettazione e il codice (sei sicuro di non aver dimenticato per caso di aggiungerlo ad alcune clausole WHERE?) E complica la funzionalità di hosting, come i backup specifici del client.

Era nell'episodio n. 20 o n. 21 (controlla i dettagli delle trascrizioni).

A mio avviso, dipenderà dalla tua probabile base di clienti. Se potessi entrare in una situazione in cui entrambi i rivali stanno usando il tuo sistema, allora staresti meglio con database separati. Dipende anche da come più database vengono implementati dal tuo DBMS. Se ogni database ha una copia separata dell'infrastruttura, ciò suggerisce un singolo database (o una modifica del DBMS). Se più database possono essere serviti da un'unica copia dell'infrastruttura, sceglierei database separati.

Pensa al backup del database. Il cliente A dice " Vi prego di inviarmi una copia dei miei dati " ;. Molto, molto più facile in una configurazione di database separata rispetto alla condivisione di un singolo database. Pensa di rimuovere un cliente; ancora una volta, molto più facile con database separati.

(La parte dell '"infrastruttura" ha una bocca mediocre perché ci sono grandi differenze tra i diversi DBMS su ciò che costituisce un "database" rispetto a un' "istanza del server", ad esempio. Aggiungi : la domanda è taggato "mysql", quindi forse quei pensieri non sono completamente pertinenti.)

Aggiungi : Un altro problema: con più clienti in un unico database, ogni query SQL dovrà garantire che vengano scelti i dati per il cliente corretto. Ciò significa che l'SQL sarà più difficile da scrivere e leggere e il DBMS dovrà lavorare di più per l'elaborazione dei dati e gli indici saranno più grandi e ... Vorrei davvero scegliere un database separato per cliente per molti scopi.

Chiaramente, StackOverflow (come esempio) non ha un database separato per utente; usiamo tutti lo stesso database. Ma se gestissi sistemi di contabilità per diverse società, non penso che sarebbe accettabile (per le società, e forse non per le persone giuridiche) condividere database.

  • sviluppo Per un rapido sviluppo, utilizzare un database per cliente. Pensa a quanto sarà facile eseguire il backup, ripristinare o eliminare i dati di un cliente. O per misurare / monitorare / fatturare l'utilizzo. Non dovrai scrivere codice per farlo da solo, basta usare le tue basi di database.

  • Performance Per prestazioni, utilizzare un database per tutti. Pensa al pool di connessioni, alla memoria condivisa, alla cache, ecc.

  • BUSINESS Se il tuo business plan deve avere molti piccoli clienti (pensa a hotmail) probabilmente dovresti lavorare su un singolo DB. E avere tutte le attività amministrative come la registrazione, la cancellazione, la migrazione dei dati, ecc. Completamente automatizzate ed esposte in un'interfaccia amichevole. Se prevedi di avere dozzine o fino a poche centinaia di grandi clienti, puoi lavorare in un DB per cliente e disporre di script di amministrazione del sistema che possono essere gestiti dal personale dell'assistenza clienti.

Il seguente screencast spiega come viene fatto su salesforce.com. Usano un database con una colonna speciale OrgId che identifica i dati di ciascun inquilino. C'è molto di più, quindi dovresti esaminare questo. Andrei con il loro approccio.

C'è un altro eccezionale articolo su MSDN. Spiega in dettaglio quando è necessario utilizzare un approccio condiviso o isolato. Ricorda che avere un DB condiviso per tutti i tuoi inquilini ha alcune importanti implicazioni per la sicurezza e se tutti condividono gli stessi oggetti DB potresti voler usare [sicurezza a livello di riga] - a seconda del DBMS che usi (sono sicuro che sia possibile in MS SQL Server e Oracle, probabilmente anche in IBM DB2). Puoi utilizzare trucchi come sicurezza a livello di riga in mySQL per ottenere risultati simili (visualizzazioni + trigger ).

Per la multi-tenancy, le prestazioni aumentano in genere di più le risorse che riesci a condividere tra i tenant, vedi

http://en.wikipedia.org/wiki/Multitenancy

Quindi, se puoi, vai con il singolo database. Sono d'accordo che i problemi di sicurezza si verificherebbero solo a causa di bug, in quanto è possibile implementare tutto il controllo di accesso nell'applicazione. In alcuni database, è ancora possibile utilizzare il controllo di accesso al database mediante un uso attento delle viste (in modo che ogni utente autenticato ottenga una vista diversa).

Esistono anche modi per fornire estensibilità. Ad esempio, è possibile creare una singola tabella con attributi di estensione (chiave per tenant, record di base e ID dell'attributo di estensione). Oppure puoi creare tabelle di estensioni per tenant, in modo che ogni tenant abbia il suo schema di estensione.

Quando si progetta un database multi-tenant, in genere sono disponibili tre opzioni:

  1. Avere un database per inquilino
  2. Avere uno schema per inquilino
  3. Tutti gli inquilini devono condividere le stesse tabelle

L'opzione scelta ha implicazioni su scalabilità, estensibilità e isolamento. Queste implicazioni sono state ampiamente discusse in diverse Domande StackOverflow e articoli del database.

In pratica, ognuna delle tre opzioni di progettazione, con sufficiente sforzo, può rispondere a domande su scala, dati che variano tra i tenant e isolamento. La decisione dipende dalla dimensione primaria per cui stai costruendo. Il sommario:

  • Se stai costruendo per la scala: chiedi a tutti gli inquilini di condividere le stesse tabelle
  • Se stai costruendo per l'isolamento: crea un database per tenant

Ad esempio, Google e Salesforce seguono il primo modello e i loro tenant condividono le stesse tabelle. Stackoverflow invece segue il secondo modello e mantiene un database per tenant. Il secondo approccio è anche più comune nelle industrie regolamentate, come l'assistenza sanitaria.

La decisione si riduce alla dimensione principale per cui stai ottimizzando la progettazione del database. Questo articolo sulla progettazione di Database SaaS per scalare parla dei compromessi e fornisce una sintesi nel contesto di PostgreSQL.

Un altro punto da considerare è che potresti avere l'obbligo legale di mantenere i dati di una società separati da quelli degli altri.

Avere un database per client generalmente non si adatta bene. MySQL (e probabilmente altri database) tiene aperte le risorse per tabella, ciò non si presta bene a 10k + tabelle su un'istanza, cosa che accadrebbe in una situazione di multi-tenancy su larga scala.

Naturalmente, se hai qualche altro problema che causa altri problemi prima di arrivare a questo livello, questo potrebbe non essere pertinente.

Inoltre, " sharding " è probabile che un'applicazione multi-tenant & # 8364; essere la cosa giusta da fare alla fine man mano che la tua applicazione diventa sempre più grande.

Frammentazione non significa tuttavia un database (o un'istanza) per inquilino, ma uno per frammento o set di frammenti, che possono avere diversi inquilini ciascuno. Dovrai scoprire i parametri di ottimizzazione giusti per te, probabilmente in produzione (quindi probabilmente deve essere abbastanza sintonizzabile fin dall'inizio)

& # 8364; Non posso garantirlo.

Puoi iniziare con un singolo database e partizionarlo man mano che l'applicazione cresce. Se lo fai, ci sono alcune cose che consiglierei:

1) Progettare il database in modo che possa essere facilmente partizionato. Ad esempio, se i clienti condivideranno i dati, assicurarsi che i dati vengano replicati facilmente in ciascun database.

2) Quando si dispone di un solo database, assicurarsi che venga eseguito il backup su un altro server fisico. In caso di failover è possibile ripristinare il traffico su questo altro server e mantenere intatti i dati.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top