O que Robert C. Martin entende por SQL ser desnecessário? [fechadas]

45

Eu tenho lido / assistido muito conteúdo de Robert C. Martin. Eu já vi ele dizendo que o SQL é desnecessário por causa das unidades de estado sólido. Quando eu busco outras fontes para fazer isso, recebo um monte de artigos aleatórios descrevendo a diferença do desempenho de SQL entre discos rígidos e unidades de estado sólido (o que está relacionado, mas não o que estou tentando pesquisar).

Por fim, não entendo o que ele está tentando entender. Ele está dizendo substituir SQL com tecnologias No-SQL? Ele está dizendo armazenar dados em arquivos em um sistema de arquivos? Ou ele só quer que as pessoas parem de usar SQL / Relational Databases por causa de ataques SQLi? Temo que estou sentindo falta do que ele está tentando fazer.

Eu fornecerei alguns links aqui para que você possa ler diretamente de sua mente:

  1. Tabelas de Bobby
  2. Palestra sobre Arquitetura Limpa

Primeiro, ele afirma que o SQL deve ser removido do sistema inteiramente.

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, embora ele fale sobre a substituição do SQL por uma API, NÃO acho que ele queira colocar o SQL por trás de uma API por causa dessa citação anterior e do que ele diz anteriormente no artigo.

Frameworks don’t handle the issue;...

Nota: Ao dizer SQL, tenho certeza que Robert significa a maioria dos bancos de dados relacionais. Talvez nem todos, mas a maioria. Em qualquer caso, a maioria das pessoas está usando o SQL de qualquer maneira. então ...

Se o SQL não está sendo usado para persistir dados, então o que devemos usar?

Antes de responder isso, eu também devo observar. Robert enfatiza que drives de estado sólido devem mudar as ferramentas que usamos para persistir os dados. A resposta de Søren D. Ptæus aponta isso.

Também devo responder ao grupo "mas integridade de dados". Após algumas pesquisas, Robert diz que devemos usar bancos de dados transacionais como datomic . Então o CRUD se transforma em CR (criar e ler) e as transações SQL desaparecem completamente. A integridade dos dados é obviamente importante.

Não consigo encontrar uma pergunta que englobe tudo isso. Acho que estou procurando alternativas que correspondam às diretrizes de Robert. Datomic é um, mas é isso? Quais outras opções correspondem a essas diretrizes? E eles realmente funcionam melhor com drives de estado sólido?

    
por christo8989 26.02.2018 / 02:41
fonte

11 respostas

74

Bob Martin está claramente exagerando para deixar seu ponto mais claro. Mas qual é o seu ponto?

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

No meu entender, nessa postagem do blog (seu primeiro link), Martin tenta convencer as pessoas a parar de usar SQL, mas não bancos de dados relacionais. Estas são duas coisas diferentes .

O SQL é uma linguagem extremamente poderosa e é padronizada em algum grau. Permite criar consultas e comandos complexos de uma forma muito compacta, de uma forma legível, compreensível e fácil de aprender. Ele não depende de outra linguagem de programação, portanto, é útil para a maioria dos programadores de aplicativos, não importa se eles preferem Java, C, C ++, C #, Python, Ruby, JavaScript, Básico, Go, Perl, PHP ou qualquer outra coisa. / p>

No entanto, esse poder vem por um custo : escrever consultas / comandos SQL seguros é mais difícil do que escrever inseguras. Uma API segura deve facilitar a criação de consultas seguras "por padrão". Pessoas potencialmente inseguras devem precisar de mais esforço mental ou pelo menos mais de digitação. Isso é IMHO porque Martin está reclamando contra o SQL em sua forma atual.

O problema não é novo, e há APIs mais seguras do que o SQL padrão para acessar um banco de dados relacional. Por exemplo, todos os mapeadores OR que conheço estão tentando fornecer uma API desse tipo (embora eles sejam normalmente criados para outras metas principais). As variantes de SQL estática dificultam a criação de consultas dinâmicas com dados de entrada não-digitalizados (e isso não é uma nova invenção: o SQL incorporado, que usa SQL estático frequentemente, tem cerca de 30 anos).

Infelizmente, não conheço nenhuma API tão flexível, padronizada, madura, independente de linguagem e tão poderosa quanto SQL, especialmente a SQL dinâmica. É por isso que tenho algumas dúvidas sobre a sugestão de Martin de "não usar o SQL" como uma maneira realista de resolver os problemas mencionados. Então, leia seu artigo como um pensamento na direção certa, não como uma "melhor prática" que você pode seguir cegamente a partir de amanhã.

    
por 26.02.2018 / 11:26
fonte
57

