Che cosa significa Robert C. Martin per SQL non è necessario? [chiuso]

45

Ho letto / guardato un sacco di contenuti di Robert C. Martin. Mi sono imbattuto in lui dicendo che SQL non è necessario a causa delle unità a stato solido. Quando cerco altre fonti per eseguire il backup di questo, ottengo un sacco di articoli casuali che descrivono la differenza delle prestazioni SQL tra dischi rigidi e unità a stato solido (che è correlato ma non quello che sto cercando di ricercare).

In definitiva, non capisco cosa stia cercando di ottenere. Sta dicendo di sostituire SQL con le tecnologie No-SQL? Sta dicendo di memorizzare i dati in file in un file system? O vuole solo che le persone smettano di usare database SQL / relazionali a causa di attacchi SQLi? Temo di perdere il punto che sta cercando di fare.

Fornirò alcuni link qui in modo da poter leggere direttamente dalla sua mente:

  1. Bobby Tables
  2. Lettura di architettura pulita

In primo luogo, afferma che SQL dovrebbe essere rimosso completamente dal sistema.

The solution. The only solution. Is to eliminate SQL from the system entirely. If there is no SQL engine, then there can be no SQLi attacks.

E anche se parla di sostituire SQL con un'API, NON penso che significhi mettere SQL dietro un'API a causa di quella citazione precedente e di quello che ha detto prima nell'articolo.

Frameworks don’t handle the issue;...

Nota a margine: nel dire SQL, sono abbastanza sicuro che Robert significhi la maggior parte dei database relazionali. Forse non tutti, ma la maggior parte. In ogni caso, la maggior parte delle persone usa comunque SQL. così ...

Se SQL non viene utilizzato per mantenere i dati, allora cosa dovremmo usare?

Prima di rispondere, dovrei anche notare. Robert sottolinea che le unità a stato solido dovrebbero cambiare gli strumenti che usiamo per mantenere i dati. La risposta di Søren D. Ptæus indica ciò.

Devo anche rispondere al gruppo ", ma integrità dei dati". In seguito a ulteriori ricerche, Robert afferma che dovremmo utilizzare database transazionali come datomic . Quindi CRUD si trasforma in CR (create and read) e le transazioni SQL vanno via del tutto. L'integrità dei dati è ovviamente importante.

Non riesco a trovare una domanda che comprenda tutto questo. Immagino di essere alla ricerca di alternative che corrispondano alle linee guida di Robert. Datomic è uno ma è così? Quali altre opzioni corrispondono a queste linee guida? E funzionano davvero meglio con le unità a stato solido?

    
posta christo8989 26.02.2018 - 02:41
fonte

11 risposte

74

Bob Martin sta chiaramente esagerando per rendere più chiaro il suo punto. Ma qual è il suo punto?

Does he just want people to stop using SQL/Relational Databases because of SQLi attacks?

A quanto mi risulta, in quel post del blog (il tuo primo link) Martin cerca di convincere le persone a smettere di usare SQL, ma non i database relazionali. Questi sono due cose diverse .

SQL è un linguaggio estremamente potente, ed è standardizzato in una certa misura. Permette di creare query e comandi complessi in modo molto compatto, in modo leggibile, comprensibile, facile da apprendere. Non dipende da un altro linguaggio di programmazione, quindi è utilizzabile per la maggior parte dei programmatori di applicazioni, indipendentemente dal fatto che preferiscano Java, C, C ++, C #, Python, Ruby, JavaScript, Basic, Go, Perl, PHP o qualcos'altro. / p>

Tuttavia, questo potere ha un costo : scrivere query / comandi SQL sicuri è più difficile che scrivere quelli non sicuri. Un'API sicura dovrebbe facilitare la creazione di query sicure "per impostazione predefinita". Quelli potenzialmente pericolosi dovrebbero necessitare di uno sforzo mentale maggiore o almeno maggiore. Questo è IMHO perché Martin sta battendo contro SQL nella sua forma attuale.

