>  기사  >  백엔드 개발  >  PHPMyAdmin에서 SQL 구문 분석을 위해 sql-parser 사용

PHPMyAdmin에서 SQL 구문 분석을 위해 sql-parser 사용

*文
*文원래의
2017-12-23 14:13:073572검색

SQL을 작성하는 것은 PHP에서 흔한 일인데, SQL 문을 분석하여 SQL을 최적화하는 방법은 무엇입니까? sql-parser는 이러한 기능을 제공하므로 살펴보겠습니다.

phpMyAdmin은 웹에서 실행되고 MySQL 및 MariaDB 데이터베이스 관리를 지원하는 오픈 소스 데이터베이스 관리 도구입니다. phpMyAdmin의 프로그램은 주로 PHP와 JavaScript를 사용하여 개발됩니다. 설치 및 사용이 비교적 간단하고 관련 소개가 많이 있으므로 오늘은 소스 코드의 핵심 구성 요소 중 하나인 sql-parser를 소개하지 않겠습니다.

sql-parser 소개

sql-parser 구성 요소의 주요 목적은 SQL 문의 어휘 분석 및 구문 분석을 수행하여 SQL 문의 해체, 처리, 대체 및 재조립을 실현하는 것입니다. 또한 SQL 분석 강조 표시 및 기타 처리도 수행할 수 있습니다. sql-parser는 순수 PHP 언어로 구현되며, 전체 phpMyAdmin 소스 코드에서 상대적으로 명확한 코드 구조를 갖고 있으며 PHP 세계의 현재 PSR 표준 사양을 준수하는 몇 안되는 모듈 중 하나입니다.

sql-parser 컴포넌트 설치

php, git 클라이언트, Composer PHP 패키지 관리 도구를 미리 설치해야 합니다

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

컴포넌트가 설치되고, 구체적인 호출은 아래에 소개됩니다

일반 구문 분석

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);

$parser 실행 결과에서 변수는 $query 문의 어휘 분석 결과 $query->list, 구문 분석 결과 $query-statements, 오류 정보를 저장하는 대형 객체입니다.
$query-statements의 구조는 다음과 같습니다:

{"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}


Parse transaction

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);

출력 결과:

{"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}

위의 두 문 외에도 sql-parser는 저장 프로시저 구문 분석과 거의 모든 MySQL 구문을 지원합니다. .몇 가지 예를 하나씩 들어보세요. 다음은 SQL 생성자의 사용 예입니다.

SQL 문 조합

select 문 조합:

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());

출력 결과:

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 "

트리거 문 조합:

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());


출력 결과:

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 재처리

함께 처리되는 여러 문:

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>

출력 결과 :

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"

위 내용은 sql-parser 구성 요소의 몇 가지 기본 사용 예입니다. phpMyAdmin의 sql-parser 구성 요소는 상대적으로 풍부하고 완전한 기능을 가지고 있습니다. 관심 있는 독자는 공간 제한으로 인해 자세한 내용을 읽을 수 있습니다. 소스 코드. 매우 고급 사용법.

관련 권장 사항:

MySQL 최적화에 대한 일부 작업

mysql 최적화 (3) 클러스터형 인덱스 및 비클러스터형 인덱스

MySql Sql 최적화 기술 사진과 텍스트 자세한 소개 코드에

위 내용은 PHPMyAdmin에서 SQL 구문 분석을 위해 sql-parser 사용의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.