2013-07-27 11 views
10

Utilizzo Symfony da quasi 2 anni, finora, ogni progetto che costruisco viene distribuito in modo specifico per ciascun client (vale a dire un client, un codebase, un db).SAAS e multi-tenancy in Symfony2?

Diciamo che ho un'app di gestione dei progetti che desidero distribuire per molti client. Supponendo che i clienti andranno con qualsiasi caratteristiche costruisco nel sistema, se schiero una base di codice diverso (quindi, un DB diverso) per ogni cliente, qui ci sono i problemi che prevedono:

  1. Pushing correzioni di bug e aggiornamenti sarà doloroso. Devo inviarlo a tutti i repository che ho distribuito. Non scalerà bene se ho 50 client che usano la stessa app.

  2. La gestione è dolorosa. Come faccio a creare un sistema di amministrazione per me stesso in cui posso inserire TUTTI i progetti in un'unica tabella HTML? Dopotutto, ogni client ha il proprio database, giusto? Per farmi fare qualcosa di significativo con tutti i record di tutti i miei clienti, ho bisogno di un modo per esaminare tutti i loro database in una volta sola, il che ... non credo che Symfony lo consenta. (Non sono sicuro)

  3. Problemi dell'account utente. Se un utente lavora per più aziende, tutte utilizzando la mia app Gestione progetti, l'utente deve registrarsi più volte. (So ​​che questo può essere aggirato se uso oauth, ma sto cercando di non andare lì se posso)

Qui ci sono le soluzioni che ho pensato e provato a un certo punto.


Soluzione 1

un database e una base di codice per tutti i miei clienti. I progetti andranno sotto una tabella, le fatture vanno sotto una tabella, tutte contrassegnate dal proprio client_id. Gli utenti possono essere assegnati ai progetti quindi non è necessario registrarsi più volte.

Questo non è difficile da creare. Ma cosa succede se clienti diversi hanno bisogno di colonne diverse per le loro fatture? La mia tabella delle fatture continuerà ad espandersi (con campi diversi richiesti da client diversi) e ogni riga può potenzialmente contenere molti campi null. Per non parlare, la mia entità fattura crescerà in dimensioni del file, e dovrà aggiornare lo schema del database ogni volta che una nuova personalizzazione entra.


Soluzione 2

Un database in cui ogni cliente ha il proprio prefisso tabella. Quindi per il cliente A, potrei usare clientA_projects, clientA_invoices, clientA_configuration ecc.

Questo è l'ideale se ogni cliente desidera personalizzare i propri campi. Ma questo significa che devo creare una nuova entità e formare classi per ogni nuovo cliente che entra nel sistema? Sembra che con questa soluzione, ho bisogno di aggiornare lo schema del database con ogni nuovo client che ottengo.


Attualmente, sto sperimentando con i database di schema-less (mongo e divano), sperando che senza bisogno di specificare lo schema della tabella in anticipo, posso implementare Soluzione 1 senza problemi. Ma sto ancora sperimentando, e ci sono modi per andare prima di avere il coraggio di implementare un'app pronta per la produzione, non avendo familiarità con i problemi di mongo e couch con Symfony.


Quindi, questo è il punto in cui sono bloccato. Essendo un programmatore autodidatta, sento di avere un sacco di buchi nella mia conoscenza che richiede il riempimento (al contrario di qualcuno di un background CS). Non ci sono molti posti sul web che parlano di Symfony 2 e multi-tenancy (forse sto cercando la cosa sbagliata). Se qualcuno di qualcuno può indicarmi una direzione più chiara, forse le migliori pratiche, progetti di esempio, lo apprezzerò davvero!

Btw, ho intenzione di eseguirlo nell'ultima versione di Symfony (2.3.2 in questo momento).

Grazie in anticipo ragazzi.

+0

@ LU0-dezhang c'è c'è qualche possibilità per te di condividere i tuoi risultati? Sto avviando una nuova app SaaS usando Symfony3 ma non ho idea di database e organizzazione dei progetti Symfony3, quindi ... tosti? – ReynierPM

risposta

6

Sto anche utilizzando Symfony2 per una quantità di tempo simile (da uno dei BETA) e vi consiglio di andare con la soluzione n. Se stai andando in SaaS non puoi dare il codice ai clienti per i motivi che hai scritto (problemi con aggiornamenti/aggiornamenti principalmente). L'intera seccatura sarà nella gestione degli utenti - quale utente ha accesso a quali dati, appartiene a quale gruppo, azienda e così via. Tutte le altre cose, se fatte correttamente, saranno codificate nello stesso modo agonostico dell'utente. Cosa dovresti fare con requisiti diversi per diverse aziende? Effettuare tali funzioni configurable. È possibile implementare questo su diversi livelli: gli attributi

  • semplice entità: hanno un campo attributes in ogni tabella e salvare tutto come JSON, YAML o altro contenuto dinamico-structurable,
  • configurazione generale: avere un posto in cui un'entità la configurazione di base è archiviata (nei mezzi che ho scritto sopra) e consente agli utenti di gestire nuove funzionalità da lì, tutte le modifiche vengono propagate a entità semplici,
  • implementare qualcosa che io chiamo Entity Parameters Pattern - progettare tabelle di database che conterrebbero tipi di parametro, parametro valori e relazione con altre entità su diversi livelli e quindi creare parametri configurabili generici tipi che possono essere applicati a qualsiasi luogo con un significato predefinito. Ad esempio "preferred_season" essendo un parametro di tipo "choice_string" contenente la configurazione "spring, summer, autumn, winter" e se collegato a una determinata entità restituisce sempre un campo <select> con scelte e salva il valore selezionato in relazione sia all'entità che al tipo di parametro .

Anche la soluzione # 1 ha un vantaggio imbattibile: potrebbe gestire più di una società anche se si desidera fornire il codice alla fine. Dovresti solo mascherare la possibilità di aggiungere altro. :)

Questa domanda è contrassegnata Symfony2 ma in realtà non dovrebbe. Non importa quale framework stai usando, dovresti astrarre il tuo design dell'applicazione dal codice e quindi utilizzare i framework come mero strumento per eseguire il lavoro senza intoppi. Mi piacerebbe dire che anche prendendo in considerazione la frase precedente, sono assolutamente innamorato di Symfony2. :)

1

So che questa è una domanda più vecchia ma può essere utile per gli altri.

Sono d'accordo con @Tomasz e soluzione n. 1 con one database - tutti gli inquilini in un database. Il problema più grande qui è la corretta progettazione del database per risolvere ulteriori problemi di sicurezza: l'accesso alle risorse deve essere controllato dall'applicazione per impedire l'accesso non autorizzato tra gli inquilini. Dall'altra parte abbiamo un'implementazione semplice poiché stiamo implementando una singola applicazione con un solo database.

bell'articolo su Symfony2 e trasferirsi in SaaS modello: http://www.browserlondon.com/blog/2015/01/moving-to-a-saas-model-with-symfony2/

anche "deve leggere" articolo sulla progettazione di database in SaaS piattaforma - modelli che sono indipendenti dalla piattaforma: http://labs.octivi.com/database-design-in-saas-platforms/