web-dev-qa-db-fra.com

Que veut dire Robert C. Martin par SQL inutile?

J'ai lu/regardé beaucoup de contenu de Robert C. Martin. Je l'ai rencontré en disant que SQL n'est pas nécessaire à cause des disques SSD. Lorsque je recherche d'autres sources pour sauvegarder cela, je reçois un tas d'articles aléatoires décrivant la différence de performances SQL entre les disques durs et les disques SSD (ce qui est lié mais pas ce que j'essaie de rechercher).

En fin de compte, je ne comprends pas ce qu'il essaie de faire. Dit-il remplacer SQL par des technologies sans SQL? Dit-il stocker des données dans des fichiers dans un système de fichiers? Ou veut-il simplement que les gens cessent d'utiliser les bases de données SQL/relationnelles à cause des attaques SQLi? Je crains de manquer le point qu'il essaie de faire valoir.

Je vais fournir quelques liens ici afin que vous puissiez lire directement dans son esprit:

  1. Tables Bobby
  2. Conférence sur l'architecture propre

Premièrement, il déclare que SQL devrait être supprimé complètement du système.

La solution. La seule solution. Est d'éliminer complètement SQL du système. S'il n'y a pas de moteur SQL, il ne peut y avoir aucune attaque SQLi.

Et bien qu'il parle de remplacer SQL par une API, je ne pense pas qu'il veuille mettre SQL derrière une API à cause de cette citation précédente et de ce qu'il dit plus tôt dans l'article.

Les cadres ne gèrent pas le problème; ...

Note latérale: En disant SQL, je suis presque sûr que Robert signifie la plupart des bases de données relationnelles. Peut-être pas tous, mais la plupart. Dans tous les cas, la plupart des gens utilisent de toute façon SQL. alors ...

Si SQL n'est pas utilisé pour conserver les données, que devons-nous utiliser?

Avant de répondre à cela, je dois également noter. Robert souligne que les disques SSD doivent changer les outils que nous utilisons pour conserver les données. Søren D. Ptæus réponse le souligne.

Je dois également répondre au groupe "mais l'intégrité des données". Après quelques recherches supplémentaires, Robert dit que nous devrions utiliser des bases de données transactionnelles comme datomic . CRUD se transforme alors en CR (création et lecture) et les transactions SQL disparaissent complètement. L'intégrité des données est bien sûr importante.

Je ne trouve pas de question qui englobe tout cela. Je suppose que je cherche des alternatives qui correspondent aux directives de Robert. Datomic en est un, mais est-ce bien cela? Quelles autres options correspondent à ces directives? Et fonctionnent-ils mieux avec les disques SSD?

45
christo8989

Bob Martin exagère clairement pour clarifier son propos. Mais quel est son point?

Veut-il simplement que les gens cessent d'utiliser les bases de données SQL/relationnelles à cause des attaques SQLi?

À ma connaissance, dans ce billet de blog (votre premier lien), Martin essaie de convaincre les gens d'arrêter d'utiliser SQL, mais pas les bases de données relationnelles. Ceux-ci sont deux choses différentes.

SQL est un langage extrêmement puissant, et il est normalisé dans une certaine mesure. Il permet de créer des requêtes et des commandes complexes de manière très compacte, de manière lisible, compréhensible et facile à apprendre. Il ne dépend pas d'un autre langage de programmation, il est donc utilisable par la plupart des programmeurs d'applications, qu'ils préfèrent Java, C, C++, C #, Python, Ruby, JavaScript, Basic, Go, Perl, PHP ou autre chose.

Cependant, ce pouvoir a un coût: écrire des requêtes/commandes SQL sécurisées est plus difficile que d'écrire des requêtes non sécurisées. Une API sûre devrait faciliter la création de requêtes sûres "par défaut". Les personnes potentiellement dangereuses devraient nécessiter plus d'efforts mentaux ou au moins plus de frappe. C'est à mon humble avis pourquoi Martin se déchaîne contre SQL dans sa forme actuelle.

