Senza schema / flessibile + database ACID?


15

Sto cercando di riscrivere un'applicazione on-premise (installata localmente) basata su VB (fatturazione + inventario) come applicazione Clojure basata sul web per i clienti delle piccole imprese. Intendo che questo sia offerto come applicazione SaaS per clienti in attività simili.

Stavo guardando le opzioni del database: la mia scelta era un RDBMS: Postgresql / MySQL. Potrei scalare fino a 400 utenti nel primo anno, con in genere 20-40 visualizzazioni di pagina / al giorno per utente, principalmente per transazioni non viste statiche. Ogni vista coinvolgerà il recupero dei dati e l'aggiornamento dei dati. È necessaria la conformità ACID (o almeno così penso). Quindi il volume delle transazioni non è enorme.

Sarebbe stato un gioco da ragazzi scegliere uno di questi in base alle mie preferenze, ma per questo requisito, che credo sia tipico di un'app SaaS: lo schema cambierà quando aggiungo più clienti / utenti e per ogni cliente cambiamento delle esigenze aziendali (offrirò una flessibilità limitata solo per cominciare). Dato che non sono un esperto di DB, in base a ciò che posso pensare e che ho letto, posso gestirlo in diversi modi:

  1. Disporre di uno schema RDBMS tradizionale in MySQl / Postgresql con un singolo DB che ospita più tenant. E aggiungi abbastanza colonne "fluttuanti" in ogni tabella per consentire modifiche future mentre aggiungo più clienti o modifiche per un cliente esistente. Ciò potrebbe avere un aspetto negativo nel propagare le modifiche al DB ogni volta che viene apportata una piccola modifica allo schema. Ricordo di aver letto che in Postgresql gli aggiornamenti dello schema possono essere eseguiti in tempo reale senza blocco. Ma non sono sicuro di quanto sia doloroso o pratico in questo caso d'uso. Inoltre, poiché le modifiche allo schema potrebbero introdurre anche modifiche SQL nuove / minori.
  2. Avere un RDBMS, ma progettare lo schema del database in modo flessibile: con un valore di attributo-entità vicino o semplicemente come un archivio di valori-chiave. (Workday, FriendFeed per esempio)
  3. Conserva l'intero oggetto in memoria come oggetti e memorizzalo periodicamente nei file di registro (ad esempio, edval, lmax)
  4. Scegli un DB NoSQL come MongoDB o Redis. Ma in base a ciò che posso raccogliere, non sono adatti per questo caso d'uso e non sono pienamente conformi all'ACID.
  5. Scegli alcuni Dbs NewSQL come VoltDb o JustoneDb (basati su cloud) che mantengono il comportamento conforme a SQL e ACID e sono RDBMS "di nuova generazione".
  6. Ho guardato neo4j (graphdb), ma non sono sicuro che si adatterà a questo caso d'uso

Nel mio caso d'uso, più che scalabilità o calcolo distribuito, sto cercando un modo migliore per ottenere "Flessibilità nello schema + ACID + alcune prestazioni ragionevoli". La maggior parte degli articoli che ho trovato in rete parlano di flessibilità nello schema come causa che porta alle prestazioni (nel caso dei DB NoSQL) e alla scalabilità, lasciando fuori il lato ACID / Transazioni.

È un caso "uno o" delle transazioni "Flessibilità dello schema rispetto all'ACID" o Esiste una via d'uscita migliore?


2
Dai un'occhiata al modulo hstore in PostgreSQL. Questo è "NoSQL" all'interno di un database SQL: postgresql.org/docs/current/static/hstore.html
a_horse_with_no_name

@horse: grazie ... è un buon indicatore. Ho sentito i plugin NoSQL per MySQL. Stavo guardando simile per Postgres.
martedì

Risposte:


11

opzione 1

Ci sono diverse ragioni per questo, che spiegherò di seguito. Innanzitutto, ecco come farlo.

  • Usa la tua scelta di piattaforma RDBMS standard.

  • Imposta lo schema con diversi campi configurabili dall'utente e fai in modo che la tua applicazione faciliti la configurazione in base al tenant.

  • Dai metadati per tenant, è possibile creare una vista per tenant dei loro dati, che ha i filtri integrati e le colonne denominate dai metadati. Qualsiasi report fornito può anche ereditare i metadati. Se vogliono fare il MI fuori dai dati, fornisci loro un estratto dei dati transazionali, o forse qualche altra applicazione MIS su un server diverso se pagheranno per quello.

  • Non provare a fornire una personalizzazione maggiore di questa (cioè nessuna modifica radicale allo schema) a meno che il client non sia disposto a pagare per la propria istanza privata e a mantenere una build personalizzata.

