None

13 Gründe gegen SQL

Zeit, SQL über Bord zu werfen (?)
Foto: Vector Artworks | shutterstock.com




Seiner Popularität und seinem Erfolg zum Trotz, ist die Datenbanksprache SQL ein Paradoxon. Sie kann unglaublich umständlich und langatmig sein – dennoch stellt sie für Developer oft den einfachsten Weg dar, ohne Umwege die Daten zu extrahieren, die sie benötigen (falls die Abfrage korrekt geschrieben ist).



Das tabellarische SQL-Modell ist dabei so dominant, dass auch viele Nicht-SQL-Projekte auf Wunsch der Benutzer SQL-ähnliche Schnittstellen hinzufügen. Das gilt auch für Projekte im Bereich NoSQL, der eigentlich geschaffen wurde, um sich vom alten Paradigma zu lösen (das war wohl nichts). Fakt ist allerdings auch: Die Probleme von SQL sind real und:




erhöhen den Stress für Entwickler,



führen unter Umständen zu Verzögerungen, und



bei manchen Projekten sogar zum Reengineering.




In diesem Artikel nennen wir Ihnen 13 Gründe, die dafür sprechen würden, SQL endlich über Bord zu werfen – auch wenn wir alle wissen, dass das wohl nie (vollumfänglich) passieren wird.



1. Tabellen skalieren nicht



Das relationale Datenbankmodell von SQL fokussiert auf Tabellen. Was für kleine oder normal große Datenbanken auch in Ordnung ist. Im Fall von großen DBs beginnt das SQL-Modell allerdings in sich zusammenzubrechen.



Das versuchen manche zu verhindern, indem sie beispielsweise Sharding in ältere Open-Source-Datenbanken integrieren. Das kann das Datenmanagement vereinfachen und bietet eine vermeintlich grenzenlose Skalierung. Allerdings kann ein JOIN– oder SELECT-Befehl mitunter auch extrem lange dauern – je nachdem, wie viele Daten die Shards beinhalten.



2. JSON? YAML? XML?



SQL mag ein Dauerbrenner sein, verträgt sich aber nicht besonders gut mit neueren Datenaustauschformaten wie JSON, YAML und XML. Es ist zwar relativ einfach, dieses Problem mit ein bisschen Klebstoff-Code zu übertünchen – das bezahlen Entwickler allerdings mit einem erhöhten Zeitaufwand.



Manche SQL-Datenbanken sind inzwischen auch in der Lage, JSON, XML, GraphQL oder YAML als native Funktionen zu kodieren und zu dekodieren. Das Problem dabei: Die Daten werden in der Regel nach demselben alten Tabellenmodell gespeichert und indiziert – bleiben also im Kern dem relationalen Ansatz verhaftet.



So lange, bis irgendein cleverer Datenbankentwickler einen Weg findet, den Zeitaufwand für die Datenkonvertierung zu eliminieren, gibt es wohl nur einen (schlechten) Ausweg: den SQL Parser.



3. Marhsalling frisst Zeit



SQL-Datenbanken speichern Informationen im Tabellenformat ab. Das stellt Developer vor Probleme, denn der Code, den sie schreiben, arbeitet mit Objekten.



Der Prozess, die strukturierten Daten in das Objektformat zu überführen, wird Marshalling genannt – und verschlingt Unmengen an Zeit. Schließlich müssen die Datenfelder des Objekts im Rahmen eines Demarshaling-Prozesses auch wieder in einem SQL-Upsert freigegeben werden. Ein unmittelbar einsetzbares Datenformat wäre an dieser Stelle ein echter Fortschritt.



4. Echtzeit entfällt



Das SQL-Konzept hat bereits einige Jahrzehnte auf dem Buckel und stammt aus einer Zeit, in der man Datenbanken isoliert betrachtete. Ursprünglich waren SQL-DBs deshalb für Stapelverarbeitung und Interactive Mode konzipiert. Das Konzept von Streaming-Daten und langen Verarbeitungs-Pipelines passt nicht wirklich in diese alte Welt.



