Heim  >  Artikel  >  Backend-Entwicklung  >  Verwendung von sql-parser für die SQL-Syntaxanalyse in PHPMyAdmin

Verwendung von sql-parser für die SQL-Syntaxanalyse in PHPMyAdmin

*文
*文Original
2017-12-23 14:13:073680Durchsuche

Das Schreiben von SQL ist für PHP üblich. Wie kann man also SQL-Anweisungen analysieren, um SQL zu optimieren? SQL-Parser bietet eine solche Funktion, werfen wir einen Blick darauf.

phpMyAdmin ist ein Open-Source-Datenbankverwaltungstool, das im Web läuft und die Verwaltung von MySQL- und MariaDB-Datenbanken unterstützt. Das Programm von phpMyAdmin wird hauptsächlich mit PHP und JavaScript entwickelt. Seine Installation und Verwendung sind relativ einfach und es gibt viele verwandte Einführungen. Heute werde ich eine der Kernkomponenten im Quellcode vorstellen, SQL-Parser.

Einführung in SQL-Parser

Der Hauptzweck der SQL-Parser-Komponente besteht darin, eine lexikalische Analyse und Syntaxanalyse von SQL-Anweisungen durchzuführen und anschließend SQL zu dekonstruieren, zu verarbeiten, zu ersetzen und wieder zusammenzusetzen Anweisungen usw. Anforderungen, und Sie können auch eine Hervorhebungsverarbeitung in SQL durchführen. sql-parser ist in reiner PHP-Sprache implementiert und eines der wenigen Module im gesamten phpMyAdmin-Quellcode, das eine relativ klare Codestruktur aufweist und den aktuellen PSR-Standardspezifikationen in der PHP-Welt entspricht.

Installation der SQL-Parser-Komponente

Sie müssen PHP, den Git-Client und das Composer-PHP-Paketverwaltungstool im Voraus installieren

margin@margin-MB1:~/tmp$ sudo git clone https://github.com/phpmyadmin/sql-parser.git
margin@margin-MB1:~/tmp$ cd sql-parser && sudo composer install

Die Komponente wird installiert Details werden unten vorgestellt. Rufen Sie

auf, um gewöhnliche Anweisungen zu analysieren.

require_once '../sql-parser/vendor/autoload.php';
use SqlParser\Parser;
$query = 'SELECT * FROM t1 LEFT JOIN (t2, t3, t4) '
    . 'ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)';
$parser = new Parser($query);
$stmt = $parser->statements[0];
echo json_encode($stmt);

Die Variable $parser im laufenden Ergebnis ist ein großes Objekt, das die lexikalischen Analyseergebnisse der $query-Anweisung speichert $query->list, Syntaxanalyse, Ergebnisse von $query-Anweisungen und Fehlermeldungen usw.
Die Struktur von $query-Anweisungen ist wie folgt:

{"expr":
[{"database":null,"table":null,"column":null,"expr":"*","alias":null,"function":n
ull,"subquery":null}],"from":
[{"database":null,"table":"t1","column":null,"expr":"t1","alias":null,"function":
null,"subquery":null}],"partition":null,"where":null,"group":null,"having":null,"
order":null,"limit":null,"procedure":null,"into":null,"join":
[{"type":"LEFT","expr":{"database":null,"table":null,"column":null,"expr":"(t2, 
t3, t4)","alias":null,"function":null,"subquery":null},"on":[{"identifiers":
["t2","a","t1"],"isOperator":false,"expr":"(t2.a=t1.a"},{"identifiers":
[],"isOperator":true,"expr":"AND"},{"identifiers":
["t3","b","t1"],"isOperator":false,"expr":"t3.b=t1.b"},{"identifiers":
[],"isOperator":true,"expr":"AND"},{"identifiers":
["t4","c","t1"],"isOperator":false,"expr":"t4.c=t1.c)"}],"using":null}],"union":
[],"options":{"options":[]},"first":0,"last":50}


Transaktion analysieren

require_once '../sql-parser/vendor/autoload.php';
use SqlParser\Parser;
$query = 'START TRANSACTION;' .
    'SELECT @A:=SUM(salary) FROM table1 WHERE type=1;' .
    'UPDATE table2 SET summary=@A WHERE type=1;' .
    'COMMIT;';
$parser = new Parser($query);
$stmt = $parser->statements[0];
echo json_encode($stmt);

Ausgabeergebnis:

{"type":1,"statements":[{"expr":
[{"database":null,"table":null,"column":null,"expr":"@A:=SUM(salary)","alias":nul
l,"function":"SUM","subquery":null}],"from":
[{"database":null,"table":"table1","column":null,"expr":"table1","alias":null,"fu
nction":null,"subquery":null}],"partition":null,"where":[{"identifiers":
["type"],"isOperator":false,"expr":"type=1"}],"group":null,"having":null,"order":
null,"limit":null,"procedure":null,"into":null,"join":null,"union":[],"options":
{"options":[]},"first":1,"last":19},{"tables":
[{"database":null,"table":"table2","column":null,"expr":"table2","alias":null,"fu
nction":null,"subquery":null}],"set":[{"column":"summary","value":"@A"}],"where":
[{"identifiers":
["type"],"isOperator":false,"expr":"type=1"}],"order":null,"limit":null,"options"
:{"options":[]},"first":20,"last":35}],"end":
{"type":2,"statements":null,"end":null,"options":{"options":
{"1":"COMMIT"}},"first":36,"last":37},"options":{"options":{"1":"START 
TRANSACTION"}},"first":0,"last":0}

Zusätzlich zu den beiden oben genannten Anweisungen unterstützt SQL-Parser auch das Parsen gespeicherter Prozeduren und fast aller MySQL-Syntax. Ich werde keine Beispiele einzeln nennen. Das Folgende ist ein Beispiel für die Verwendung seines SQL-Konstruktors.

SQL-Anweisung assemblieren

SELECT-Anweisung assemblieren:

require_once '../sql-parser/vendor/autoload.php';
use SqlParser\Components\OptionsArray;
use SqlParser\Components\Expression;
use SqlParser\Components\Condition;
use SqlParser\Components\Limit;
use SqlParser\Statements\SelectStatement;
$stmt = new SelectStatement();
$stmt->options = new OptionsArray(array('DISTINCT'));
$stmt->expr[] = new Expression('sakila', 'film', 'film_id', 'fid');
$stmt->expr[] = new Expression('COUNT(film_id)');
$stmt->from[] = new Expression('', 'film', '');
$stmt->from[] = new Expression('', 'actor', '');
$stmt->where[] = new Condition('film_id > 10');
$stmt->where[] = new Condition('OR');
$stmt->where[] = new Condition('actor.age > 25');
$stmt->limit = new Limit(1, 10);
var_dump($stmt->build());

Ausgabeergebnis:

margin@margin-MB1:~/code/parserTest$ php build.php 
string(137) "SELECT DISTINCT `sakila`.`film`.`film_id` AS `fid`, COUNT(film_id) 
FROM `film`, `actor` WHERE film_id > 10 OR actor.age > 25 LIMIT 10, 1 "

Trigger-Anweisung assemblieren:

require_once '../sql-parser/vendor/autoload.php';
use SqlParser\Components\Expression;
use SqlParser\Components\OptionsArray;
use SqlParser\Statements\CreateStatement;
$stmt = new CreateStatement();
$stmt->options = new OptionsArray(array('TRIGGER'));
$stmt->name = new Expression('ins_sum');
$stmt->entityOptions = new OptionsArray(array('BEFORE', 'INSERT'));
$stmt->table = new Expression('account');
$stmt->body = 'SET @sum = @sum + NEW.amount';
var_dump($stmt->build());


Ausgabeergebnis:

margin@margin-MB1:~/code/parserTest$ php build.php 
string(89) "CREATE TRIGGER ins_sum BEFORE INSERT ON account FOR EACH ROW SET @sum 
= @sum + NEW.amount"

SQL-Neuverarbeitung

Mehrere Anweisungen zusammen verarbeitet:

require_once '../sql-parser/vendor/autoload.php';
use SqlParser\Parser;
use SqlParser\Components\Expression;
$query  = <<<str id="3" from="" change="" $statement_0="$parser-" 处理第一条语句="" parser($query);="" $parser="new" str;="" where="" tbl3="" *="" select="" null;="" not="" unsigned="" )="" 10="" int(="" `field_2`="" `field_1`="" `tbl`="" table="" alter="" auto_increment;="" null="" `uid`="">statements[0];
$statement_0->table  = new Expression(
    &#39;db2&#39;, &#39;tb2&#39;, &#39;&#39;
);
var_dump($statement_0->build());
//处理第二条语句
$statement_1 = $parser->statements[1];
$statement_1->table  = new Expression(
    &#39;db3&#39;, &#39;tb3&#39;, &#39;&#39;
);
var_dump($statement_1->build());</str>

Ausgabeergebnisse:

margin@margin-MB1:~/code/parserTest$ php build.php 
string(85) "ALTER TABLE `db2`.`tb2` CHANGE `uid` `uid` INT( 10 ) UNSIGNED NOT 
NULL AUTO_INCREMENT"
string(78) "ALTER TABLE `db3`.`tb3` CHANGE `field_1` `field_2` INT( 10 ) UNSIGNED 
NOT NULL"

Die oben genannten sind einige grundlegende Anwendungsbeispiele der SQL-Parser-Komponente von phpMyAdmin. Dieser Artikel kann aufgrund von Platzbeschränkungen nicht erschöpfend sein Code, um eine fortgeschrittenere Verwendung zu erlernen.

Verwandte Empfehlungen:

Einige Vorgänge zur MySQL-Optimierung

MySQL-Optimierung (3) Clustered-Index und Nicht-Clustered-Index

Detaillierte grafische Code-Einführung in MySQL-SQL-Optimierungstechniken

Das obige ist der detaillierte Inhalt vonVerwendung von sql-parser für die SQL-Syntaxanalyse in PHPMyAdmin. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn