¿Qué quiere decir Robert C. Martin con que SQL es innecesario? [cerrado]

45

He estado leyendo / viendo mucho contenido de Robert C. Martin. Me he encontrado con él diciendo que SQL es innecesario debido a las unidades de estado sólido. Cuando busco otras fuentes para respaldar esto, recibo un montón de artículos aleatorios que describen la diferencia de rendimiento de SQL entre los discos duros y los de estado sólido (que está relacionado pero no es lo que estoy tratando de investigar).

En última instancia, no entiendo a qué está tratando de llegar. ¿Está diciendo reemplazar SQL con tecnologías No-SQL? ¿Está diciendo almacenar datos en archivos en un sistema de archivos? ¿O simplemente quiere que la gente deje de usar bases de datos relacionales / de SQL debido a los ataques de SQLi? Me temo que me estoy perdiendo el punto que está tratando de hacer.

Le proporcionaré algunos enlaces aquí para que pueda leer directamente de su mente:

  1. Bobby Tables
  2. Conferencia sobre arquitectura limpia

Primero, afirma que el SQL debe eliminarse completamente del sistema.

  

La solución. La única solución. Es eliminar el SQL del sistema.   enteramente. Si no hay un motor SQL, entonces no puede haber SQLi   ataques.

Y aunque él habla de reemplazar SQL con una API, NO creo que signifique poner SQL detrás de una API debido a esa cita anterior y lo que dice anteriormente en el artículo.

  

Los marcos no manejan el problema; ...

Nota al margen: al decir SQL, estoy bastante seguro de que Robert significa la mayoría de las bases de datos relacionales. Tal vez no todos, pero la mayoría. En cualquier caso, la mayoría de la gente está utilizando SQL de todos modos. entonces ...

Si no se está utilizando SQL para datos persistentes, ¿qué se supone que debemos utilizar?

Antes de responder a eso, también debo anotar. Robert enfatiza que las unidades de estado sólido deben cambiar las herramientas que utilizamos para conservar los datos. La respuesta de Søren D. Ptæus lo señala.

También debo responder al grupo "pero integridad de datos". Tras una investigación adicional, Robert dice que deberíamos usar bases de datos transaccionales como datomic . Luego CRUD se convierte en CR (crear y leer) y las transacciones de SQL desaparecen por completo. La integridad de los datos es, por supuesto, importante.

No puedo encontrar una pregunta que abarque todo esto. Supongo que estoy buscando alternativas que coincidan con las pautas de Robert. Datomic es uno pero ¿es eso? ¿Qué otras opciones coinciden con estas pautas? ¿Y realmente funcionan mejor con unidades de estado sólido?

    
pregunta christo8989 26.02.2018 - 02:41

11 respuestas

74

Bob Martin está claramente exagerando para aclarar su punto. Pero ¿cuál es su punto?

  

¿Quiere que la gente deje de usar SQL / bases de datos relacionales debido a los ataques de SQLi?

A mi entender, en esa publicación de blog (su primer enlace), Martin intenta convencer a las personas para que dejen de usar SQL, pero no las bases de datos relacionales. Estas son dos cosas diferentes .

SQL es un lenguaje extremadamente poderoso, y está estandarizado hasta cierto punto. Permite crear consultas y comandos complejos de una manera muy compacta, de manera legible, comprensible y fácil de aprender. No depende de otro lenguaje de programación, por lo que es útil para la mayoría de los programadores de aplicaciones, sin importar si prefieren Java, C, C ++, C #, Python, Ruby, JavaScript, Basic, Go, Perl, PHP o cualquier otra cosa.

Sin embargo, este poder tiene un costo : escribir consultas / comandos SQL seguros es más difícil que escribir mensajes inseguros. Una API segura debería facilitar la creación de consultas seguras "de forma predeterminada". Los potencialmente inseguros deberían necesitar más esfuerzo mental o al menos más de mecanografía. En mi opinión, este es el motivo por el cual Martin se está despotricando contra SQL en su forma actual.