Le problème n'est pas nouveau et il existe des API plus sûres que le SQL standard pour accéder à une base de données relationnelle. Par exemple, tous les mappeurs OR que je connais tentent de fournir une telle API (bien qu'ils soient généralement conçus pour d'autres objectifs principaux). Les variantes SQL statiques rendent difficile la création de requêtes dynamiques avec une entrée non désinfectée. données (et ce n'est pas une nouvelle invention: Embedded SQL, qui utilise souvent du SQL statique, a environ 30 ans).

Malheureusement, je ne connais aucune API aussi flexible, standardisée, mature, indépendante du langage et aussi puissante que SQL, en particulier SQL dynamique. C'est pourquoi j'ai des doutes sur la suggestion de Martin de "ne pas utiliser SQL" comme moyen réaliste de résoudre les problèmes mentionnés. Lisez donc son article comme une pensée dans la bonne direction, et non comme une "meilleure pratique" que vous pouvez suivre aveuglément à partir de demain.

74
Doc Brown

L'opinion de Bob Martin n'est que cela; l'opinion d'un homme.

On s'attend à ce qu'un programmeur comprenne le système qu'il écrit suffisamment bien pour faire preuve d'une attention raisonnable quant à sa sécurité et ses performances. Cela signifie que, si vous parlez à une base de données SQL, vous faites ce que le Bobby Tableswebsite dit de faire: vous désinfectez vos données d'entrée. Cela signifie que vous placez votre base de données SQL sur une machine qui promet des performances adéquates. Il existe des moyens très connus et bien compris de faire ces choses, et bien qu'ils ne garantissent pas une sécurité absolue ou des performances idéales, rien d'autre ne fait rien d'autre.

L'affirmation selon laquelle nous n'avons plus besoin de SQL parce que nous avons maintenant des SSD est juste spécieuse. SQL n'a pas été inventé parce que les disques durs à haute vitesse n'existaient pas encore; il a été inventé parce que nous avions besoin d'un moyen standard pour exprimer des concepts de récupération de données. Les systèmes de bases de données relationnelles ont de nombreuses autres qualités que la vitesse et la sécurité qui les rendent idéales pour les opérations commerciales; en particulier, ACIDE . L'intégrité des données est au moins aussi importante que la vitesse ou la sécurité, et si vous ne les avez pas, quel est l'intérêt de sécuriser les mauvaises données ou de les récupérer le plus rapidement possible?

Avant de prendre l'hystérie d'un homme comme un évangile, je vous suggère de vous renseigner sur la sécurité et les performances des applications et des systèmes selon leurs propres termes, pas en lisant des articles Internet aléatoires. La sécurité, les performances et la conception de système robuste ne se limitent pas à "éviter cette technologie".

Nous n'interdisons pas les couteaux de cuisine car quelques malheureux parviennent à se couper accidentellement les doigts avec.

57
Robert Harvey

Que dit-il réellement?

Dit-il remplacer SQL par des technologies sans SQL?

TL; DR: Oui (en quelque sorte)

Dans un discours plus récent que celui auquel vous avez fait un lien sur le même sujet, il dit: "La base de données est un détail. Pourquoi avons-nous des bases de données?" .

Il prétend que la base de données visait à faciliter l'accès aux données des disques en rotation, mais à l'avenir "[...] il n'y aura pas de disques" grâce à la nouvelle technologie et à ce qu'il appelle la "RAM persistante" et qu'il sera plus facile de stocker des données à l'aide des structures utilisées par les programmeurs, telles que des tables de hachage ou des arbres.

Il continue de prédire que les bases de données relationnelles dans leur ensemble disparaîtront largement en raison de leur nouvelle concurrence:

Si j'étais Oracle, j'aurais assez peur parce que la raison de mon existence s'évapore sous moi. [...] La raison pour laquelle la base de données existe est en train de disparaître.

Il y aura probablement des tables relationnelles qui survivent, mais maintenant il y a une saine concurrence .

Donc non, pour lui, il ne s'agit pas seulement d'injection SQL, bien qu'il soit d'avis SQL est intrinsèquement défectueux à cet égard .


Note de l'auteur:

Les déclarations dans ce post ne sont que des citations pour comprendre le point de vue de Robert C. Martin sur ce sujet et ne représentent pas l'opinion de l'auteur. Pour un point de vue plus différencié, voir réponse de Robert Harvey .

16
Søren D. Ptæus

SQL est un détail. La connaissance d'un détail ne doit pas se propager.

Comme SQL est utilisé de plus en plus dans votre code, votre code en dépend de plus en plus.

Au fur et à mesure que vous apprenez de plus en plus d'astuces SQL, vous résolvez de plus en plus de problèmes en utilisant SQL. Cela signifie que le passage à une autre API pour persister implique plus que la simple traduction. Vous devez résoudre des problèmes que vous ne saviez pas que vous aviez.

Vous rencontrez ce même basculement entre les bases de données. L'un offre la fonctionnalité 5 de fantaisie whizzbang, vous ne l'utilisez donc qu'à plusieurs endroits uniquement pour découvrir que la fonction 5 de fantaisie whizzbang est propriétaire et vous avez maintenant un problème de licence qui va coûter beaucoup d'argent. Donc, vous faites beaucoup de travail en fouillant partout où vous avez utilisé la fonctionnalité 5 et en résolvant le problème par vous-même pour découvrir plus tard que vous utilisez également la fonctionnalité whizzbang 3.

L'une des choses qui rend Java si portable est que certaines fonctionnalités du CPU ne sont tout simplement pas disponibles. S'ils étaient disponibles, je les utiliserais. Et soudainement, il y a des CPU sur lesquels mon code Java ne fonctionnera pas car ils n'ont pas ces fonctionnalités. C'est la même chose avec les fonctionnalités de base de données.

Il est facile de sacrifier votre indépendance sans vous en rendre compte. SQL n'est pas un choix donné. Si vous décidez d'utiliser SQL, faites-le au même endroit. Faites-le d'une manière qui peut être défaite.

Le fait que SQL ait des problèmes de sécurité et que nous passions à des modèles de mémoire persistante ne signifie pas que SQL est condamné. Cela ramène à la maison le point que c'est un choix. Si vous voulez conserver le droit de faire ce choix, vous devez faire le travail.