A opinião de Bob Martin é apenas isso; opinião de um homem.

Espera-se que um programador entenda o sistema que ele está escrevendo bem o suficiente para exercer um cuidado razoável sobre sua segurança e desempenho. Isso significa que, se você está falando com um banco de dados SQL, você faz o que o Bobby Tables site diz para fazer: você limpa seus dados de entrada. Isso significa que você coloca o seu Banco de dados SQL em uma máquina que promete desempenho adequado. Existem maneiras bem conhecidas e bem compreendidas de fazer essas coisas e, embora não garantam segurança absoluta ou desempenho ideal, nenhuma outra coisa faz.

A afirmação de que não precisamos mais de SQL porque agora temos SSDs é apenas ilusória. O SQL não foi inventado porque os discos rígidos de alta velocidade ainda não existiam; foi inventado porque precisávamos de uma maneira padrão da indústria para expressar conceitos de recuperação de dados. Os sistemas de bancos de dados relacionais têm muitas outras qualidades, além de velocidade e segurança, que os tornam ideais para operações de negócios; em particular, ACID . A integridade dos dados é pelo menos tão importante quanto a velocidade ou a segurança, e se você não a possui, então qual é o objetivo de proteger dados ruins ou recuperá-los o mais rápido possível?

Antes de você pegar a histeria de um homem como evangelho, sugiro que você aprenda sobre segurança e desempenho de aplicativos e sistemas em seus próprios termos, e não lendo artigos aleatórios da Internet. Há muito mais para segurança, desempenho e design de sistema robusto do que simplesmente "evitar essa tecnologia".

Não proibimos facas de cozinha porque alguns indivíduos infelizes conseguem acidentalmente cortar os dedos com elas.

    
por 26.02.2018 / 06:51
fonte
15

O que ele está realmente dizendo?

Is he saying replace SQL with No-SQL technologies?

TL; DR: Sim (mais ou menos)

Em uma conversa mais recente do que aquela que você vinculou basicamente no mesmo tópico, ele diz: " O banco de dados é um detalhe. Por que temos bancos de dados? ".

Ele alega que o banco de dados passou a ser o de facilitar o acesso aos dados a partir dos discos giratórios, mas no futuro " [...] não haverá discos " graças à nova tecnologia e ao que ele chama de" RAM persistente "e que será mais fácil armazenar dados usando as estruturas que os programadores usam, como hashtables ou árvores.

Ele prossegue, prevendo que os bancos de dados relacionais de um todo desaparecerão em grande parte devido à nova concorrência:

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.

Então, não, para ele não é apenas sobre injeção de SQL, embora ele opere SQL é inerentemente defeituoso a esse respeito .

Nota do autor:

As declarações neste post são apenas citações para entender a opinião de Robert C. Martin sobre este tópico e não representam a opinião do autor. Para um ponto de vista mais diferenciado, consulte a resposta de Robert Harvey .

    
por 26.02.2018 / 13:56
fonte
11

SQL é um detalhe. O conhecimento de um detalhe não deve se espalhar.

Como o SQL é usado em mais e mais lugares em seu código, seu código se torna mais e mais dependente dele.

À medida que você aprende mais e mais truques SQL, resolve cada vez mais problemas usando o SQL. Isso significa que mudar para outra API para persistir envolve mais do que apenas traduzir. Você tem que resolver problemas que você não sabia que tinha.

Você se depara com isso, mesmo alternando entre bancos de dados. Um deles oferece um recurso sofisticado de whizzbang 5, então você o usa em vários lugares apenas para descobrir que o recurso de whizzbang 5 é proprietário e agora você tem um problema de licenciamento que vai custar muito dinheiro. Então, você faz muito trabalho desenterrando todos os lugares em que usou o recurso 5 e resolvendo o problema sozinho, para descobrir mais tarde que também está usando o recurso 3 do whizzbang.

Uma das coisas que torna o Java tão portátil é que certos recursos da CPU simplesmente não estão disponíveis. Se eles estivessem disponíveis eu os usaria. E, de repente, há CPUs em que meu código Java não funciona porque elas não têm esses recursos. É o mesmo com os recursos do banco de dados.