El problema no es nuevo y existen API más seguras que las de SQL estándar para acceder a una base de datos relacional. Por ejemplo, todos los mapeadores de OR que conozco están tratando de proporcionar dicha API (aunque normalmente están diseñados para otros objetivos primarios). Las variantes de SQL estático dificultan la creación de consultas dinámicas con datos de entrada no saneados (y eso no es un invento nuevo: el SQL incorporado, que a menudo utiliza SQL estático, tiene alrededor de 30 años).

Lamentablemente, no conozco ninguna API que sea tan flexible, estandarizada, madura, independiente del lenguaje y también tan potente como SQL, especialmente SQL dinámico. Por eso tengo algunas dudas sobre la sugerencia de Martin de "no usar SQL" como una forma realista de resolver los problemas mencionados. Entonces lea su artículo como un pensamiento en la dirección correcta, no como una "mejor práctica" que puede seguir ciegamente a partir de mañana.

    
respondido por el Doc Brown 26.02.2018 - 11:26
57

La opinión de Bob Martin es solo eso; La opinión de un hombre.

Se espera que un programador entienda el sistema que está escribiendo lo suficientemente bien como para ejercer un cuidado razonable sobre su seguridad y rendimiento. Eso significa que, si está hablando con una base de datos SQL, haga lo que Bobby Tables sitio web dice: usted desinfecta sus datos de entrada. Significa que usted pone su Base de datos SQL en una máquina que promete un rendimiento adecuado. Hay formas muy conocidas y bien entendidas de hacer estas cosas, y si bien no garantizan una seguridad absoluta ni un rendimiento ideal, ninguna otra cosa lo hace.

La afirmación de que ya no necesitamos SQL porque ahora tenemos SSD es simplemente engañosa. SQL no fue inventado porque los discos duros de alta velocidad aún no existían; se inventó porque necesitábamos una forma estándar de la industria para expresar los conceptos de recuperación de datos. Los sistemas de bases de datos relacionales tienen muchas otras cualidades además de la velocidad y la seguridad que los hacen ideales para las operaciones comerciales; en particular, ACID . La integridad de los datos es al menos tan importante como la velocidad o la seguridad, y si no la tiene, ¿para qué proteger los datos erróneos o recuperarlos lo más rápido posible?

Antes de tomar la histeria de un hombre como evangelio, le sugiero que aprenda sobre la aplicación y la seguridad y el rendimiento del sistema en sus propios términos, no leyendo artículos de Internet al azar. La seguridad, el rendimiento y el diseño robusto del sistema son mucho más que simplemente "evitar esta tecnología".

No prohibimos los cuchillos de cocina porque algunas personas desafortunadas logran cortarse los dedos accidentalmente con ellos.

    
respondido por el Robert Harvey 26.02.2018 - 06:51
15

¿Qué está diciendo en realidad?

  

¿Está diciendo reemplazar SQL con tecnologías No-SQL?

TL; DR: Sí (tipo de)

En una conversación más reciente que la que vinculaste básicamente en el mismo tema, él dice: " La base de datos es un detalle. ¿Por qué tenemos bases de datos? ".

Afirma que la base de datos llegó a facilitar el acceso a los datos desde los discos giratorios, pero en el futuro " [...] no habrá discos " gracias a la nueva tecnología y lo que él llama" RAM persistente "y que será más fácil almacenar datos usando las estructuras que usan los programadores, como como tablas hash o árboles.

Continúa prediciendo que las bases de datos relacionales en general desaparecerán en gran medida debido a su nueva competencia:

  

Si fuera Oracle, estaría bastante asustada porque la razón de mi existencia se está evaporando de debajo de mí. [.. .] El motivo por el que existe la base de datos está desapareciendo.

     

Probablemente habrá algunas tablas relacionales que sobrevivan, pero ahora hay una competencia sana .