Le ragioni dietro questo sono:

  • Questi sistemi di database gestiranno il tipo di volumi che descrivi su hardware abbastanza ordinario. Non hai davvero il tipo di volume di transazione che merita un database NoSQL. A meno che tu non abbia qualche altro motivo architettonico per volerne uno, non ha molto senso andare al limite.

  • Sono tecnologie mature e ben comprese.

  • Gestione del sistema, backup / ripristino, replica, reportistica e disaster recovery sono tutti ben ordinati su piattaforme RDBMS.

  • È possibile ottenere librerie client incluso JDBC per tutte le principali piattaforme RDBMS.

  • Le viste possono essere utilizzate per la personalizzazione per utente e generate dai metadati dell'applicazione.

  • È sostanzialmente più efficiente dei campi XML o delle strutture EAV.


@COTW: grazie per la risposta dettagliata. Una cosa importante di cui mi sono preoccupato è stata la "anticipata" modifica dello schema, che credo dovrei riflettere e renderlo il più "preconfigurabile" possibile in anticipo ed evitare drastiche modifiche dello schema in seguito.
martedì

Il ripristino di emergenza per un singolo tenant non è semplice se condividono tabelle. (Se ogni riga ha un numero ID inquilino.)
Mike Sherrill 'Cat Recall',

Fallo, ma usa una colonna JSON: gist.github.com/tobyhede/2715918
mwhite

5

Con PostgreSQL hai la possibilità di utilizzare database separati, schemi separati o viste per gestire la multi-tenancy.

L'uso di più database (all'interno dello stesso server di database) rende l'amministrazione più complessa perché ogni database deve essere gestito individualmente. Pertanto, questo è consigliabile solo se la sicurezza tra gli inquilini è la massima preoccupazione.

Schemi separati offrono molta flessibilità e sicurezza, ma rendono gli aggiornamenti più complessi perché devono essere applicati singolarmente ed è probabilmente necessario solo se i tenant utilizzano strutture di tabella completamente diverse; che è improbabile se stanno usando la stessa applicazione.

Le viste consentono ai tenant di vedere parti diverse di una struttura di tabella comune e di controllare a quali tabelle, a quali colonne e a quali file hanno accesso. L'unica avvertenza è che l'applicazione deve garantire che utilizzi solo quelle viste e non le tabelle di base, altrimenti potrebbero verificarsi perdite accidentali di dati tra i tenant a causa di difetti del software.

Non è necessario creare colonne prima dei requisiti dell'applicazione. Le colonne possono essere aggiunte alle tabelle in modo dinamico (senza alcun impatto evidente sugli utenti) e anche le viste possono essere aggiornate in modo dinamico. Devi solo pensare all'ordine di apportare modifiche, ad es. cambia tabelle, quindi visualizza quindi il codice dell'applicazione.

La tua unica potenziale preoccupazione è se devi aggiungere una nuova colonna che deve essere aggiunta a un indice esistente o richiede un nuovo indice. Questo è quando la tabella può essere bloccata dall'uso durante la creazione dell'indice, ma PostgreSQL supporta la possibilità di creare indici contemporaneamente senza bloccare la tabella. Funziona bene a meno che il nuovo indice non sia univoco e rilevi una violazione dell'unicità.

Probabilmente non è necessario un database NoSQL poiché rimuovono efficacemente lo schema dal database e richiedono invece l'applicazione per gestirlo. Non sembra che i tuoi volumi richiedano quel tipo di sacrificio.


1
Con 9.1 puoi persino sostituire un vincolo univoco o chiave primaria senza bloccare la tabella. Vedi qui: depesz.com/index.php/2011/02/19/…
a_horse_with_no_name

Concordato. Stavo tentando di dire che si crea un problema quando viene creato un indice univoco ma viene violato il vincolo, quindi è necessario risolvere il problema dell'unicità. Questo è più un problema di aggiungere colonne piuttosto che aggiungere indici di per sé.
Duncan Pauly,

@DuncanPauly: grazie per la comprensione. Capisco dalla tua risposta che Postgresql consente il "cambio di schema online / live". Ma, quando utilizzo Google, ottengo principalmente "cambio di schema online di Facebook" o "pt-online ..." ecc., Che riguardano MySQL. Saresti a conoscenza di un link o materiale che mi aiuti a capire la modifica dello schema live per Postgresql? Apprezzo il tuo aiuto. Grazie.
tmbsundar,

Questo link descrive come modificare le tabelle postgresql.org/docs/8.1/static/ddl-alter.html . Il principio importante da ricordare è che la creazione, l'alterazione e l'eliminazione di tabelle o viste è praticamente istantanea; mentre la creazione e la modifica di indici è tutt'altro che.
Duncan Pauly,
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.