É fácil sacrificar sua independência sem perceber. SQL é uma escolha não dada. Se você tomar a decisão de usar o SQL, faça-o em um só lugar. Faça isso de uma maneira que pode ser desfeita.

O fato de o SQL ter problemas de segurança e de estarmos migrando para modelos de memória persistentes não significa que o SQL esteja condenado. Isso apenas mostra que é uma escolha. Se você quer preservar o direito de fazer essa escolha, você tem que fazer o trabalho.

Pode ser interessante notar que o movimento do banco de dados dos anos 80 e do Uncle Bob tem uma história bastante desagradável. Ele teve todos os seus problemas resolvidos com um sistema de arquivos simples quando o gerenciamento forçou um administrador de banco de dados em sua vida. Este evento empurrou-o para sua carreira de consultoria estelar. (Ele conta essa história em um de seus primeiros livros limpos, esquece que) Ele sabe como resolver problemas sem o DB e tem pouca paciência para aqueles que agem como se estivessem usando-os como um dado.

Ele também conta uma história sobre adiar o acréscimo de um banco de dados a um aplicativo até o último minuto, quando um cliente exigia, e o adicionou em um dia como um recurso opcional. Meu palpite é que ele vê como a maioria de nós usa o DB como um vício. Ele está tentando nos mostrar como largar o hábito.

    
por 26.02.2018 / 15:36
fonte
5

A citação da sua primeira citação é (ênfase minha)

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.

O discurso é contra permitir que programadores de aplicativos usem SQL.

A correção sugerida é permitir que eles usem uma API: o que não é SQL e não permite injeção.

IMO, exemplos de tais APIs podem incluir:

  • O

    link sugere que os programadores C # usem a API do ADO.NET.

    Esse não é um exemplo perfeito porque o ADO.NET é uma API ampla ou profunda (ou seja, poderosa ou de propósito geral), que também permite que seus usuários insiram SQL bruto (ou raw-ish).

  • Alguns desenvolvedores de SQL ou administradores de banco de dados sugerem que um banco de dados deve ser configurado de modo a permitir acesso somente por meio de (um número limitado de instruções habilitadas) , e que os desenvolvedores de aplicativos não devem ter permissão para escrever suas próprias consultas SQL (perigosas)

  • Outra maneira de "eliminar o SQL do sistema" é colocar o banco de dados (que expõe o SQL) em algum outro outro sistema, acessado por meio de uma API REST ou similar.

Assim, o IMO, a solução ou o sistema geral ainda pode usar um banco de dados (especialmente dado que um mecanismo de banco de dados implementa propriedades ACID úteis e escalas bem e assim por diante, pode ser tolice tentar fazer sem um, ou para escrever um aplicativo específico).

Os requisitos do rant são satisfeitos se a API SQL do banco de dados estiver oculta dos desenvolvedores de aplicativos, por trás de alguma outra API (por exemplo, ADO, talvez um ORM, um serviço da Web ou qualquer outra coisa).

Mais geralmente, suponho que isso signifique ter um DAL específico do aplicativo (uma "camada de acesso a dados" ou "camada de abstração de banco de dados"). Um DAL isola o aplicativo dos detalhes de como e onde os dados são armazenados e / ou buscados. O DAL pode ou não ser implementado usando um banco de dados SQL.

    
por 26.02.2018 / 15:35
fonte
3

Todos parecem estar respondendo a essa pergunta do ponto de vista de segurança ou com uma lente SQL.

Eu assisti a uma palestra de Robert Martin em que ele conta que, como programadores, usamos muitas estruturas de dados diferentes, ideais para nossos programas específicos. Portanto, em vez de armazenar universalmente todos os dados em uma estrutura tabular, devemos armazenar nossos dados em tabelas de hash, árvores etc., para que possamos coletar os dados e ir direto para o programa.

Eu interpretei sua mensagem como dizendo apenas que devemos descartar nossas suposições atuais sobre armazenamento persistente por um momento para considerar outras possibilidades futuras do que o antigo formato tabular de SQL. O SSD é uma solução candidata, mas não a única.

    
por 26.02.2018 / 19:37
fonte
2

Na verdade, ele não deve usar bancos de dados e SQL - de forma bastante explícita. A primeira referência é uma questão bem conhecida, a segunda referência sai soando como um discurso retórico. Embora, eu esteja interpretando como tendo uma boa razão para usar bancos de dados e não usar SQL. Da minha perspectiva, isso nem é aconselhável.