Denn wie ein Guru auf einem Datenberg zu thronen, ist kein Konzept für moderne Applikationen: Sie erfordern immer öfter Echtzeit-Performance. Die Datenbanken, die für diese neue Welt konzipiert sind, stellen höchste Anforderungen an Geschwindigkeit und Reaktionsfähigkeit. Aufwendige SQL-Abfragen, die alles zum Stillstand bringen, sind hier fehl am Platz.



5. JOINs sind schmerzintensiv



Die große Stärke von relationalen Datenbanken besteht darin, Daten in kleinere, übersichtlichere Tabellen aufzuteilen. Das bereitet vor allem im Nachgang regelmäßig Kopfzerbrechen, vor allem wenn entsprechende Datenmengen vorliegen und diese mit JOINs zusammengeführt werden sollen.



JOINs an sich sind schon unfassbar verwirrend – den Unterschied zwischen einem “inner” und einem “outer” JOIN zu verstehen, ist dabei nur der erste Schritt. Geht es darum, den besten Weg zu identifizieren, um mehrere JOINs miteinander zu verknüpfen, steigt das Schmerz-Level regelmäßig auf unerträglich. Interne Optimizer (dazu später mehr) können an dieser Stelle helfen – allerdings nur, wenn keine besonders komplexen Kombinationen gefordert sind.



6. Problembehaftete Spalten



Eine große Errungenschaft der NoSQL-Bewegung: den Benutzern mehr Freiheit zu ermöglichen. Einen neuen Wert zu einem Datenbankeintrag hinzuzufügen, funktioniert über Columns (Spalten) – mit beliebigen Tags und Namen. Es besteht keine Notwendigkeit, dafür das Schema zu aktualisieren.



Für SQL-Verfechter ist dies Konzept-gewordenes Chaos. Sie legen Wert auf die Ordnung, die Daten in Tabellenform vermitteln. Spontan neue Felder hinzuzufügen, ist für sie ein Unding. Das ist ein guter Punkt – allerdings kann es ziemlich teuer und zeitaufwändig sein, Daten “komplett” nachträglich hinzuzufügen – insbesondere bei umfangreichen Datensätzen. Will man die neuen Daten in separate Spalten einfügen und sie mit JOINs abgleichen, wird das Ganze noch komplexer.



7. Wenn Optimizer nicht mehr helfen



Um Datenbankabfragen bestmöglich zu zerlegen und die einzelnen Prozesse zu ordnen, haben Datenbank-Anbieter und -Entwickler Optimizer entwickelt. Diese können beträchtliche Vorteile realisieren – allerdings sind ihre Möglichkeiten begrenzt, wenn es darum geht, besonders umfangreiche oder komplexe Antworten zu liefern.



Das merken manche Datenbankadministratoren erst, wenn ihre Anwendung beginnt zu skalieren. Wenn es für die Testdatensätze im Rahmen der Entwicklung noch gereicht hat, für die Praxis aber nicht, führt das zu Problemen.



8. Denormalisierung macht alles zunichte



Developer finden sich oft zwischen den Stühlen wieder: Auf der einen Seite stehen die User, die sich eine bessere Performance wünschen. Auf der anderen die Erbsenzähler aus der Buchhaltung, die der Anschaffung besserer (und damit meist teurerer) Hardware meist abweisend gegenüberstehen.



Ein gängiger Ausweg besteht darin, Tabellen zu denormalisieren. Das sorgt dafür, dass komplexe JOINs oder tabellenübergreifende Elemente beseitigt werden. Das ist zwar per se keine schlechte technische Lösung – dieses Vorgehen sorgt aber auch dafür, dass die cleversten Parts des SQL-Konzepts über Bord geworfen werden. Eine Datenbank, die einer exzessiven .csv-Datei gleichkommt, fällt sehr wahrscheinlich nicht in die Kategorie “smart”.



9. Plötzlicher Datenbanktod



SQL wird seit Jahrzehnten immer wieder um neue Funktionen erweitert. Einige davon sind auch ziemlich nützlich. Auf der anderen Seite sind viele dieser Funktionen aber auch eher “angeflanscht” – was nicht nur zu Nachteilen, sondern unter Umständen zum kompletten Zusammenbruch der Datenbank führen kann – Stichwort Subqueries.



In den meisten Fällen werden Probleme in diesem Bereich erst erkannt, wenn es bereits zu spät ist. Dann kann in der Regel nur noch ein krisenerprobter SQL-Silverback dabei helfen, den Fehler zu finden, indem er sich durch unzählige Schichten arbeitet.



