Separazione logica del contenuto del database

2

Sfondo

Ho un'applicazione che memorizza molte entità in un database relazionale classico (Microsoft SQL Server) e utilizzo un ORM (Entity Framework) per interrogare i dati da esso. Questo database ha uno schema non esiste solo una "vista globale" per questi dati. I dati sono resi disponibili agli utenti tramite un'API OData.

Per semplicità diciamo che è un sistema di blog con le tabelle Posts , Comments , Tags , Users . La relazione esatta tra loro non è così importante per ora.

Domanda

Con la prossima versione dell'applicazione vorremmo gestire più blog all'interno di un'installazione software. Tutti i blog con i loro contenuti sono indipendenti gli uni dagli altri e gestiti da utenti diversi.

Come si può eseguire una tale estensione del software?

La soluzione più ovvia al problema mi sembra rendere la parte di separazione del modello di dati. Ciò richiederebbe di introdurre un'entità contenitore e lasciare che tutte le altre entità puntino tramite FK al contenitore a cui appartengono. Quindi nell'applicazione tutte le query devono essere estese da un filtro per caricare solo i dati per il contenitore corrente .

Come puoi immaginare, questo richiede un grande sforzo di sviluppo. Ogni query deve specificare correttamente questo filtro e, in caso contrario, potrebbero essere visualizzati dati provenienti da blog errati. Anche i vincoli univoci devono essere rielaborati per essere unici per contenitore.

Un'altra idea era di creare anche 1 database per container e connettersi al DB corrispondente a seconda del contenitore a cui si accede. Anche l'impegno di manutenzione dietro a questo mi sembra un po 'complesso.

Ci sono forse altre soluzioni tecniche a questa domanda?

Purtroppo mi mancano i termini corretti per fare una ricerca adeguata su questo argomento. La cosa migliore che posso sperare è una funzionalità di SQL Server che consente di archiviare più "set" di dati nello stesso schema di database con una separazione rigorosa.

    
posta Danielku15 06.08.2018 - 11:33
fonte

3 risposte

2

Hai inchiodato le due scelte ovvie. Ma nessuno dei due è abbastanza duro come dici tu, e ciò ha più senso in base a quanto ti aspetti di integrare il contenuto di un blog in un altro.

Approccio database separato :

Questo è l'approccio più semplice da implementare. Hai già una stringa di connessione per la connessione al tuo database. Basta avvolgerlo dietro una funzione, che accetta una sorta di oggetto 'Request' come argomento. Può quindi solo restituire la stringa di connessione al database corretta. Facile e molto modulare. In sostanza nulla cambia nella tua applicazione.

L'unico svantaggio di questo approccio è che se vuoi analizzare tutti i blog (ad esempio quale Blog è il più attivo, quale blog usa la parola 'scoreggia' più spesso, ecc.), questo non funzionerà bene con questo approccio.

Nell'ambito di un approccio al database :

Ciò richiede un campo extra "blog" in tutte le tue tabelle di livello superiore (forse tutte le tabelle). Ovunque si raccolgano dati senza prima accedere a un altro tavolo (se si sta già entrando in un tavolo con il blogid, probabilmente non è necessario aggiungere il blogid alla nuova tabella, come forse la tabella degli utenti? Ciò dipende dalla semantica che si desidera anche ).

E sì, questo richiede una piccola modifica alle query di livello più alto - dicendo dove blogID = blogIDImWorkingOn. Ma rende più facile - roba dopo - quando vuoi integrare / analizzare i contenuti sui blog.

Spero che questo aiuti! Buona fortuna!

    
risposta data 06.08.2018 - 22:16
fonte
5

Anche se non sono un architetto esperto, ma poiché la domanda sta in piedi, potresti non voler cambiare molto.

Devi solo aggiungere una tabella Blogs e una colonna "blog_id" ai post (proprio come il tuo "commento" probabilmente ha già una colonna "post_id"). Bene, a seconda delle entità che desideri separare, potresti apportare altre modifiche, ad esempio, dici di voler separare gli utenti, ma dal momento che non fornisci molti dettagli, è giusto presumere che non sia necessaria molta complessità . Forse gli utenti condivisi tra i blog sarebbero una caratteristica.

A seconda delle dimensioni del progetto, potrebbe non essere troppo efficiente, ma ancora una volta, se non si prevedono problemi, non c'è motivo di sovradimensionare il sistema

    
risposta data 06.08.2018 - 14:24
fonte
1

Abbiamo risolto questo problema utilizzando un database per cliente e disponendo di un singolo database di configurazione che mappa quale sottodominio / cliente si connette a quale database. Semplicemente memorizzando connectiontring, sottodominio clienti e altre metainformazioni in questo database di configurazione. Simile a quello che proponi come seconda soluzione.

Richiede alcune impostazioni per cliente, ma non penso che sia evitabile, non importa come la si implementa. Utilizziamo l'injection dependency e ci connettiamo al database corretto durante l'inizializzazione del contenitore. Questo viene fatto su base per richiesta.

Questa non è una buona risposta, ma funziona per noi, quindi probabilmente lo farà per te. Non ho idea se ci sono modi migliori per farlo comunque.

risposta data 06.08.2018 - 13:55
fonte

Leggi altre domande sui tag