Infelizmente, o exemplo que ele está usando é um exemplo bem conhecido com uma solução bem conhecida que ele aponta. Geralmente acontece quando um programador não percebe o que está fazendo. Por exemplo, construindo strings contendo SQL como:

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

ao contrário de

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

Este é um exemplo DBI perl para o código ruby on rails. O código de trilhos que ele fornece é fácil de confundir entre o seguro e o inseguro. Como muitos ORMs escondem o que o SQL está por baixo e muitas vezes você está lidando com uma interface que constrói e executa o SQL para você. Isso não soa quase como o que uma API faria por você?

Minha interpretação da primeira referência é que ele está sugerindo que devemos substituir um problema bem conhecido que tem uma solução bem conhecida.

Também é lamentável que ele não mencione que, se isso for feito corretamente, tornará o código mais fácil de escrever e mais legível, embora, se for bem feito, seja realmente mais difícil de escrever e menos legível. Além disso, ele não menciona que o SQL é realmente muito fácil de ler e faz o que você geralmente espera que ele faça.

Ele está parcialmente correto, em última análise, teremos uma memória infinitamente grande e rápida e um processador infinitamente rápido. Até sairmos da física atual que limita a computação, ele não está correto.

Sim, o disco giratório é uma coisa do passado e agora usamos SSDs. Os discos funcionam com aproximadamente 10 milissegundos por transferência de dados, os SSDs funcionam com tempo de acesso a dados de aproximadamente 0,5 milissegundos (500 micros). A RAM é da ordem de 100 nano segundos, os processadores operam no intervalo de 100s de pico segundos. Este é o coração do porquê precisamos de bancos de dados. Os bancos de dados gerenciam a transferência de dados entre discos giratórios ou SSDs com memória principal. O advento dos SSDs não eliminou a necessidade de bancos de dados.

    
por 26.02.2018 / 13:32
fonte
2

Resposta

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

O artigo 'Bobby Tables' parece sugerir que isso, e por si só, é uma razão para não usar o 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.

Ele pode ter outras razões que ele discute em outro lugar. Eu não sei porque eu realmente não leio muito do material dele.

Digressão

Esta parte não é realmente uma resposta, mas eu acho que a questão do valor do SQL é muito mais interessante (como os outros, aparentemente).

Eu tive muita experiência usando SQL e acho que tenho uma compreensão justa de seus pontos strongs e fracos. Meu sentimento pessoal é que ele tem sido usado em demasia e abusado, mas a ideia de que nunca devemos usá-lo é meio boba. A ideia de que devemos escolher 'SQL sempre' ou 'SQL nunca' é uma falsa dicotomia.

No que diz respeito à injeção de SQL como argumento para não usar SQL, isso é risível. Este é um problema bem compreendido com uma solução bastante simples. O problema com esse argumento é que o SQLi não é a única vulnerabilidade existente. Se você acha que o uso de APIs JSON torna sua empresa segura, você tem uma grande surpresa.

Acho que todos os desenvolvedores devem assistir a este vídeo intitulado "Sexta-feira dia 13: Atacando JSON - Álvaro Muñoz & Oleksandr Mirosh - AppSecUSA 2017 "

Se você não tiver tempo ou disposição para assisti-lo, aqui está a essência: Muitas bibliotecas de deserialização JSON têm vulnerabilidades de execução remota de código. Se você estiver usando XML, terá ainda mais com o que se preocupar. Banir o SQL da sua arquitetura não tornará seu sistema seguro.

    
por 26.02.2018 / 16:17
fonte
2

Eu quero abordar apenas uma breve declaração:

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

Não. Essa é uma suposição errada. Não podemos dizer que devemos parar de usar carros, porque eles são responsáveis por pessoas que morrem em acidentes de carro. Da mesma forma, os bancos de dados SQL / relacionais (ou qualquer outra coisa neste contexto, como o RDBMS) não são responsáveis pela carga útil do SQL mal-intencionado que um invasor pode executar em seu aplicativo da Web. Tenho certeza de que o autor não quis dizer isso, porque existe uma planilha de prevenção de injeção de SQL para essa finalidade.

    
por 26.02.2018 / 11:42
fonte
2

O problema de Martin parece ser com programadores construindo SQL dinamicamente diretamente da entrada do usuário, algo como (me perdoe, sou principalmente um programador C e C ++):

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