10. Anfällige Syntax



In der Zeit, in der SQL entstanden ist, war SQL unter menschlichen Benutzern ziemlich angesagt. Heute fügen viele Systeme Abfragen automatisch zusammen, was naiven wie böswilligen Benutzern viel Macht gibt, um Schaden anzurichten. Datenbankadministratoren lernen schnell, bestimmte Schlüsselwörter zu vermeiden. Ein Gelegenheitsnutzer möchte aber vielleicht trotzdem SELECT GROUP als Spalte nutzen. Und dann gibt es noch die wunderbaren Standardlösungen, um Wörter wie SELECT zu umgehen: MySQL verwendet Backticks, PostgreSQL nutzt doppelte Anführungszeichen.



Erschwerend kommt hinzu, dass clevere Angreifer diese Schwachstelle ausnutzen können, indem sie SQL-Befehle in Abfragen einschleusen. Einen Befehl wie ; DROP TABLE users; DROP TABLE products; DROP TABLE orders;-- führt der SQL-Parser bereitwillig aus. Schließlich wurde er ebenfalls in einer Zeit geschrieben, als nur Menschen Abfragen stellten.



11. Tabellen sind nicht alles



Überraschend viele Datensätze lassen sich gut in Tabellen abbilden. Aber eine wachsende Menge passt auch nicht mehr so gut auf diese Form. So werden beispielsweise soziale Netzwerke, hierarchische Daten und viele wissenschaftliche Phänomene mit Graphen modelliert. Diese lassen sich zwar in Tabellen speichern, aber alles, was über eine simple Query hinausgeht, wird komplex.



Andere Daten existieren in zwei, drei oder vielleicht sogar mehreren Dimensionen. Tabellen weisen jedoch nur eine Achse für die Zeilen und eine untergeordnete Achse für die verschiedenen Spalten auf. Zweidimensionale Daten wie Breiten- und Längengrade lassen sich also speichern, mehrdimensionale Berechnungen sind diffizil. Das können neue, geografische Erweiterungen zwar ausgleichen, das Paradigma bleibt allerdings limitierend.



12. Standardisierungsdifferenzen



SQL mag ein ANSI/ISO-Standard sein. Das bedeutet allerdings nicht, dass man es einfach von einer standardkonformen Implementierung auf eine andere übertragen kann. DBAs sind mit den vielfältigen syntaktischen Unterschieden bestens vertraut:




MySQL verwendet CURDATE(),



Oracle SYSDATE, und



PostgreSQL CURRENT_DATE.




In SQL Server können Sie Zeichenfolgen mit dem +-Operator verknüpfen. Andere verlangen ||. Und diese syntaktischen Inkompatibilitäten sind nur der Anfang. Es gibt große philosophische Unterschiede zwischen den Implementierungen von gespeicherten Prozessen, Triggern und unterstützten Funktionen. Selbst die grundlegenden Datentypen weisen in ihren Bereichen Nuancen auf, wenn es um ihre Präzision geht.



13. Es gibt bessere Optionen



Der beste Grund, SQL aufzugeben: Es gibt bessere, prägnantere und flexiblere Alternativen. Etwa GraphQL, das häufig in Webanwendungen zum Einsatz kommt, um mit einem einfachen Muster genau die richtigen Datenkombinationen abzufragen. Hierarchische Daten werden nativ unterstützt.



Für die Suche in NoSQL-Datenbanken stehen bereits mehrere gute, alternative Optionen zur Verfügung. Viele der Key-Value-Speicher suchen dabei einfach nach übereinstimmenden Knoten. Einige ahmen dabei den beliebten JSON-Standard nach, wie etwa die MongoDB Query Language (MQL). Entwickler, die dokumentenzentrische Lösungen wie SOLR oder Elastic Search einsetzen, können komplexe Ähnlichkeitsfunktionen nutzen. Diese Optionen unterstützen Abfragen, die sowohl leistungsfähiger als auch für Menschen leichter zu lesen und zu erstellen sind. (fm)



Dieser Artikel ist im Original bei unserer Schwesterpublikation Infoworld.com erschienen.