Así que no, para él no se trata solo de inyección de SQL, aunque él opina que SQL tiene fallas inherentes en este aspecto .

Nota del autor:

Las declaraciones en esta publicación son solo citas para comprender la opinión de Robert C. Martin sobre este tema y no representan la opinión del autor. Para obtener un punto de vista más diferenciado, consulte la respuesta de Robert Harvey .

    
respondido por el Søren D. Ptæus 26.02.2018 - 13:56
11

SQL es un detalle. El conocimiento de un detalle no debe extenderse.

A medida que se usa SQL en más y más lugares en su código, su código depende cada vez más de él.

A medida que aprendes más y más trucos de SQL, resuelves más y más problemas usando SQL. Esto significa que cambiar a otra API para persistir implica más que solo traducir. Tienes que resolver problemas que no te habías dado cuenta.

Te encuentras con esto incluso cambiando entre bases de datos. One ofrece la característica 5 de whizzbang de lujo, por lo que la usa en varios lugares solo para descubrir que la característica 5 de whizzbang de lujo es exclusiva y ahora tiene un problema de licencia que va a costar mucho dinero. Así que trabajas mucho desenterrando todos los lugares donde usaste la función 5 y resolviendo el problema por tu cuenta solo para descubrir más tarde que también estás usando la función 3 de whizzbang.

Una de las cosas que hace que Java sea tan portátil es que ciertas características de la CPU simplemente no están disponibles. Si estuvieran disponibles los usaría. Y de repente hay CPUs en las que mi código Java no funcionará porque no tienen esas características. Es lo mismo con las características de la base de datos.

Es fácil sacrificar tu independencia sin darte cuenta. SQL es una opción no dada. Si toma la decisión de usar SQL, entonces hágalo en un solo lugar. Hazlo de una manera que se pueda deshacer.

El hecho de que SQL tenga problemas de seguridad y de que nos estamos moviendo a modelos de memoria persistentes no significa que SQL esté condenado. Simplemente lleva a casa el punto de que es una elección. Si desea conservar el derecho a tomar esa decisión, tiene que hacer el trabajo.

Puede valer la pena señalar que el movimiento de la base de datos de los años 80 y el tío Bob tienen una historia bastante desagradable. Resolvió todos sus problemas con un sistema de archivos planos cuando la administración obligó a un administrador de base de datos a entrar en su vida. Este evento lo empujó a su carrera de consultoría estelar. (Cuenta esta historia en uno de sus primeros libros limpios, olvida cuál) Sabe cómo resolver problemas sin DB y tiene poca paciencia para aquellos que actúan como si usarlos es un hecho.

También cuenta una historia sobre posponer la adición de un DB a una aplicación hasta el último minuto cuando un cliente lo exigió, y la agregó en un día como una característica opcional. Mi conjetura es que él ve la manera en que la mayoría de nosotros usamos DB's como una adicción. Él está tratando de mostrarnos cómo dejar el hábito.

    
respondido por el candied_orange 26.02.2018 - 15:36
5

La cita de tu primera cita es (énfasis mío),

  

La solución. La única solución. Es eliminar SQL del sistema por completo. Si no hay un motor SQL, entonces no puede haber ataques SQLi.

     

¿Qué reemplazaría a SQL? Un API por supuesto! Y NO una API que usa un lenguaje textual. En su lugar, una API que utiliza un conjunto adecuado de estructuras de datos y llamadas a funciones para acceder a los datos necesarios.

La queja es contra permitir que los programadores de aplicaciones usen SQL.

La solución sugerida es permitirles usar una API en su lugar: que no es SQL y no permite la inyección.