que é absolutamente uma receita para azia (daí a faixa Bobby Tables ). Qualquer programador que coloque código como esse em um sistema de produção merece um paddlin '.

Você pode atenuar (se não eliminar totalmente) o problema usando declarações preparadas e saneando adequadamente suas entradas. Se você puder ocultar o SQL por trás de uma API, de modo que os programadores não estejam construindo diretamente as strings de consulta, tanto melhor (o que é parte do que Martin defende).

Mas, para me livrar completamente do SQL, não acho que seja prático ou desejável. Os modelos relacionais são úteis , é por isso que eles existem em primeiro lugar, e o SQL é provavelmente a melhor interface para trabalhar com modelos relacionais.

Como sempre, é uma questão de usar a ferramenta certa para o trabalho. Se o seu aplicativo de carrinho de compras não precisar de um modelo relacional completo, não use um modelo relacional (o que significa que você não precisará usar o SQL). Para os momentos em que você precisa de um modelo relacional, é quase certo que você estará trabalhando com o SQL.

    
por 26.02.2018 / 23:37
fonte
1

As duas fontes que você vincula transmitem mensagens diferentes:

O post do blog diz que a lógica de acesso a dados não deve existir como texto em tempo de execução, para que não seja misturado com entradas não confiáveis do usuário. Ou seja, o post do blog condena a escrita de consultas pela concatenação de strings.

A palestra é diferente. A primeira diferença está no tom: A palestra especula e põe em causa, mas não condena. Ele não diz que bancos de dados são maus, mas nos desafia a imaginar a persistência sem um banco de dados. Ele argumenta que nos 30 anos desde que os bancos de dados relacionais se tornaram difundidos, muitas coisas mudaram e destaca duas que podem afetar nossa escolha da tecnologia de persistência:

  • o espaço de armazenamento aumentou em um fator de cerca de 1 milhão - a preços comparáveis! Consequentemente, é menos necessário conservar o armazenamento e, em particular, não é mais necessário excluir. Usando o armazenamento somente de anexação, o controle de simultaneidade pode ser simplificado porque os bloqueios de leitura são desnecessários. Isso pode evitar a necessidade de transações.
  • os tempos de acesso caíram, porque a maioria dos conjuntos de dados agora se encaixam na RAM, reduzindo significativamente a latência de leitura.

Essas circunstâncias alteradas alteram a tecnologia de persistência ideal? Curiosamente, o tio Bob não diz - presumivelmente porque ele acha que nenhuma resposta seria correta para todos os programas. É por isso que ele nos adverte a tratar a nossa escolha da tecnologia de persistência como um detalhe, em vez de consagrá-la em tábuas de pedra e transmiti-la como uma sabedoria recebida aos nossos pares.

Existem alternativas?

Escrever lógica de acesso a dados sem strings é totalmente possível. Em Java, você pode usar QueryDSL , onde as consultas são descritas usando uma API fluente e segura para tipos gerada a partir de seu esquema de banco de dados. Essa consulta pode ter a seguinte aparência:

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

Como você pode ver, a lógica da consulta não é expressa como uma String, separando claramente a estrutura confiável da consulta dos parâmetros não confiáveis (e, é claro, o QueryDSL nunca inclui os parâmetros no texto da consulta, mas usa instruções preparadas para separar a consulta para seus parâmetros no nível JDBC). Para conseguir uma injeção SQL com QueryDSL, você teria que escrever seu próprio parser para analisar uma string e traduzi-la em uma árvore de sintaxe, e mesmo se você fizesse isso, provavelmente não iria adicionar suporte para coisas desagradáveis como select ... into file . Em suma, o QueryDSL torna impossível a injeção de SQL, além de melhorar a produtividade do programador e aumentar a segurança da refatoração. Impediu o maior risco à segurança de aplicativos da Web, que existiu o tempo suficiente para gerar correções e impulsionou a produtividade do desenvolvedor? Ouso dizer que, se você ainda escrever consultas como strings, está fazendo errado.

Quanto a alternativas para bancos de dados relacionais, é curioso saber que o postgres O controle de simultaneidade de várias versões é exatamente esse tipo de estrutura de dados apenas de unificação que o Tio Bob está falando, embora ele provavelmente estivesse pensando em mais de lojas de eventos , e o padrão de fornecimento de eventos em geral, que também se encaixa bem com a noção de manter o estado atual na RAM.

    
por 27.02.2018 / 03:55
fonte