Il livello di accesso ai dati dovrebbe rispecchiare la configurazione del mio database?

2

Sto cercando di decidere come (o se) il mio Data Access Layer dovrebbe occuparsi delle protezioni di sicurezza e integrità esistenti sul database. L'architetto in me dice che separation of concerns è una priorità e la duplicazione dei compiti è dispendiosa quindi dovrei lasciare il database per gestire il controllo degli accessi e lasciare che il Object Relational Mapping sia un mediocre idiota tra business logic e persistence strati. Ma il DBA in me non apprezza l'idea di creare modelli che consentano ad altri sviluppatori di tentare di gestire i dati sottostanti in modi che non dovrebbero (come definito da vincoli, relazioni e sicurezza dell'account sul database).

Quanto "intelligente" dovrebbe essere il mio DAL? Il mio DAL dovrebbe tenere conto dei privilegi di accesso (come chi può leggere / scrivere) per creare una versione accessibile orientata agli oggetti del mio livello di persistenza? O dovrebbe essere un vero pass-through e dovrei aspettarmi che il mio livello aziendale rispetti la sicurezza a cui potrebbe non avere visibilità immediata? Più probabilmente qualcosa in mezzo?

In altre parole ... se ho un account di database che fornisce solo SELECT (sola lettura) diritti alla tabella MYTABLE , se l'oggetto Data Access Layer per MYTABLE riflette queste autorizzazioni in quali metodi sono permesso di essere chiamato contro questo modello? Che dire quando ho una singola entità a cui si può accedere in modi diversi a seconda di quale account (o servizio) lo sta colpendo? Devo avere più modelli degli stessi dati sottostanti?

Se non riesci a capire dal mio testo sopra, preferirei avere un DAL più intelligente che assicuri che i miei controlli del database siano almeno in qualche modo rispettati (senza la necessità di lanciare un sacco di errori di runtime). Ma non so dove tracciare la linea tra "business logic" e "data access logic" e odio l'idea di duplicare il lavoro.

    
posta DanK 08.08.2016 - 16:03
fonte

3 risposte

1

Questa domanda sembra riguardare la tua domanda in quanto richiede qualcosa che sembra implicito: dovresti creare un utente di database per ogni utente che accede all'applicazione. E la mia risposta sarebbe un NO senza riserve!

Per quanto riguarda le chiavi primarie e le chiavi esterne, ti consiglio caldamente di implementarle entrambe nel tuo database, escludendo che questo debba ricadere sul tuo livello di accesso ai dati.

Un anti-pattern che ho visto (e che è stato documentato da molti altri ) è l'Anemico Modello. Dove i mapping degli oggetti al DB sono poco più di oggetti di trasferimento dati (setter e getter) che saranno gestiti da altri elementi nell'applicazione.

Hibernate è un O / RM piuttosto potente perché va oltre la semplice mappatura dal database agli oggetti ma fornisce vera ignoranza della persistenza consentendo ai tuoi modelli di oggetti di essere molto più espressivi della logica di business.

Ad esempio invece di avere qualche operazione che richiede un Cliente e inserisce un oggetto Ordine usando l'ID cliente, avresti un'operazione di createOrder sul cliente che aggiunge un nuovo ordine nell'attributo Customer.orders e lo restituisce in modo che tu possa puoi aggiungere elementi pubblicitari ad esso prima di chiamare finalmente salvare nel contesto e tutto va al database in un colpo solo.

Leggi informazioni su Domain-Driven Design per vedere come creare un livello di dati più espressivo che non si limiti a spostare le informazioni avanti e indietro dal database.

    
risposta data 08.08.2016 - 22:06
fonte
2

Un RDBMS è un ottimo software che fa molte cose oltre a mettere i dati nei file di dati.

Non enumererò qui le funzioni di un RDBMS, ma potresti indovinare che avresti bisogno di scrivere tomi di codice solo per emulare una piccola parte di ciò che può fare.

It's no longer one-app<->one-database world.

Diverse app possono accedere allo stesso database e una singola app può accedere a diversi database. Quindi, cercando di applicare tutta l'integrità referenziale e le autorizzazioni in "l'app" mi fa chiedere a "quale app ?, quella Android ?, l'iPhone ?, quella Web ?, quella desktop ?, ecc. ". Ci sono molti modi in cui un utente del database può accedere a un database. "L'app " è solo uno di questi.

L'RDBMS dovrebbe implementare l'integrità referenziale, controllare l'accesso agli oggetti, ecc. Se vuoi fare lo stesso in "l'app" , bene, perché salvi un viaggio nel database ma io consiglia di farlo in modo efficace e non di regola.

Il DAL dovrebbe catturare le eccezioni e agire di conseguenza.

E altra cosa: come pensi di mantenere il tuo DAL in sincrono con le autorizzazioni del database?

Nei database, gli utenti vengono creati continuamente e le autorizzazioni vengono concesse e revocate in continuazione, in che modo il DAL genererà il codice per riflettere questo?

Un DBA junior temporaneo potrebbe aiutare. La manutenzione di un codebase è costosa. Più codice è orientato al livello aziendale o orientato all'utente finale, meglio è. Investire tempo di programmazione in attività banali come assicurarsi che nessun duplicato sia inserito in tabelle PK-less o una riga non correlata inserita in una tabella FK-less è una perdita di tempo per lo sviluppatore. Il tempo del programmatore è costoso.

    
risposta data 08.08.2016 - 18:40
fonte
1

Se vedi un oggetto DAL come proxy per un oggetto persistente, dovrebbe offrire la stessa funzionalità.

D'altro canto, la funzionalità che il tuo oggetto db offre potrebbe essere dipendente dall'utente (autorizzazione), quindi scoprire solo all'esecuzione del comando che fallisce. Quindi sembra un limite ragionevole. Ed emulare il db nel tuo DAL per anticipare potenziali errori non solo sarebbe un lavoro ridondante ambizioso, contro la separazione delle preoccupazioni, ma è destinato a fallire: non puoi impedire all'utente concurent di bloccare i dati, né anticipare tutta l'integrità referenziale e db -triggers che il dba potrebbe aggiungere nel tempo. E cosa succederebbe se passassi a un db con un diverso schema di autorizzazione (es. Oracle a mongodb o aerospike)?

Parlando di separazione delle preoccupazioni, se capisco la tua affermazione, non vuoi replicare la logica db ma solo impedire a un utente di eseguire operazioni che non dovrebbe fare. Questa è davvero una responsabilità DAL? Le autorizzazioni e i ruoli degli utenti non sono una questione di logica aziendale e le autorizzazioni db sono solo un modo per implementarla? Suggerirei quindi di riconsiderare la tua architettura:

  • avere qualche oggetto business per rappresentare le autorizzazioni aziendali (e portarle in accout nella tua interfaccia utente) e, se necessario, nel tuo DAL prevedere un modo per istanziare gli oggetti di autorizzazione aziendale dalle autorizzazioni db (e solo se questo è davvero il tuo modo gestirò le autorizzazioni aziendali)
  • verifica se il livello di tabella / livello di visualizzazione o persino il livello di accesso alla gestione delle query è davvero il livello di astrazione corretto per il DAL
risposta data 08.08.2016 - 19:21
fonte