OMI, los ejemplos de tales API pueden incluir:

  • enlace sugiere que los programadores de C # pueden usar la API de ADO.NET.

    Este no es un ejemplo perfecto porque ADO.NET es una API amplia o profunda (es decir, potente o de propósito general), que también permite a sus usuarios ingresar SQL sin formato (o raw-ish).

  • Algunos desarrolladores de SQL o administradores de bases de datos sugieren que una base de datos debe configurarse de modo que solo permita el acceso a través de (un número limitado de expertos) procedimientos almacenados , y que a los desarrolladores de aplicaciones no se les debe permitir escribir sus propias consultas SQL (peligrosas)

  • Otra forma de "eliminar SQL del sistema" es colocar la base de datos (que expone a SQL) en algún otro sistema otro , al que se accede mediante una API REST o similar.

Entonces, IMO, la solución general o el sistema [s] todavía pueden usar una base de datos (especialmente dado que un motor de base de datos implementa propiedades útiles de ACID, y se adapta bien, etc., puede ser una tontería tratar de hacerlo sin uno, o para escribir una aplicación específica).

Los requisitos de la perorata se satisfacen si la API de SQL de la base de datos está oculta para los desarrolladores de aplicaciones, detrás de otra API (por ejemplo, ADO, quizás un ORM, un servicio web, o lo que sea).

Más generalmente, supongo que significa tener un DAL específico de la aplicación (una "capa de acceso a datos" o "capa de abstracción de base de datos"). Un DAL aísla la aplicación de los detalles de cómo y dónde se almacenan y / o recuperan los datos. El DAL puede o no implementarse utilizando una base de datos SQL.

    
respondido por el ChrisW 26.02.2018 - 15:35
3

Todo el mundo parece estar respondiendo esta pregunta desde un punto de vista de seguridad, o con una lente SQL.

Vi una conferencia de Robert Martin en la que relata que, como programadores, usamos muchas estructuras de datos diferentes que son óptimas para nuestros programas específicos. Por lo tanto, en lugar de almacenar universalmente todos los datos en una estructura tabular, deberíamos almacenarlos en tablas hash, árboles, etc. para poder capturar los datos y saltar directamente al programa.

Interpreté su mensaje como si solo dijera que deberíamos desechar nuestras suposiciones actuales sobre el almacenamiento persistente por un momento para considerar otras posibilidades futuras que no sean el antiguo formato tabular de SQL. SSD es una solución candidata, pero no la única.

    
respondido por el Keenan 26.02.2018 - 19:37
2

En realidad, no debe usar bases de datos y SQL, de manera bastante explícita. La primera referencia es un problema bien conocido, la segunda referencia suena como una perorata. Aunque, lo estoy interpretando como que tiene una buena razón para usar bases de datos y no para usar SQL. Desde mi perspectiva esto ni siquiera es un consejo razonable.

Desafortunadamente, el ejemplo que está usando es un ejemplo bien conocido con una solución bien conocida que luego señala. Normalmente ocurre cuando un programador no se da cuenta de lo que está haciendo. Por ejemplo, construyendo cadenas que contengan SQL como:

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

a diferencia de

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

Este es un ejemplo DBI perl para el código ruby on rails. El código de rieles que proporciona es fácil de confundir entre lo seguro y lo inseguro. Como muchos ORM, oculta lo que está debajo del SQL y, a menudo, se trata de una interfaz que construye y ejecuta el SQL por usted. ¿No suena esto casi como lo que una API haría por ti?

Mi interpretación de la primera referencia es que él sugiere que deberíamos reemplazar un problema bien conocido que tiene una solución bien conocida.

También es desafortunado que no mencione que si se hace correctamente hará que el código sea más fácil de escribir y más legible, aunque si se hace bien, en realidad puede ser más difícil de escribir y menos legible. Además, no menciona que SQL es realmente muy fácil de leer y hace lo que generalmente se espera que haga.

Es parcialmente correcto, en última instancia tendremos una memoria infinitamente grande y rápida y un procesador infinitamente rápido. Hasta que salgamos de la física actual que restringe la computación, él no está en lo correcto.

