iamcal / sql-parser
MySQL架构解析器
Requires (Dev)
- php-coveralls/php-coveralls: ^1.0
- phpunit/phpunit: ^5|^6|^7|^8|^9
This package is auto-updated.
Last update: 2024-08-29 17:25:20 UTC
README
这个库接受MySQL的CREATE TABLE
语句并返回一个表示该表的数据结构。支持MySQL语法版本5.7。这个库不尝试验证输入 - 目标是解构有效的CREATE TABLE
语句。
安装
您可以使用composer安装此包。要将它添加到您的composer.json
composer require iamcal/sql-parser
然后您可以使用composer自动加载器来加载它
require_once 'vendor/autoload.php'; use iamcal\SQLParser; $parser = new SQLParser();
如果您不使用composer,您可以直接包含src/SQLParser.php
。
用法
用于提取SQL中定义的表
$parser = new SQLParser(); $parser->parse($sql); print_r($parser->tables);
tables
属性是一个包含表的数组,每个表都是一个嵌套数组结构,定义了表的结构
CREATE TABLE `achievements_counts` ( `achievement_id` int(10) unsigned NOT NULL, `num_players` int(10) unsigned NOT NULL, `date_updated` int(10) unsigned NOT NULL, PRIMARY KEY (`achievement_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
[ 'achievements_counts' => [ 'name' => 'achievements_counts', 'fields' => [ [ 'name' => 'achievement_id', 'type' => 'INT', 'length' => '10', 'unsigned' => true, 'null' => false, ], [ 'name' => 'num_players', 'type' => 'INT', 'length' => '10', 'unsigned' => true, 'null' => false, ], [ 'name' => 'date_updated', 'type' => 'INT', 'length' => '10', 'unsigned' => true, 'null' => false, ], ], 'indexes' => [ [ 'type' => 'PRIMARY', 'cols' => [ [ 'name' => 'achievement_id', ], ], ], ], 'props' => [ 'ENGINE' => 'InnoDB', 'CHARSET' => 'utf8', ], ], ]
您也可以直接使用词法分析器来处理其他SQL片段
$parser = new SQLParser(); $parser->lex($sql); print($parser->tokens);
tokens
属性包含一个包含标记的数组。SQL关键字以大写形式返回,多词术语(例如DEFAULT CHARACTER SET
)作为一个标记。字符串和转义标识符不再进一步处理;它们将按照输入SQL中表达的方式返回。
默认情况下,词法分析器将忽略未结束的注释和字符串,并在该点停止解析,不再产生其他标记。您可以将$parser->throw_on_bad_syntax = true;
设置为抛出一个类型为iamcal\SQLParserSyntaxException
的异常。
性能
我的测试目标是包含Glitch主数据库中114张表的88K SQL文件。
第一个版本,使用php-sql-parser,仅对输入进行词法分析就花费了超过60秒。这显然不是一个好选择。
当前实现使用手动编写的词法分析器,对相同的输入进行词法分析大约需要140毫秒,并且施加的限制较少。这似乎是正确的方法。
历史
这个库是为了解析多个CREATE TABLE
架构并比较它们而创建的,以便找出将一个迁移到另一个所需做的事情。
这是基于在b3ta、Flickr和Tiny Speck使用的系统,用于检查生产数据库和开发数据库以及分片实例之间的差异。原始系统仅显示diff(参见SchemaDiff),但这有点麻烦。
不支持的功能
MySQL表定义有很多选项,所以有些功能根本不支持。包括
UNION
表属性TABLESPACE
表属性- 表分区
FLOAT[(bits)]
字段- 废弃的
YEAR(2|4)
字段 ASCII
属性作为CHARACTER SET latin1
的简写UNICODE
属性作为CHARACTER SET ucs2
的简写- 修改
NATIONAL
以用于CHAR
和VARCHAR
字段
如果您需要支持这些功能之一,请提出一个issue或(更好的)发送带有测试的pull request。
每个字段分组规格的规格可以在以下位置找到
- https://dev.mysqlserver.cn/doc/refman/5.7/en/numeric-type-syntax.html
- https://dev.mysqlserver.cn/doc/refman/5.7/en/date-and-time-type-syntax.html
- https://dev.mysqlserver.cn/doc/refman/5.7/en/string-type-syntax.html
- https://dev.mysqlserver.cn/doc/refman/5.7/en/spatial-type-overview.html
替代方案
如果您使用PHP,那么Modyllic是一个优秀的SQL解析器和一组架构管理工具。
如果您使用Hack,那么Hack SQL Fake 允许您解析SQL并创建一个用于测试的假MySQL服务器,具有MySQL的许多(但不是全部!)功能。
发布
要发布新版本
- 将更改提交到master
- 添加git标签
- 前往https://packagist.org.cn/packages/iamcal/sql-parser并点击“更新”