Eu tenho lido / assistido muito conteúdo de Robert C. Martin. Eu o encontrei dizendo que o SQL é desnecessário por causa de unidades de estado sólido. Quando pesquiso outras fontes para fazer backup disso, recebo vários artigos aleatórios que descrevem a diferença de desempenho do SQL entre discos rígidos e unidades de estado sólido (que está relacionada, mas não é o que estou tentando pesquisar).
Por fim, não entendo o que ele está tentando entender. Ele está dizendo substituir SQL por 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 bancos de dados SQL / relacionais devido a ataques SQLi? Receio estar perdendo o argumento que ele está tentando fazer.
Vou fornecer alguns links aqui para que você possa ler diretamente de sua mente:
Primeiro, ele afirma que o SQL deve ser removido completamente do sistema.
A solução. A única solução. É eliminar completamente o SQL do sistema. Se não houver mecanismo SQL, não haverá ataques SQLi.
E embora ele fale sobre substituir o SQL por uma API, NÃO acho que ele queira colocar o SQL por trás de uma API por causa da citação anterior e do que ele disse anteriormente neste artigo.
As estruturas não lidam com o problema; ...
Nota lateral: Ao dizer SQL, tenho certeza que Robert significa a maioria dos bancos de dados relacionais. Talvez não todos, mas a maioria. De qualquer forma, a maioria das pessoas está usando o SQL de qualquer maneira. tão...
Se o SQL não está sendo usado para persistir dados, o que devemos usar?
Antes de responder a isso, devo observar também. Robert enfatiza que as unidades de estado sólido devem alterar as ferramentas que usamos para manter os dados. A resposta de Søren D. Ptæus aponta isso.
Também devo responder ao grupo "mas a integridade dos dados". Após algumas pesquisas, Robert diz que devemos usar bancos de dados transacionais como o datômico . Em seguida, 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? Que outras opções correspondem a essas diretrizes? E eles realmente funcionam melhor com unidades de estado sólido?
eval(request.GET["table_name"] + ".get(pk=" + request.GET["pk"] + ")"))
. Não é realmente o SQL que falha, mas os programadores pobres e ignorantes.Respostas:
Bob Martin está claramente exagerando para deixar seu argumento mais claro. Mas qual é o ponto dele?
Na minha opinião, nesse post (seu primeiro link), Martin tenta convencer as pessoas a parar de usar o SQL, mas não os bancos de dados relacionais. Essas são duas coisas diferentes .
SQL é uma linguagem extremamente poderosa e é padronizada até certo ponto. Permite criar consultas e comandos complexos de maneira muito compacta, de maneira legível, compreensível e fácil de aprender. Ele não depende de outra linguagem de programação; portanto, é utilizável para a maioria dos programadores de aplicativos, independentemente de preferir Java, C, C ++, C #, Python, Ruby, JavaScript, Básico, Go, Perl, PHP ou qualquer outra coisa.
No entanto, esse poder tem um custo : escrever consultas / comandos SQL seguros é mais difícil do que escrever perguntas não seguras. Uma API segura deve facilitar a criação de consultas seguras "por padrão". Os potencialmente inseguros devem precisar de mais esforço mental ou pelo menos mais de digitação. É por isso que IMHO Martin está reclamando contra o SQL em sua forma atual.
O problema não é novo e existem APIs mais seguras que o SQL padrão para acessar um banco de dados relacional. Por exemplo, todos os mapeadores OR que eu conheço estão tentando fornecer uma API (embora eles geralmente sejam projetados para outros objetivos principais). As variantes de estática do SQL dificultam a criação de consultas dinâmicas com dados de entrada não autorizados (e isso não é uma invenção nova: o SQL incorporado, que usa frequentemente o SQL estático, tem cerca de 30 anos).
Infelizmente, não conheço nenhuma API que seja tão flexível, padronizada, madura, independente de linguagem e também tão poderosa quanto SQL, especialmente SQL dinâmico. É por isso que tenho algumas dúvidas sobre a sugestão de Martin de "não usar SQL" como uma maneira realista de resolver os problemas mencionados. Portanto, leia o artigo dele como um pensamento na direção certa, não como uma "melhor prática" que você possa seguir cegamente a partir de amanhã.
fonte
A opinião de Bob Martin é exatamente isso; opinião de um homem.
Espera-se que um programador entenda o sistema que está escrevendo bem o suficiente para ter um cuidado razoável com sua segurança e desempenho. Isso significa que, se você estiver conversando com um banco de dados SQL, faça o que o site Bobby Tables faz: desinfeta seus dados de entrada. Isso significa que você coloca seu banco de dados SQL em uma máquina que promete desempenho adequado. Existem maneiras muito conhecidas e bem compreendidas de fazer essas coisas e, embora não garantam segurança absoluta ou desempenho ideal, nem mais nada.
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 ainda não existiam discos rígidos de alta velocidade; foi inventado porque precisávamos de uma maneira padrão do setor para expressar conceitos de recuperação de dados. Os sistemas de bancos de dados relacionais têm muitas outras qualidades além da 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 os possui, qual é o sentido de proteger dados ruins ou recuperá-los o mais rápido possível?
Antes de considerar 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, não lendo artigos aleatórios da Internet. Há muito mais na segurança, desempenho e design robusto do sistema do que simplesmente "evitar esta tecnologia".
Não proibimos facas de cozinha porque algumas pessoas infelizes conseguem acidentalmente cortar os dedos com elas.
fonte
O que ele está realmente dizendo?
TL; DR: Sim (mais ou menos)
Em uma conversa mais recente do que a que você ligou basicamente sobre o mesmo tópico, ele diz: "O banco de dados é um detalhe. Por que temos bancos de dados?" .
Ele afirma que o banco de dados veio para facilitar o acesso a dados de 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 armazene dados usando as estruturas que os programadores usam, como hashtables ou árvores.
Ele continua prevendo que os bancos de dados relacionais desaparecerão em grande parte devido à nova concorrência:
Portanto, não, para ele, não se trata apenas de injeção de SQL, embora ele opine que o SQL seja inerentemente defeituoso nesse aspecto .
Nota do autor:
As declarações neste post são apenas citações para entender a visão de Robert C. Martin sobre esse tópico e não representam a opinião do autor. Para um ponto de vista mais diferenciado, consulte a resposta de Robert Harvey .
fonte
SQL é um detalhe. O conhecimento de um detalhe não deve se espalhar.
Como o SQL é usado em mais e mais lugares no seu código, seu código se torna cada vez mais dependente dele.
À medida que aprende mais e mais truques sobre SQL, você resolve mais e 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 não sabia que tinha.
Você encontra isso mesmo alternando entre bancos de dados. Um oferece o recurso sofisticado whizzbang 5, para que você o use em vários lugares apenas para descobrir que o recurso sofisticado whizzbang 5 é proprietário e agora você tem um problema de licenciamento que vai custar muito dinheiro. Então, você trabalha bastante em todos os lugares em que usou o recurso 5 e resolve 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, existem CPUs nas quais meu código Java não funciona porque eles 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 que não é dada. Se você decidir usar o SQL, faça-o em um só lugar. Faça de uma maneira que possa ser desfeita.
O fato de o SQL ter problemas de segurança e de estarmos migrando para modelos de memória persistente não significa que o SQL esteja condenado. Apenas leva para casa o ponto em que é uma escolha. Se você deseja preservar o direito de fazer essa escolha, deve fazer o trabalho.
Pode-se notar que o movimento do banco de dados dos anos 80 e o tio Bob têm 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 a entrar em sua vida. Este evento o levou a sua carreira de consultoria estelar. (Ele conta essa história em um de seus primeiros livros limpos, esqueça qual deles). Ele sabe como resolver problemas sem os DB e tem pouca paciência para aqueles que agem como usá-los.
Ele também conta uma história sobre adiar a adição de um banco de dados a um aplicativo até o último minuto em que um cliente o exigiu e o adicionou em um dia como um recurso opcional. Meu palpite é que ele vê como a maioria de nós usa DBs como um vício. Ele está tentando nos mostrar como largar o hábito.
fonte
A citação da sua primeira citação é (ênfase minha),
O argumento é contra permitir que programadores de aplicativos usem o SQL.
A correção sugerida é permitir que eles usem uma API: o que não é SQL e não permite injeção.
Na IMO, exemplos dessas APIs podem incluir:
http://bobby-tables.com/csharp sugere que programadores de C # podem usar a API ADO.NET.
Esse não é um exemplo perfeito, porque o ADO.NET é uma API ampla ou profunda (ou seja, poderosa ou de uso geral), que também permite que seus usuários insiram SQL bruto (ou bruto).
Alguns desenvolvedores de SQL ou administradores de banco de dados sugerem que um banco de dados seja configurado de forma a permitir o acesso apenas por meio de procedimentos armazenados (um número limitado de escritos por especialistas) e que os desenvolvedores de aplicativos não devem 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 outro sistema, acessado por meio de uma API REST ou similar.
Portanto, na IMO, a solução ou os sistemas gerais ainda podem usar um banco de dados (especialmente considerando que um mecanismo de banco de dados implementa propriedades ACID úteis e dimensiona bem e assim por diante, pode ser tolice tentar ficar sem um ou escrever um aplicativo específico).
Os requisitos do discurso retórico são atendidos 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 outro).
Mais geralmente, suponho que significa 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.
fonte
Todo mundo parece estar respondendo a essa pergunta do ponto de vista de segurança ou com uma lente SQL.
Vi uma palestra de Robert Martin, onde ele conta que, como programadores, usamos muitas estruturas de dados diferentes que são ideais para nossos programas específicos. Portanto, em vez de armazenar todos os dados universalmente em uma estrutura tabular, devemos armazenar nossos dados em tabelas de hash, árvores, etc., para que possamos pegar os dados e pular direto para o programa.
Interpretei sua mensagem como dizendo apenas que deveríamos jogar fora nossas suposições atuais sobre armazenamento persistente por um momento para considerar outras possibilidades futuras além do antigo formato tabular do SQL. O SSD é uma solução candidata, mas não a única.
fonte
Na verdade, ele não deve usar bancos de dados e SQL - de maneira bastante explícita. A primeira referência é uma questão bem conhecida, a segunda referência soa como um discurso retórico. Embora, eu o interprete como um bom motivo para usar bancos de dados e não usar SQL. Da minha perspectiva, isso nem é um conselho razoável.
Infelizmente, o exemplo que ele está usando é um exemplo bem conhecido, com uma solução conhecida que ele aponta. Geralmente ocorre quando um programador não percebe o que está fazendo. Por exemplo, construindo strings contendo SQL, como:
em oposição a
Este é um perl DBI como exemplo 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, oculta o que é o SQL e, com frequência, você está lidando com uma interface que constrói e executa o sql para você. Isso não parece quase o que uma API faria por você?
Minha interpretação da primeira referência é que ele está sugerindo que devemos substituir um problema conhecido que tenha uma solução 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, pode ser 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ê normalmente espera que ele faça.
Ele está parcialmente correto, finalmente teremos uma memória infinitamente grande e rápida e um processador infinitamente rápido. Até sairmos da física atual que restringe a computação, ele não está correto.
Sim, o disco giratório é coisa do passado, e agora usamos SSDs. Os discos funcionam com cerca de ~ 10 milissegundos por transferência de dados, os SSDs funcionam com ~ 0,5 milissegundos (500 microssegundos). A RAM é da ordem de 100 nano segundos, os processadores operam com mais de 100 segundos de pico segundos. Esse é o coração do motivo pelo qual 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.
fonte
Responda
O artigo 'Bobby Tables' parece sugerir que isso, por si só, é um motivo para não usar SQL:
Ele pode ter outros motivos para discutir em outro lugar. Eu não saberia porque realmente não leio muito das coisas dele.
Digressão
Esta parte não é realmente uma resposta, mas acho que a questão do valor do SQL é muito mais interessante (assim como outros, aparentemente).
Eu tenho muita experiência com o SQL e acho que tenho um entendimento justo de seus pontos fortes e fracos. Meu sentimento pessoal é que ele foi usado em excesso e abusado, mas que a ideia de nunca usá-lo é meio boba. A ideia de que devemos escolher 'SQL sempre' ou 'SQL nunca' é uma dicotomia falsa.
Tanto quanto a injeção de SQL ser um argumento para não usar SQL, isso é ridículo. Este é um problema bem compreendido com uma solução bastante simples. O problema com esse argumento é que o SQLi não é a única vulnerabilidade que existe. Se você acha que o uso de APIs JSON o protege, você terá uma grande surpresa.
Acho que todo desenvolvedor deve assistir a este vídeo intitulado "Sexta-feira 13: atacando JSON - Alvaro Muñoz e Oleksandr Mirosh - AppSecUSA 2017"
Se você não tem tempo ou inclinação para assistir, aqui está o essencial: Muitas bibliotecas de desserialização JSON têm vulnerabilidades de execução remota de código. Se você estiver usando XML, precisará se preocupar ainda mais. Proibir o SQL da sua arquitetura não tornará seu sistema seguro.
fonte
Quero abordar apenas uma declaração curta:
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 maneira, os bancos de dados SQL / relacionais (ou qualquer outra coisa nesse contexto, como RDBMS) não são responsáveis pela carga maliciosa de SQL que um invasor pode executar em seu aplicativo Web. Estou certo de que o autor não quis dizer isso, porque existe toda uma folha de dicas sobre prevenção de injeção de SQL para esse fim.
fonte
O problema de Martin parece estar com os programadores construindo SQL dinâmico diretamente da entrada do usuário, algo como (me desculpe, eu sou principalmente um programador de C e C ++):
que é absolutamente uma receita para azia (daí a tira das mesas de Bobby ). Qualquer programador que coloque código como esse em um sistema de produção merece um remo.
Você pode atenuar (se não eliminar totalmente) o problema usando instruções preparadas e higienizando adequadamente suas entradas. Se você pode ocultar o SQL atrás de uma API, de modo que os programadores não construam diretamente as strings de consulta, tanto melhor (o que é parte do que Martin defende).
Mas, quanto a me livrar completamente do SQL, não acho isso prático ou desejável. 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 aplicativo do 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). Nas vezes em que você precisa de um modelo relacional, quase certamente estará trabalhando com o SQL.
fonte
sprintf
não contém o tipo de sanitização que SQL exige, as funções que são projetados especificamente para esta finalidade fazer, e são perfeitamente seguros. Exemplo: SqlQuery no Entity Framework .sprintf
usam apenas SQL dinâmico, que não é como você faz.As duas fontes vinculadas transmitem mensagens diferentes:
A postagem 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 misturada com a entrada não confiável do usuário. Ou seja, a postagem do blog condena a gravação de consultas concatenando seqüências de caracteres.
A palestra é diferente. A primeira diferença está no tom: a palestra especula e questiona, mas não condena. Ele não diz que os bancos de dados são maus, mas nos desafia a imaginar persistência sem um banco de dados. Ele argumenta que, nos 30 anos desde que os bancos de dados relacionais se espalharam, muitas coisas mudaram e destaca dois que podem afetar a nossa escolha da tecnologia de persistência:
Essas circunstâncias alteradas alteram a tecnologia de persistência ideal? Curiosamente, o tio Bob não diz - provavelmente porque ele acha que nenhuma resposta seria correta para todos os programas. É por isso que ele nos adverte a tratar nossa escolha de tecnologia de persistência como um detalhe, em vez de consagrá-la em tábuas de pedra e transmiti-la como sabedoria recebida a nossos pares.
Existem alternativas?
Escrever a lógica de acesso a dados sem strings é inteiramente possível. No Java land, você pode usar QueryDSL , em que as consultas são descritas usando uma API fluente de segurança de tipo gerada a partir do seu esquema de banco de dados. Essa consulta pode ter a seguinte aparência:
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 obter a injeção de SQL com o QueryDSL, você teria que escrever seu próprio analisador para analisar uma string e convertê-la em uma árvore de sintaxe, e mesmo se você fizer isso, provavelmente não adicionará suporte para coisas desagradáveis como
select ... into file
. Em resumo, o QueryDSL torna quase impossível a injeção de SQL e também melhora a produtividade do programador e aumenta a segurança da refatoração. Impediu o maior risco à segurança de aplicativos da Web, que existe o tempo suficiente para gerar gags em execuçãoe aumentou a produtividade do desenvolvedor? Ouso dizer que, se você ainda escrever consultas como strings, estará fazendo errado.Quanto às alternativas às bases de dados relacionais, é curioso saber que o controle de simultaneidade de várias versões do postgres é exatamente esse tipo de estrutura de dados somente anexada que o Tio Bob está falando, embora provavelmente estivesse pensando mais em armazenamentos de eventos e na fonte de eventos padrão em geral, que também se encaixa muito bem com a noção de manter o estado atual na RAM.
fonte