Sí, los discos giratorios son cosa del pasado, y ahora usamos SSD. Los discos funcionan con aproximadamente ~ 10 milisegundos por transferencia de datos, los SSD funcionan con ~ 0.5 milisegundos (500 microsegundos) de tiempo de acceso a datos. La RAM es del orden de 100 nano segundos, los procesadores operan en el orden de 100 segundos de pico segundos. Este es el corazón de por qué necesitamos bases de datos. Las bases de datos administran la transferencia de datos entre discos giratorios o SSD con memoria principal. La llegada de los SSD no ha eliminado la necesidad de bases de datos.

    
respondido por el Robert Baron 26.02.2018 - 13:32
2

Respuesta

  

¿solo quiere que la gente deje de usar SQL / bases de datos relacionales debido a los ataques de SQLi?

El artículo 'Bobby Tables' parece sugerir que esto, en sí mismo, es una razón para no usar SQL:

  

La solución. La única solución. Es eliminar el SQL del sistema por completo. Si no hay un motor SQL, entonces no puede haber ataques SQLi.

Él podría tener otras razones que él discute en otra parte. No lo sabría porque realmente no leo mucho de sus cosas.

Digresión

Esta parte no es realmente una respuesta, pero creo que la cuestión del valor de SQL es mucho más interesante (al igual que otros, al parecer)

He tenido mucha experiencia en el uso de SQL y creo que tengo una comprensión justa de sus fortalezas y debilidades. Mi sensación personal es que se ha usado en exceso y se ha abusado de ella, pero que la idea de que nunca deberíamos usarla es un poco tonta. La idea de que debemos elegir 'SQL siempre' o 'SQL nunca' es una falsa dicotomía.

En cuanto a que la inyección de SQL es un argumento para no usar SQL, es ridículo. Este es un problema bien entendido con una solución bastante simple. El problema con este argumento es que SQLi no es la única vulnerabilidad que existe. Si crees que el uso de las API de JSON te hace seguro, te espera una gran sorpresa.

Creo que todos los desarrolladores deberían ver este video titulado "Friday" 13: Atacando a JSON - Alvaro Muñoz & Oleksandr Mirosh - AppSecUSA 2017 "

Si no tiene el tiempo o la inclinación para mirar a través de él, aquí está la idea: muchas bibliotecas de deserialización JSON tienen vulnerabilidades de ejecución remota de código. Si está utilizando XML, tiene aún más de qué preocuparse. Prohibir SQL de su arquitectura no hará que su sistema sea seguro.

    
respondido por el JimmyJames 26.02.2018 - 16:17
2

Quiero abordar solo una breve declaración:

  

O simplemente quiere que la gente deje de usar SQL / bases de datos relacionales   debido a los ataques de SQLi?

No. Esa es una suposición errónea. No podemos decir que debemos dejar de usar automóviles, ya que son responsables de las personas que mueren en accidentes automovilísticos. De la misma manera, las bases de datos SQL / relacionales (o cualquier otra cosa en este contexto, como RDBMS) no son responsables de la carga de SQL maliciosa que un atacante puede realizar en su aplicación web. Estoy seguro de que el autor no quiso decir eso, porque hay una hoja de trucos de prevención de inyección SQL para este propósito.

    
respondido por el Billal Begueradj 26.02.2018 - 11:42
2

El problema de Martin parece ser que los programadores crean SQL dinámico directamente a partir de las aportaciones del usuario, algo así (perdóname, soy principalmente un programador de C y C ++):

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

que es absolutamente una receta para la acidez estomacal (de ahí la tira Bobby Tables ). Cualquier programador que ponga código como ese en un sistema de producción merece un paddlin '.

Puede mitigar (si no eliminar por completo) el problema utilizando declaraciones preparadas y saneando adecuadamente sus entradas. Si puede ocultar el SQL detrás de una API, de modo que los programadores no están creando cadenas de consulta directamente, es mucho mejor (lo que es parte de lo que Martin defiende).

Pero para deshacerme de SQL por completo, no creo que sea práctico o deseable. Los modelos relacionales son útiles , es por eso que existen en primer lugar, y SQL es probablemente la mejor interfaz para trabajar con modelos relacionales.