Il problema non è nuovo e ci sono API più sicure di SQL standard per accedere a un database relazionale. Ad esempio, tutti i mappatori OR che conosco stanno cercando di fornire una tale API (sebbene siano in genere progettati per altri obiettivi primari). Le varianti SQL statiche rendono difficile la creazione di query dinamiche con dati di input non criticati (e non è una nuova invenzione: SQL incorporato, che utilizza SQL spesso statico, ha circa 30 anni).

Purtroppo, non sono a conoscenza di alcuna API che sia flessibile, standardizzata, matura, indipendente dalla lingua e potente come SQL, in particolare SQL dinamico. Ecco perché ho qualche dubbio sul suggerimento di Martin di "non usare SQL" come un modo realistico per risolvere i problemi citati. Quindi leggi il suo articolo come un pensiero nella giusta direzione, non come una "pratica migliore" che puoi seguire ciecamente da domani.

    
risposta data 26.02.2018 - 11:26
fonte
57

L'opinione di Bob Martin è proprio questa; l'opinione di un uomo.

Ci si aspetta che un programmatore comprenda il sistema che sta scrivendo abbastanza bene da esercitare una ragionevole attenzione sulla sua sicurezza e prestazioni. Ciò significa che, se stai parlando con un database SQL, fai ciò che Bobby Tables sito web dice di fare: tu disinfetti i tuoi dati di input. Significa che metti la tua Database SQL su una macchina che promette prestazioni adeguate. Ci sono modi ben noti e ben compresi per fare queste cose, e mentre non garantiscono la sicurezza assoluta o le prestazioni ideali, non fa altro.

L'asserzione che non abbiamo più bisogno di SQL perché ora abbiamo SSD è solo speciosa. SQL non è stato inventato perché i dischi rigidi ad alta velocità non esistevano ancora; è stato inventato perché avevamo bisogno di un modo standard del settore per esprimere concetti di recupero dei dati. I sistemi di database relazionali hanno molte altre qualità oltre alla velocità e alla sicurezza che li rendono ideali per le operazioni aziendali; in particolare, ACID . L'integrità dei dati è importante almeno quanto la velocità o la sicurezza e, se non la possiedi, qual è il motivo per proteggere i dati cattivi o recuperarli il più rapidamente possibile?

Prima di prendere l'isterismo di un uomo come vangelo, ti suggerisco di conoscere la sicurezza e le prestazioni delle applicazioni e del sistema alle loro condizioni, non leggendo articoli casuali su Internet. C'è molto di più nella sicurezza, nelle prestazioni e nella progettazione di un sistema robusto rispetto al semplice "evitare questa tecnologia".

Non vietiamo i coltelli da cucina perché alcuni individui sfortunati riescono a tagliarsi accidentalmente le dita con loro.

    
risposta data 26.02.2018 - 06:51
fonte
15

Cosa sta dicendo in realtà?

Is he saying replace SQL with No-SQL technologies?

TL; DR: Sì (sorta di)

In un discorso più recente di quello a cui ti sei collegato sostanzialmente sullo stesso argomento, egli dice: " Il database è un dettaglio. Perché disponiamo di database? ".

Egli afferma che il database è stato creato per facilitare l'accesso ai dati dai dischi rotanti, ma in futuro " [...] non ci saranno i dischi " grazie alla nuova tecnologia e ciò che lui chiama" RAM persistente "e che sarà più facile memorizzare i dati usando le strutture che i programmatori usano, come come hashtables o alberi.

Prosegue predicendo che i database relazionali nel complesso scompariranno in gran parte a causa della loro nuova competizione:

If I were Oracle, I would be pretty scared because the reason for my existence is evaporating from underneath me.[...] The reason for the database to exist is disappearing.

There will probably be some relational tables that survive, but now there is some healthy competition.

Quindi no, per lui non si tratta solo di SQL injection, anche se opina SQL è intrinsecamente imperfetto in questo senso .

Nota dell'autore:

Le dichiarazioni in questo post sono solo citazioni per comprendere la visione di Robert C. Martin su questo argomento e non rappresentano l'opinione dell'autore. Per un punto di vista più differenziato, vedi la risposta di Robert Harvey .

    
risposta data 26.02.2018 - 13:56
fonte
11

SQL è un dettaglio. La conoscenza di un dettaglio non dovrebbe diffondersi.

Poiché SQL viene utilizzato in un numero sempre maggiore di punti del codice, il codice diventa sempre più dipendente da esso.

Man mano che impari sempre più trucchi SQL, risolvi sempre più problemi usando SQL. Ciò significa che il passaggio a un'altra API per persistere implica più di una semplice traduzione. Devi risolvere i problemi che non ti rendevi conto di avere.

Ci si imbatte anche in questo passaggio tra i database. Uno offre funzionalità di whizzbang fantasioso 5 in modo che tu lo usi in un numero di posti solo per scoprire il whizzbang di fantasia 5 è proprietario e ora hai un problema di licenza che ti costerà un sacco di soldi. Quindi fai un sacco di lavoro scavando ovunque tu abbia usato la funzionalità 5 e risolvendo il problema da solo solo per scoprire in seguito che stai usando anche la funzione whizzbang 3.

Una delle cose che rende così portatile Java è che alcune funzionalità della CPU non sono disponibili. Se fossero disponibili li userei. E improvvisamente ci sono CPU in cui il mio codice Java non funzionerà perché non hanno queste caratteristiche. È lo stesso con le funzionalità del database.

È facile sacrificare la tua indipendenza senza rendersene conto. SQL è una scelta, non un dato. Se decidi di usare SQL, fallo in un posto. Fallo in un modo che non può essere rimosso.

Il fatto che SQL abbia problemi di sicurezza e che stiamo passando a modelli di memoria persistenti non significa che SQL sia destinato a fallire. Porta semplicemente a casa il punto che è una scelta. Se vuoi preservare il diritto di fare quella scelta devi fare il lavoro.

Può valere la pena notare che il movimento del database degli anni '80 e lo zio Bob hanno una storia piuttosto spiacevole. Ha avuto tutti i suoi problemi risolti con un file system flat quando la gestione ha forzato un amministratore del database nella sua vita. Questo evento lo ha spinto nella sua carriera di consulenza stellare. (Racconta questa storia in uno dei suoi primi libri puliti, dimentica quale) Sa come risolvere i problemi senza DB e ha poca pazienza per quelli che si comportano come usarli è un dato di fatto.

Racconta anche una storia su come rimandare l'aggiunta di un DB a un'applicazione fino all'ultimo minuto quando un cliente lo richiedeva e lo aggiungeva in un giorno come funzione opzionale. La mia ipotesi è che vede come la maggior parte di noi usa DB come una dipendenza. Sta cercando di mostrarci come prendere l'abitudine.

    
risposta data 26.02.2018 - 15:36
fonte
5

La citazione della tua prima citazione è (sottolineatura mia),

The solution. The only solution. Is to eliminate SQL from the system entirely. If there is no SQL engine, then there can be no SQLi attacks.

What would replace SQL? An API of course! And NOT an API that uses a textual language. Instead, an API that uses an appropriate set of data structures and function calls to access the necessary data.

Il rant è contrario a consentire ai programmatori di applicazioni di utilizzare SQL.

La soluzione suggerita è di consentire loro di utilizzare invece un'API: che non è SQL e non consente l'iniezione.

IMO, esempi di tali API potrebbero includere:

  • Il

    link suggerisce che i programmatori C # possono utilizzare l'API ADO.NET.

    Questo non è un esempio perfetto perché ADO.NET è un'API ampia o profonda (cioè potente o generica), che anche consente ai suoi utenti di immettere SQL raw (o raw-ish).

  • Alcuni sviluppatori SQL o amministratori di database suggeriscono che un database deve essere configurato in modo tale da consentire l'accesso solo tramite (un numero limitato di parole scritte in modo esperto) stored procedure , e gli sviluppatori di applicazioni non dovrebbero essere autorizzati a scrivere le proprie (pericolose) query SQL

  • Un altro modo per "eliminare SQL dal sistema" consiste nel mettere il database (che espone SQL) su qualche altro sistema, accessibile tramite un'API REST o simile.