Il convient de noter que le mouvement de la base de données des années 80 et l'oncle Bob ont une histoire plutôt désagréable. Il avait résolu tous ses problèmes avec un système de fichiers plat lorsque la direction a forcé un administrateur de base de données dans sa vie. Cet événement l'a poussé dans sa brillante carrière de consultant. (Il raconte cette histoire dans l'un de ses premiers livres propres, oubliez lequel) Il sait comment résoudre les problèmes sans DB et a peu de patience pour ceux qui agissent comme si les utiliser était une évidence.

Il raconte également une histoire sur le report de l'ajout d'une base de données à une application jusqu'à la dernière minute lorsqu'un client l'a demandé, et l'a ajouté en une journée en tant que fonctionnalité facultative. Je suppose qu'il voit la façon dont la plupart d'entre nous utilisent les DB comme une dépendance. Il essaie de nous montrer comment arrêter cette habitude.

11
candied_orange

La citation de votre première citation est (c'est moi qui souligne),

La solution. La seule solution. C'est éliminer complètement SQL du système . S'il n'y a pas de moteur SQL, il ne peut y avoir aucune attaque SQLi.

Qu'est-ce qui remplacerait SQL? Une API bien sûr! Et PAS une API qui utilise un langage textuel. Au lieu de cela, une API qui utilise un ensemble approprié de structures de données et d'appels de fonction pour accéder aux données nécessaires.

La diatribe ne permet pas aux programmeurs d'applications d'utiliser SQL.

Le correctif suggéré est de les laisser utiliser une API à la place: ce qui n'est pas SQL et ne permet pas l'injection.

OMI, des exemples de telles API peuvent inclure:

  • http://bobby-tables.com/csharp suggère que les programmeurs C # peuvent utiliser l'API ADO.NET.

    Ce n'est pas un exemple parfait car ADO.NET est une API large ou profonde (c'est-à-dire puissante ou polyvalente), qui aussi permet à ses utilisateurs d'entrer du SQL brut (ou raw-ish).

  • Certains développeurs SQL ou administrateurs de bases de données suggèrent qu'une base de données doit être configurée de manière à n'autoriser l'accès que via (un nombre limité de procédures écrites) procédures stockées , et que les développeurs d'applications ne devraient pas être autorisés à écrire leur propres requêtes SQL (dangereuses)

  • Une autre façon "d'éliminer SQL du système" consiste à placer la base de données (qui expose SQL) sur un système autre, accessible via un REST ou similaire .

Ainsi, l'OMI, la solution globale ou le système [s] peut toujours utiliser une base de données (en particulier étant donné qu'un moteur de base de données implémente des propriétés ACID utiles, et évolue bien et ainsi de suite, il peut être stupide d'essayer de s'en passer ou d'écrire une application spécifique).

Les exigences de la diatribe sont satisfaites si l'API SQL de la base de données est cachée aux développeurs d'applications, derrière une autre API (par exemple ADO, peut-être un ORM, un service Web ou autre).

Plus généralement, je suppose que cela signifie avoir un DAL spécifique à l'application (une "couche d'accès aux données" ou une "couche d'abstraction de base de données"). Un DAL isole l'application des détails sur comment et où les données sont stockées et/ou récupérées. Le DAL peut ou non être implémenté à l'aide d'une base de données SQL.

5
ChrisW

Tout le monde semble répondre à cette question du point de vue de la sécurité ou avec une lentille SQL.

J'ai vu une conférence de Robert Martin où il raconte qu'en tant que programmeurs, nous utilisons de nombreuses structures de données différentes qui sont optimales pour nos programmes spécifiques. Ainsi, plutôt que de stocker universellement toutes les données dans une structure tabulaire, nous devrions stocker nos données dans des tables de hachage, des arbres, etc. afin que nous puissions saisir les données et sauter directement dans le programme.

J'ai interprété son message comme disant seulement que nous devrions jeter nos hypothèses actuelles sur le stockage persistant pendant un moment pour envisager d'autres possibilités futures que le vieux format tabulaire SQL. Le SSD est une solution candidate, mais pas la seule.

3
Keenan

Réponse

veut-il simplement que les gens cessent d'utiliser les bases de données SQL/relationnelles à cause des attaques SQLi?

L'article "Bobby Tables" semble suggérer que cela, en soi, est une raison de ne pas utiliser SQL:

La solution. La seule solution. Est d'éliminer complètement SQL du système. S'il n'y a pas de moteur SQL, il ne peut y avoir aucune attaque SQLi.

Il pourrait avoir d'autres raisons qu'il discute ailleurs. Je ne le saurais pas parce que je ne lis pas vraiment beaucoup de ses trucs.

Digression

Cette partie n'est pas vraiment une réponse, mais je pense que la question de la valeur de SQL est beaucoup plus intéressante (comme d'autres, apparemment.)

J'ai beaucoup d'expérience avec SQL et je pense avoir une bonne compréhension de ses forces et de ses faiblesses. Mon sentiment personnel est qu'il a été abusé et abusé, mais que l'idée que nous ne devrions jamais l'utiliser est un peu idiot. L'idée que nous devons choisir "SQL toujours" ou "SQL jamais" est une fausse dichotomie.

Pour autant que l'injection SQL soit un argument pour ne pas utiliser SQL, c'est risible. C'est un problème bien compris avec une solution assez simple. Le problème avec cet argument est que SQLi n'est pas la seule vulnérabilité qui existe. Si vous pensez que l'utilisation des API JSON vous rend sûr, vous êtes surpris.

Je pense que chaque développeur devrait regarder cette vidéo intitulé "Vendredi 13: Attaquer JSON - Alvaro Muñoz & Oleksandr Mirosh - AppSecUSA 2017"

Si vous n'avez pas le temps ou l'envie de le parcourir, voici l'essentiel: de nombreuses bibliothèques de désérialisation JSON ont des vulnérabilités d'exécution de code à distance. Si vous utilisez XML, vous avez encore plus à vous soucier. L'interdiction de SQL de votre architecture ne sécurisera pas votre système.

