Es gibt einige architektonische Hindernisse für intelligentere Abfragesprachen in einem Datenbankmanager. Das Haupthindernis ist der Abfrageoptimierer. Eine der Entwurfseinschränkungen von SQL besteht darin, dass nur Konstrukte verwendet werden können, die für den Abfrageoptimierer zugänglich sind. Das bedeutet, dass die Sprache und ihre Fähigkeiten ziemlich eng an die Fähigkeiten der Abfrageausführungsmaschine und des Abfrageplanoptimierers gekoppelt sind.
Die andere wichtige Designbedingung ist die mechanische Natur des Datenbanksystems - Datenbankprogrammierung ist fast einzigartig, da sie eine mechanische Komponente hat. Die Abfrageleistung wird durch die mechanischen Zwänge der Plattenkopfsuche und die Rotationslatenz (die Wartezeit, bis die gewünschten Daten unter den Köpfen ankommen) begrenzt.
Dies schließt viele clevere Abstraktionen aus, die SQL leistungsfähiger oder einfacher zu handhaben machen könnten. Viele Datenbankverwaltungssysteme ergänzen SQL durch prozedurale Alternativen, die für die Skripterstellung verwendet werden können. Sie interagieren jedoch mit dem DBMS durch Sie interagieren jedoch mit dem DBMS, indem sie eine Reihe von SQL-Abfragen ausführen, die vom Optimierer einzeln verarbeitet werden. Einige Sprachen dieser Art, die mit verschiedenen DBMS-Plattformen ausgeliefert werden, sind:
-
Oracle's PL/SQL y eingebettetes Java . PL/SQL ist eigentlich auf Ada basiert - es ist ziemlich nach modernen Maßstäben ziemlich 'old school' und hat eine Legacy-Code-Basis, mit der es abwärtskompatibel bleiben muss. Es ist nicht unbedingt die angenehmste Programmierumgebung, aber sie hat Konstrukte für Einrichtungen wie Parallelität und ein einigermaßen flexibles Typensystem. Einer der größten Kritikpunkte an Java Stored Procedures an Oracle ist, dass Sie für die Oracle's kapazitätsbasierte Lizenzierung auf der CPU, auf der Sie die JVMs ausführen ausführt.
-
SQL-Server CLR-Integration . Ähnlich wie bei Oracles Java Stored Procedures, ermöglicht dies CLR Module, die aus C# (oder einer anderen .net Sprache) in eine SQL Server-Instanz geladen werden Instanz geladen und in ähnlicher Weise wie wie gespeicherte Prozeduren. SQL Server hat auch PostgreSQL-ähnliche APIs zur Erstellung benutzerdefinierte Aggregatfunktionen durch CLR Integration und andere Hooks für gemischte SQL/CLR-Codebasen.
-
PostgreSQL ist eigentlich die System, in dem die Back-End-Sprach Integration ursprünglich entwickelt wurde. Das System exportiert eine native C-API mit Einrichtungen für benutzerdefinierte Aggregatfunktionen, Speicher Speicher-Engines, prozedurale Erweiterungen und andere Funktionalität. Die Sprachschnittstellen basieren auf dieser API und umfassen: PL/pgSQL (eine maßgeschneiderte Sprache ähnlich ähnlich wie PL/SQL), Python , Perl y Tcl .
Dies schaffte es in die Mainstream durch Illustra , a kommerzialisierte Version von Postgres, das dann von Informix aufgekauft wurde Informix aufgekauft (das später von von IBM aufgekauft wurde). Die wichtigsten Funktionen wurden übernommen in Informix-Online das ist immer noch von IBM verkauft wird.
Eine wesentliche Einschränkung dieser Sprachen ist ihre begrenzte Interaktion mit dem Query Optimierer (obwohl die C-API für PostgreSQL dies unterstützt). Teilnahme an einem Abfrageplan als Bürger erster Klasse erfordert, dass der Abfrageoptimierer eine vernünftige Sicht der Ressourcen, die Ihre Aktion in Anspruch nehmen wird, ausarbeiten kann. In der Praxis ist diese Art der Interaktion mit dem Abfrageoptimierer hauptsächlich für die Implementierung von Speicher-Engines nützlich.
Dieser Grad an Eingriffen in die Speicher-Engine ist (a) etwas esoterisch, wenn die Funktionalität überhaupt zur Verfügung steht (so dass die meisten Leute nicht die Fähigkeit haben, dies zu tun) und (b) wahrscheinlich erheblich mühsamer als das einfache Schreiben der Abfrage in SQL. Die Beschränkungen des Abfrageoptimierers bedeuten, dass man mit SQL wahrscheinlich nie den Grad an Abstration erreichen wird, den man mit (sagen wir) Python oder sogar C# oder Java erreichen könnte.
Der Weg des geringsten Widerstands für effiziente Abfragen ist wahrscheinlich der die Abfrage in SQL mit einigen prozeduralen Elementen in einer der anderen Sprachen zu schreiben. In manchen Fällen eignet sich eine Berechnung wirklich für einen prozeduralen Ansatz.
Dies kann zu einem Problem werden und zu großen Mengen an Standard-SQL-Code führen. Die einzigen wirklichen Optionen hierfür sind handcodiertes SQL oder Systeme zur Codegenerierung. Ein triviales Beispiel für die Codegenerierung ist die von Frameworks bereitgestellte CRUD-Funktionalität, bei der dieser SQL-Code aus Metadaten generiert wird. Ein komplexeres Beispiel findet sich in ETL-Tools wie Oracle Warehouse Builder o Wherescape Rot die große Mengen an gespeichertem Prozedurcode aus dem Modell generieren.
Genau aus diesem Grund baue ich halbwegs regelmäßig die eine oder andere Art von Codegenerierungssystem. Jedes Templating-System ist dafür geeignet - ich habe ziemlich gute Erfahrungen gemacht mit CherryTemplate aber es gibt viele solcher Gegenstände. Codegenerierung in Aktion ist ein recht gutes Buch zu diesem Thema - der Autor verwendet ein Ruby-basiertes System, dessen Name mir nicht einfällt.
Edit: Wenn Sie sich einen "Show Estimated Execution Plan" für einen Block von prozeduralem Code ansehen, werden Sie feststellen, dass jede Anweisung ihren eigenen Abfrageplan hat. Der Algorithmus zur Abfrageoptimierung kann nur eine einzige SQL-Anweisung bearbeiten, so dass eine Prozedur einen ganzen Wald von Abfrageplänen hat. Da prozeduraler Code ' Nebeneffekte ' können Sie die Art der Algorithmen die bei der Abfrageoptimierung verwendet werden, um Rückschlüsse auf den Code zu ziehen. Dies bedeutet, dass ein Abfrageoptimierer einen Block von prozeduralem Code nicht global optimieren kann. Er kann nur einzelne SQL-Anweisungen optimieren.