Quindi, IMO, la soluzione o il sistema generale può ancora utilizzare un database (specialmente dato che un motore di database implementa proprietà ACID utili e scala bene e così via, può essere sciocco provare a fare a meno di uno, o per scrivere uno specifico per l'applicazione).

I requisiti del rant sono soddisfatti se l'API SQL del database è nascosta agli sviluppatori dell'applicazione, dietro qualche altra API (ad esempio ADO, forse un ORM, un servizio Web o altro).

Più in generale suppongo che significhi avere un DAL specifico per l'applicazione (un "livello di accesso ai dati" o un "livello di astrazione del database"). Un DAL isola l'applicazione dai dettagli di come e dove i dati vengono archiviati e / o recuperati. Il DAL può o non può essere implementato utilizzando un database SQL.

    
risposta data 26.02.2018 - 15:35
fonte
3

Tutti sembrano rispondere a questa domanda da un punto di vista della sicurezza o con un obiettivo SQL.

Ho visto una conferenza di Robert Martin in cui racconta che come programmatori, usiamo molte strutture di dati differenti che sono ottimali per i nostri programmi specifici. Quindi, piuttosto che memorizzare universalmente tutti i dati in una struttura tabulare, dovremmo archiviare i nostri dati in tabelle hash, alberi, ecc. Così possiamo prendere i dati e passare direttamente al programma.

Ho interpretato il suo messaggio come solo dicendo che dovremmo buttare via le nostre attuali ipotesi sullo storage persistente per un momento per considerare altre possibilità future rispetto al vecchio formato tabulare SQL. SSD è una soluzione candidata, ma non l'unica.

    
risposta data 26.02.2018 - 19:37
fonte
2

In realtà, non deve utilizzare database e SQL, in modo abbastanza esplicito. Il primo riferimento è un problema ben noto, il secondo riferimento si presenta come un rant. Anche se, sto interpretando come avere una buona ragione per utilizzare i database e non utilizzare SQL. Dal mio punto di vista questo non è nemmeno un consiglio ragionevole.

Sfortunatamente, l'esempio che sta usando è un esempio ben noto con una soluzione ben nota che egli sottolinea poi. Di solito accade quando un programmatore non si rende conto di quello che sta facendo. Ad esempio, la costruzione di stringhe contenenti SQL come:

    my $sql="select a from b where a=$ui_val;";
    prepare($sql)
    execute($sql)

al contrario di

    my $sql="select a from b where a=?;";
    prepare($sql)
    execute($sql,$ui_val);

Questo è un esempio di DBI perl per il codice ruby on rails. Il codice di rotaie che fornisce è facile da confondere tra il sicuro e il non sicuro. Come molti ORM nasconde ciò che l'SQL è sotto e così spesso hai a che fare con un'interfaccia che costruisce ed esegue lo sql per te. Non sembra quasi quello che un'API potrebbe fare per te?

La mia interpretazione del primo riferimento è che suggerisce che dovremmo sostituire un problema ben noto che ha una soluzione ben nota.

È anche un peccato che lui non menzioni che se questo è fatto correttamente renderà il codice più facile da scrivere e più leggibile, anche se se fatto bene, potrebbe essere più difficile da scrivere e meno leggibile. Inoltre, non menziona che SQL sia davvero molto facile da leggere e fa quello che generalmente ti aspetteresti che faccia.

È parzialmente corretto, alla fine avremo una memoria infinitamente grande e veloce e un processore infinitamente veloce. Fino a quando non scivoliamo fuori dalla fisica corrente che limita il calcolo, non è corretto.

Sì, i dischi rotanti appartengono al passato e ora utilizziamo gli SSD. I dischi funzionano con circa ~ 10 millisecondi per trasferimento di dati, gli SSD funzionano con un tempo di accesso ai dati di ~ 0,5 millisecondi (500 microsecondi). La RAM è nell'ordine di 100 nano secondi, i processori operano nell'ordine dei 100 secondi di pico secondi. Questo è il cuore del perché abbiamo bisogno di database. I database gestiscono il trasferimento dei dati tra dischi rotanti o SSD con memoria principale. L'avvento degli SSD non ha eliminato la necessità di database.

    
risposta data 26.02.2018 - 13:32
fonte
2

risposta

does he just want people to stop using SQL/Relational Databases because of SQLi attacks?

L'articolo "Bobby Tables" sembra suggerire che questo, di per sé è un motivo per non usare SQL:

The solution. The only solution. Is to eliminate SQL from the system entirely. If there is no SQL engine, then there can be no SQLi attacks.

Potrebbe avere altre ragioni che discute altrove. Non lo saprei perché non leggo molto della sua roba.

Digressione

Questa parte non è davvero una risposta, ma penso che la questione del valore di SQL sia molto più interessante (come fanno gli altri, apparentemente).

Ho avuto molta esperienza nell'uso di SQL e penso di avere una buona comprensione dei suoi punti di forza e di debolezza. La mia sensazione personale è che è stata abusata e abusata, ma che l'idea che non dovremmo mai usarla è una specie di sciocco. L'idea che dobbiamo scegliere "SQL always" o "SQL never" è una falsa dicotomia.

Per quanto SQL injection sia un argomento per non usare SQL, è ridicolo. Questo è un problema ben compreso con una soluzione piuttosto semplice. Il problema con questo argomento è che SQLi non è l'unica vulnerabilità esistente. Se pensi che l'uso delle API di JSON ti renda al sicuro, ti sorprenderà molto.

Penso che ogni sviluppatore dovrebbe guardare questo video intitolato "Friday il 13: Attacking JSON - Alvaro Muñoz & Oleksandr Mirosh - AppSecUSA 2017 "

Se non hai il tempo o la voglia di guardarci attraverso, ecco il succo: molte librerie di deserializzazione JSON hanno vulnerabilità nell'esecuzione di codice in modalità remota. Se stai usando XML, hai ancora più di cui preoccuparti. Bloccare SQL dalla tua architettura non renderà il tuo sistema sicuro.

    
risposta data 26.02.2018 - 16:17
fonte
2

Voglio indirizzare solo una breve frase:

Or does he just want people to stop using SQL/Relational Databases because of SQLi attacks?

No. Questa è una supposizione sbagliata. Non possiamo dire che dobbiamo smettere di usare le auto, perché sono responsabili di persone che muoiono in incidenti stradali. Allo stesso modo, i database SQL / relazionali (o qualsiasi altra cosa in questo contesto, come RDBMS) non sono responsabili del payload SQL dannoso che un utente malintenzionato può eseguire sulla tua applicazione web. Sono sicuro che l'autore non intendeva questo, perché c'è un intero cheat di prevenzione dell'iniezione SQL per questo scopo.

    
risposta data 26.02.2018 - 11:42
fonte
2

Il problema di Martin sembra essere con i programmatori che creano SQL dinamico direttamente dall'input dell'utente, qualcosa di simile (perdonami, sono principalmente un programmatore C e C ++):

sprintf( query, "select foo from bar where %s;", user_input );

che è assolutamente una ricetta per il bruciore di stomaco (da cui la tabella Bobby ). Ogni programmatore che mette un codice come quello in un sistema di produzione merita un paddlin '.

Puoi mitigare (se non eliminare del tutto) il problema usando istruzioni preparate e disinfettando correttamente i tuoi input. Se è possibile nascondere l'SQL dietro un'API in modo tale che i programmatori non stiano costruendo direttamente stringhe di query, tanto meglio (che fa parte di ciò che Martin sostiene).

Ma per eliminare completamente SQL, non penso che sia pratico o desiderabile. I modelli relazionali sono utili , ecco perché esistono in primo luogo e SQL è probabilmente la migliore interfaccia per lavorare con modelli relazionali.

Come sempre, si tratta di utilizzare lo strumento giusto per il lavoro. Se la tua app del carrello non ha bisogno di un modello relazionale completo, allora non utilizzare un modello relazionale (il che significa che non dovrai usare SQL). Per i tempi in cui hai bisogno di un modello relazionale, quasi sicuramente lavorerai con SQL.

    
risposta data 26.02.2018 - 23:37
fonte
1

Le due fonti collegate collegano messaggi diversi:

Il post del blog dice che la logica di accesso ai dati non dovrebbe esistere come testo in fase di esecuzione, per evitare che venga mescolata con input utente non attendibili. Cioè, il post del blog condanna le query di scrittura concatenando le stringhe.

La lezione è diversa. La prima differenza è nel tono: la lezione specula e chiama in questione, ma non condanna. Non dice che i database sono malvagi, ma ci sfida a immaginare la persistenza senza un database. Sostiene che nei trent'anni trascorsi da quando le basi di dati relazionali si sono diffuse, molte cose sono cambiate e ne evidenzia due che potrebbero influenzare la nostra scelta della tecnologia di persistenza:

  • lo spazio di archiviazione è aumentato di un fattore di circa 1 milione - a prezzi comparabili! Di conseguenza, è meno necessario conservare la memoria e, in particolare, non è più necessario cancellarlo. Utilizzando la memoria solo append, il controllo della concorrenza può essere semplificato perché i blocchi di lettura non sono necessari. Questo può ovviare alla necessità di transazioni.
  • i tempi di accesso sono diminuiti, perché la maggior parte dei dataset ora si adattano alla RAM, riducendo in modo significativo la latenza di lettura.

Queste mutate circostanze cambiano la tecnologia di persistenza ottimale? È interessante notare che lo zio Bob non dice - presumibilmente perché ritiene che nessuna risposta sarebbe corretta per tutti i programmi. Ecco perché ci fa attenzione a considerare la nostra scelta della tecnologia di persistenza come un dettaglio piuttosto che custodirlo in tavolette di pietra e trasmetterlo ai sapienti come saggezza ricevuta.

Esistono alternative?

La scrittura della logica di accesso ai dati senza stringhe è interamente possibile. In Java land, è possibile utilizzare QueryDSL , dove le query vengono descritte utilizzando un'API fluente sicura per il tipo generata dallo schema del database. Tale query potrebbe apparire come segue:

JPAQuery<?> query = new JPAQuery<Void>(entityManager);
Customer bob = query.select(customer)
  .from(customer)
  .where(customer.firstName.eq("Bob"))
  .fetchOne();

Come puoi vedere, la logica della query non è espressa come una stringa, separando chiaramente la struttura attendibile della query dai parametri non attendibili (e, naturalmente, QueryDSL non include mai i parametri nel testo della query, ma usa istruzioni preparate per separare la query per i suoi parametri a livello JDBC). Per ottenere l'SQL injection con QueryDSL, dovresti scrivere il tuo parser per analizzare una stringa e tradurla in un albero di sintassi, e anche se lo facessi, probabilmente non aggiungerei il supporto per cose brutte come select ... into file . In breve, QueryDSL rende l'iniezione SQL quasi impossibile e migliora anche la produttività del programmatore e aumenta la sicurezza del refactoring. Prevenire il più grande rischio per la sicurezza delle applicazioni web, che è esistito abbastanza a lungo da generare gags in esecuzione e ha incrementato la produttività degli sviluppatori? Oserei dire che se scrivi ancora le query come stringhe, stai sbagliando.

Per quanto riguarda le alternative ai database relazionali, è curioso sapere che postgres" postgres"> il controllo della concorrenza versione multipla è esattamente quel tipo di struttura dati di sola aggiunta di cui parla Zio Bob, anche se probabilmente stava pensando più a negozi di eventi e il schema di sourcing di eventi in generale, che si adatta anche bene con la nozione di mantenere lo stato corrente nella RAM.

    
risposta data 27.02.2018 - 03:55
fonte