2
JimmyJames

Le problème de Martin semble être avec les programmeurs qui construisent du SQL dynamique directement à partir de l'entrée utilisateur, quelque chose comme (pardonnez-moi, je suis principalement un programmeur C et C++):

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

qui est absolument une recette pour les brûlures d'estomac (d'où la bande Bobby Tables ). Tout programmeur qui met du code comme ça dans un système de production mérite un paddlin '.

Vous pouvez atténuer (sinon éliminer complètement) le problème en utilisant des instructions préparées et en nettoyant correctement vos entrées. Si vous pouvez masquer le SQL derrière une API de sorte que les programmeurs ne construisent pas directement des chaînes de requête, tant mieux (ce qui fait partie de ce que préconise Martin).

Mais pour ce qui est de se débarrasser complètement de SQL, je ne pense pas que ce soit pratique ou souhaitable. Les modèles relationnels sont utiles , c'est pourquoi ils existent en premier lieu, et SQL est probablement la meilleure interface pour travailler avec des modèles relationnels.

Comme toujours, il s'agit d'utiliser le bon outil pour le travail. Si votre application de panier d'achat n'a pas besoin d'un modèle relationnel complet, n'utilisez pas de modèle relationnel (ce qui signifie que vous n'aurez pas besoin de utiliser SQL). Dans les cas où vous avez besoin d'un modèle relationnel, vous allez presque certainement travailler avec SQL.

2
John Bode

Je ne veux aborder qu'une courte déclaration:

Ou veut-il simplement que les gens cessent d'utiliser les bases de données SQL/relationnelles à cause des attaques SQLi?

Non, c'est une fausse hypothèse. Nous ne pouvons pas dire que nous devons cesser d'utiliser des voitures, car elles sont responsables de personnes décédées dans des accidents de voiture. De la même manière, les bases de données SQL/relationnelles (ou toute autre chose dans ce contexte, comme le SGBDR) ne sont pas responsables de la charge utile SQL malveillante qu'un attaquant peut effectuer sur votre application Web. Je suis sûr que l'auteur ne voulait pas dire cela, car il existe un aide-mémoire de prévention des injections SQL à cet effet.

2
Billal Begueradj

En fait, il ne doit pas utiliser les bases de données et SQL - assez explicitement. La première référence est un problème bien connu, la deuxième référence se fait entendre comme une diatribe. Cependant, je l'interprète comme ayant une bonne raison d'utiliser des bases de données et de ne pas utiliser SQL. De mon point de vue, ce n'est même pas un conseil raisonnable.

Malheureusement, l'exemple qu'il utilise est un exemple bien connu avec une solution bien connue qu'il souligne ensuite. Cela se produit généralement lorsqu'un programmeur ne réalise pas ce qu'il fait. Par exemple, construire des chaînes contenant du SQL comme:

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

par opposition à

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

Il s'agit d'un exemple DBI Perl pour le code Ruby on Rails. Le code Rails qu'il fournit est facile à confondre le sûr et le dangereux. Comme beaucoup d'ORM cache ce que le SQL est en dessous et si souvent vous avez affaire à une interface qui construit et exécute le sql pour vous. Cela ne ressemble-t-il pas presque à ce qu'une API ferait pour vous ?

Mon interprétation de la première référence est qu'il suggère que nous devrions remplacer un problème bien connu qui a une solution bien connue.

Il est également regrettable qu'il ne mentionne pas que si cela est fait correctement, cela rendra le code plus facile à écrire et plus lisible, mais s'il est bien fait, il peut en fait être plus difficile à écrire et moins lisible. De plus, il ne mentionne pas que SQL est vraiment très facile à lire et fait ce que vous attendez généralement qu'il fasse.

Il est partiellement correct, finalement nous aurons une mémoire infiniment grande et rapide et un processeur infiniment rapide. Jusqu'à ce que nous nous éloignions de la physique actuelle qui contraint l'informatique, il n'a pas raison.

Oui, le disque en rotation appartient au passé et nous utilisons maintenant des SSD. Les disques fonctionnent avec environ ~ 10 millisecondes par transfert de données, les SSD fonctionnent avec ~ 0,5 millisecondes (500 microsecondes) de temps d'accès aux données. RAM est de l'ordre de 100 nano secondes, les processeurs fonctionnent sur une centaine de pico secondes. C'est la raison pour laquelle nous avons besoin de bases de données. Les bases de données gèrent le transfert de données entre les disques en rotation ou SSD avec mémoire principale L'avènement des SSD n'a pas éliminé le besoin de bases de données.

2
Robert Baron

Les deux sources que vous liez véhiculent des messages différents:

Le billet de blog dit que la logique d'accès aux données ne devrait pas exister sous forme de texte au moment de l'exécution, de peur qu'elle ne soit mélangée avec une entrée utilisateur non approuvée. Autrement dit, le blog condamne l'écriture de requêtes en concaténant des chaînes.

La conférence est différente. La première différence est dans le ton: la conférence spécule et remet en question, mais ne condamne pas. Il ne dit pas que les bases de données sont mauvaises, mais nous met au défi d'imaginer la persistance sans base de données. Il fait valoir qu'au cours des 30 années qui se sont écoulées depuis la généralisation des bases de données relationnelles, de nombreuses choses ont changé et en souligne deux qui pourraient vraisemblablement affecter notre choix de technologie de persistance:

  • l'espace de stockage a été multiplié par environ 1 million - à prix comparables! Par conséquent, il est moins nécessaire de conserver le stockage, et en particulier, il n'est plus nécessaire de le supprimer. En utilisant le stockage à ajouter uniquement, le contrôle d'accès simultané peut être simplifié car les verrous de lecture ne sont pas nécessaires. Cela peut éviter le besoin de transactions.
  • les temps d'accès ont diminué, car la plupart des ensembles de données tiennent désormais dans la RAM, ce qui réduit considérablement la latence de lecture.

Ces circonstances modifiées changent-elles la technologie de persistance optimale? Fait intéressant, l'oncle Bob ne le dit pas - probablement parce qu'il pense qu'aucune réponse ne serait correcte pour tous les programmes. C'est pourquoi il nous met en garde de traiter notre choix de technologie de persistance comme un détail plutôt que de l'enfermer dans des tablettes de pierre et de la transmettre en tant que sagesse reçue à nos pairs.

Existe-t-il des alternatives?

L'écriture d'une logique d'accès aux données sans chaîne est tout à fait possible. Dans Java land, vous pouvez utiliser QueryDSL , où les requêtes sont décrites à l'aide d'une API fluide de type sécurisé générée à partir de votre schéma de base de données. Une telle requête peut se présenter comme suit:

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

Comme vous pouvez le voir, la logique de requête n'est pas exprimée sous la forme d'une chaîne, séparant clairement la structure approuvée de la requête des paramètres non approuvés (et bien sûr, QueryDSL n'inclut jamais les paramètres dans le texte de la requête, mais utilise des instructions préparées pour séparer la requête pour ses paramètres au niveau JDBC). Pour réaliser l'injection SQL avec QueryDSL, vous devez écrire votre propre analyseur pour analyser une chaîne et la traduire dans un arbre de syntaxe, et même si vous le faisiez, vous n'ajouteriez probablement pas de support pour des choses désagréables comme select ... into file. En bref, QueryDSL rend impossible l'injection SQL, et améliore également la productivité du programmeur et augmente la sécurité du refactoring. Empêché le plus grand risque pour la sécurité des applications Web, qui existe depuis assez longtemps pour se reproduire exécution de gags , et stimulé la productivité des développeurs? J'ose dire que si vous écrivez toujours des requêtes sous forme de chaînes, vous vous trompez.

En ce qui concerne les alternatives aux bases de données relationnelles, il est curieux de savoir que le postgres contrôle de concurrence multi-version est exactement le type de structure de données à ajouter uniquement dont parle Oncle Bob, bien qu'il pensait probablement plus à magasins d'événements , et le modèle de sourcing d'événements en général, ce qui correspond aussi bien à la notion de maintien de l'état actuel dans la RAM.

1
meriton