Como siempre, se trata de usar la herramienta adecuada para el trabajo. Si su aplicación de carrito de compras no necesita un modelo relacional completo, entonces no use un modelo relacional (lo que significa que no necesitará usar SQL). Para los momentos en que necesita un modelo relacional, es casi seguro que estará trabajando con SQL.

    
respondido por el John Bode 26.02.2018 - 23:37
1

Las dos fuentes que vinculas transmiten diferentes mensajes:

La publicación del blog dice que la lógica de acceso a los datos no debería existir como texto en tiempo de ejecución, para que no se mezcle con entradas de usuarios no confiables. Es decir, la publicación del blog condena las consultas de escritura mediante la concatenación de cadenas.

La conferencia es diferente. La primera diferencia está en el tono: la conferencia especula y cuestiona, pero no condena. Él no dice que las bases de datos son malas, pero nos desafía a imaginar la persistencia sin una base de datos. Argumenta que en los 30 años desde que las bases de datos relacionales se generalizaron, muchas cosas han cambiado, y destaca dos que posiblemente podrían afectar nuestra elección de tecnología de persistencia:

  • el espacio de almacenamiento ha aumentado en un factor de aproximadamente 1 millón, ¡a precios comparables! En consecuencia, es menos necesario conservar el almacenamiento y, en particular, ya no es necesario eliminar. Mediante el uso de almacenamiento solo para anexos, el control de concurrencia se puede simplificar porque los bloqueos de lectura no son necesarios. Esto puede obviar la necesidad de transacciones.
  • los tiempos de acceso han disminuido, porque la mayoría de los conjuntos de datos ahora caben en la RAM, lo que reduce enormemente la latencia de lectura.

¿Estas circunstancias cambiantes cambian la tecnología de persistencia óptima? Curiosamente, el tío Bob no lo dice, probablemente porque no cree que una respuesta sea correcta para todos los programas. Es por eso que nos advierte que tratemos nuestra elección de tecnología de persistencia como un detalle en lugar de incluirla en tabletas de piedra y transmitirla como sabiduría recibida a nuestros compañeros.

¿Existen alternativas?

Escribir lógica de acceso a datos sin cadenas es completamente posible. En Java land, puede utilizar QueryDSL , donde las consultas se describen utilizando una API fluida de tipo seguro generada a partir de su esquema de base de datos. Dicha consulta puede tener el siguiente aspecto:

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

Como puede ver, la lógica de consulta no se expresa como una Cadena, separando claramente la estructura confiable de la consulta de los parámetros que no son de confianza (y, por supuesto, QueryDSL nunca incluye los parámetros en el texto de la consulta, pero usa declaraciones preparadas para separar la consulta para sus parámetros en el nivel JDBC). Para lograr la inyección de SQL con QueryDSL, tendría que escribir su propio analizador para analizar una cadena y convertirla en un árbol de sintaxis, e incluso si lo hiciera, probablemente no agregaría soporte para cosas desagradables como select ... into file . En resumen, QueryDSL hace que la inyección de SQL sea imposible, y también mejora la productividad del programador y aumenta la seguridad de refactorización. ¿Se evitó el mayor riesgo para la seguridad de las aplicaciones web, que ha existido durante el tiempo suficiente para generar ejecutar gags y ha aumentado la productividad de los desarrolladores? Me atrevo a decir que si aún escribes consultas como cadenas, lo estás haciendo mal.

En cuanto a las alternativas a las bases de datos relacionales, es curioso saber que de postgres el control de concurrencia de varias versiones es exactamente ese tipo de estructura de datos de solo apéndice del que habla el tío Bob, aunque probablemente estaba pensando más en tiendas de eventos , y el patrón de fuente de eventos en general, que también encaja perfectamente con La noción de mantener el estado actual en la memoria RAM.

    
respondido por el meriton 27.02.2018 - 03:55