chevere/sql-parser

MySQL模式解析器

0.5.0 2024-01-12 14:39 UTC

This package is auto-updated.

Last update: 2024-09-12 16:15:32 UTC


README

Build Code size Apache-2.0 PHPStan Mutation testing badge

Quality Gate Status Maintainability Rating Reliability Rating Security Rating Coverage Technical Debt CodeFactor

这个库接受MySQL的CREATE TABLE语句并返回一个表示定义的表的数据结构。支持MySQL语法版本5.7。此库不尝试验证输入 - 目标是分解有效的CREATE TABLE语句。

安装

您可以使用composer安装此包。将其添加到您的composer.json

composer require chevere/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使用的系统来检查生产数据库和开发数据库之间以及分片实例之间的差异。原始系统只是显示差异(参见SchemaDiff),但这有点麻烦。

不支持的功能

MySQL表定义有许多选项,所以一些功能根本不支持。包括

  • UNION表属性
  • TABLESPACE表属性
  • 表分区
  • FLOAT[(bits)]字段
  • 废弃的YEAR(2|4)字段
  • ASCII属性作为CHARACTER SET latin1的简称
  • UNICODE属性作为CHARACTER SET ucs2的简称
  • NATIONAL修改了CHARVARCHAR字段

如果您需要支持这些功能之一,请打开一个问题或(更好的是)发送带有测试的pull request。

每个四个字段分组规格可以在以下位置找到

替代方案

如果您正在使用PHP,那么Modyllic是一个出色的SQL解析器和一套模式管理工具。

如果您使用Hack,那么Hack SQL Fake允许您解析SQL并创建一个用于测试的假MySQL服务器,具有MySQL的许多(但不是全部!)功能。

发布

要发布新版本