百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术流 > 正文

Python/PHP MySQL语句解析器解决业务分表

citgpt 2024-09-26 11:31 8 浏览 0 评论

自己曾经做过一个网盘项目。刚开始由于需要快速地从0到1建设上线,所以没有对核心文档表进行分表。当然我的架构理念也是“按需架构设计”。产品需求在没有明确的长远计划的情况下以“小步快跑,赶超竞品”为主。后期由于产品功能触达目标用户群需求点、产品用户体验不断提升、产品多方位导流、加强产品推广文档表每天有百万数据增长量。不得不对文档表进行按用户id分表。当时产品功能已全覆盖文档的生命周期。产品功能已丰富多彩。修改所有关联文档表的业务代码为按用户id分表开发测试成本非常高。上线后线上问题不可控。经过考虑在业务代码最底层DB层进行SQL语句解析来进行用户id分表处理。这样的话开发测试成本都非常低。上线后有问题方便回滚和追查原因。

今天为大家介绍Python/PHP两种MySQL语句解析器。当时网盘项目用的是PHP编程语言开发。

Python/PHP MySQL语句解析器解决业务分表

Python的SQL语句解析器。个人推荐使用moz_sql_parser库。经调研官方的sqlparse库解析出来的语句段无法满足需求也很难理解。

1、Python moz_sql_parser库安装

pip install moz_sql_parser 

2、Python moz_sql_parser SQL语句解析

from moz_sql_parser import parse
import json

#用例1
sql = 'select id,name from t1 where id > 1'
tree = parse(sql)
print(json.dumps(tree))
执行结果:
{
    "select": [
        {
            "value": "id"
        }, 
        {
            "value": "name"
        }
    ], 
    "from": "t1", 
    "where": {
        "gt": [
            "id", 
            1
        ]
    }
}

 #用例2
sql = 'select id,name from t1 where id > 1 and id < 1'
tree = parse(sql)
print(json.dumps(tree))
 执行结果:
 {
    "select": [
        {
            "value": "id"
        }, 
        {
            "value": "name"
        }
    ], 
    "from": "t1", 
    "where": {
        "and": [
            {
                "gt": [
                    "id", 
                    1
                ]
            }, 
            {
                "lt": [
                    "id", 
                    1
                ]
            }
        ]
    }
}

#用例3
sql = "select id,name from t1 where id in (select id from t2 WHERE content = 'xxxxxx')"
tree = parse(sql)
print(json.dumps(tree))
执行结果:
{
    "select": [
        {
            "value": "id"
        }, 
        {
            "value": "name"
        }
    ], 
    "from": "t1", 
    "where": {
        "in": [
            "id", 
            {
                "select": {
                    "value": "id"
                }, 
                "from": "t2", 
                "where": {
                    "eq": [
                        "content", 
                        {
                            "literal": "xxxxxx"
                        }
                    ]
                }
            }
        ]
    }
}

#用例4 
sql = "select t1.id, t1.name from t1 join t2 on t1.id = t2.id where t2.id > 1"
tree = parse(sql)
print(json.dumps(tree))
执行结果:
{
    "select": [
        {
            "value": "t1.id"
        }, 
        {
            "value": "t1.name"
        }
    ], 
    "from": [
        "t1", 
        {
            "join": "t2", 
            "on": {
                "eq": [
                    "t1.id", 
                    "t2.id"
                ]
            }
        }
    ], 
    "where": {
        "gt": [
            "t2.id", 
            1
        ]
    }
}

3、Python moz_sql_parser总结

    • moz_sql_parser解析出来的结果符合SQL语法格式。
    • moz_sql_parser解析出来的结果适合业务分表的需求(可以取到SQL语句里的表名和WHERE条件)
    • moz_sql_parser解析出来的结果代码二次开发复杂度低。

PHP的SQL语句解析器。个人推荐使用PhpMyAdmin的sql-parser组件。PhpMyAdmin是经过历史检验可信赖的。

1、PHP PhpMyAdmin/sql-parser安装

composer require phpmyadmin/sql-parser 

2、PHP PhpMyAdmin/sql-parser SQL语句解析

<?php
require_once 'vendor/autoload.php';

use PhpMyAdmin\SqlParser\Parser;
$query = 'SELECT t1.id, t1.name FROM t1 LEFT JOIN t2 ON t1.id = t2.id WHERE t2.name = "xxxx"';
$parser = new Parser($query);
$stmt = $parser->statements[0];
var_dump($stmt);
执行结果:
object(PhpMyAdmin\SqlParser\Statements\SelectStatement)#46 (17) {
  ["expr"]=>
  array(2) {
    [0]=>
    object(PhpMyAdmin\SqlParser\Components\Expression)#48 (7) {
      ["database"]=>
      NULL
      ["table"]=>
      string(2) "t1"
      ["column"]=>
      string(2) "id"
      ["expr"]=>
      string(5) "t1.id"
      ["alias"]=>
      NULL
      ["function"]=>
      NULL
      ["subquery"]=>
      NULL
    }
    [1]=>
    object(PhpMyAdmin\SqlParser\Components\Expression)#49 (7) {
      ["database"]=>
      NULL
      ["table"]=>
      string(2) "t1"
      ["column"]=>
      string(4) "name"
      ["expr"]=>
      string(7) "t1.name"
      ["alias"]=>
      NULL
      ["function"]=>
      NULL
      ["subquery"]=>
      NULL
    }
  }
  ["from"]=>
  array(1) {
    [0]=>
    object(PhpMyAdmin\SqlParser\Components\Expression)#50 (7) {
      ["database"]=>
      NULL
      ["table"]=>
      string(2) "t1"
      ["column"]=>
      NULL
      ["expr"]=>
      string(2) "t1"
      ["alias"]=>
      NULL
      ["function"]=>
      NULL
      ["subquery"]=>
      NULL
    }
  }
  ["index_hints"]=>
  NULL
  ["partition"]=>
  NULL
  ["where"]=>
  array(1) {
    [0]=>
    object(PhpMyAdmin\SqlParser\Components\Condition)#54 (3) {
      ["identifiers"]=>
      array(3) {
        [0]=>
        string(2) "t2"
        [1]=>
        string(4) "name"
        [2]=>
        string(4) "xxxx"
      }
      ["isOperator"]=>
      bool(false)
      ["expr"]=>
      string(16) "t2.name = "xxxx""
    }
  }
  ["group"]=>
  NULL
  ["having"]=>
  NULL
  ["order"]=>
  NULL
  ["limit"]=>
  NULL
  ["procedure"]=>
  NULL
  ["into"]=>
  NULL
  ["join"]=>
  array(1) {
    [0]=>
    object(PhpMyAdmin\SqlParser\Components\JoinKeyword)#51 (4) {
      ["type"]=>
      string(4) "LEFT"
      ["expr"]=>
      object(PhpMyAdmin\SqlParser\Components\Expression)#52 (7) {
        ["database"]=>
        NULL
        ["table"]=>
        string(2) "t2"
        ["column"]=>
        NULL
        ["expr"]=>
        string(2) "t2"
        ["alias"]=>
        NULL
        ["function"]=>
        NULL
        ["subquery"]=>
        NULL
      }
      ["on"]=>
      array(1) {
        [0]=>
        object(PhpMyAdmin\SqlParser\Components\Condition)#53 (3) {
          ["identifiers"]=>
          array(3) {
            [0]=>
            string(2) "t1"
            [1]=>
            string(2) "id"
            [2]=>
            string(2) "t2"
          }
          ["isOperator"]=>
          bool(false)
          ["expr"]=>
          string(13) "t1.id = t2.id"
        }
      }
      ["using"]=>
      NULL
    }
  }
  ["union"]=>
  array(0) {
  }
  ["end_options"]=>
  NULL
  ["options"]=>
  object(PhpMyAdmin\SqlParser\Components\OptionsArray)#47 (1) {
    ["options"]=>
    array(0) {
    }
  }
  ["first"]=>
  int(0)
  ["last"]=>
  int(39)
}

3、PHP PhpMyAdmin/sql-parser总结

    • PhpMyAdmin/sql-parser解析出来的结果是面向对象的类。类是根据SQL语法划分。
    • PhpMyAdmin/sql-parser解析出来的结果根据SQL语法来看类的话很清晰。
    • PhpMyAdmin/sql-parser解析出来的结果满足分表SQL语句解析需求。

大家有什么问题可以发评论沟通。


感谢大家的评论、点赞、分享、关注。。。

相关推荐

js中arguments详解

一、简介了解arguments这个对象之前先来认识一下javascript的一些功能:其实Javascript并没有重载函数的功能,但是Arguments对象能够模拟重载。Javascrip中每个函数...

firewall-cmd 常用命令

目录firewalldzone说明firewallzone内容说明firewall-cmd常用参数firewall-cmd常用命令常用命令 回到顶部firewalldzone...

epel-release 是什么

EPEL-release(ExtraPackagesforEnterpriseLinux)是一个软件仓库,它为企业级Linux发行版(如CentOS、RHEL等)提供额外的软件包。以下是关于E...

FullGC详解  什么是 JVM 的 GC
FullGC详解 什么是 JVM 的 GC

前言:背景:一、什么是JVM的GC?JVM(JavaVirtualMachine)。JVM是Java程序的虚拟机,是一种实现Java语言的解...

2024-10-26 08:50 citgpt

使用Spire.Doc组件利用模板导出Word文档
  • 使用Spire.Doc组件利用模板导出Word文档
  • 使用Spire.Doc组件利用模板导出Word文档
  • 使用Spire.Doc组件利用模板导出Word文档
  • 使用Spire.Doc组件利用模板导出Word文档
跨域(CrossOrigin)

1.介绍  1)跨域问题:跨域问题是在网络中,当一个网络的运行脚本(通常时JavaScript)试图访问另一个网络的资源时,如果这两个网络的端口、协议和域名不一致时就会出现跨域问题。    通俗讲...

微服务架构和分布式架构的区别

1、含义不同微服务架构:微服务架构风格是一种将一个单一应用程序开发为一组小型服务的方法,每个服务运行在自己的进程中,服务间通信采用轻量级通信机制(通常用HTTP资源API)。这些服务围绕业务能力构建并...

深入理解与应用CSS clip-path 属性
深入理解与应用CSS clip-path 属性

clip-pathclip-path是什么clip-path 是一个CSS属性,允许开发者创建一个剪切区域,从而决定元素的哪些部分可见,哪些部分会被隐...

2024-10-25 11:51 citgpt

HCNP Routing&Switching之OSPF LSA类型(二)
  • HCNP Routing&Switching之OSPF LSA类型(二)
  • HCNP Routing&Switching之OSPF LSA类型(二)
  • HCNP Routing&Switching之OSPF LSA类型(二)
  • HCNP Routing&Switching之OSPF LSA类型(二)
Redis和Memcached的区别详解
  • Redis和Memcached的区别详解
  • Redis和Memcached的区别详解
  • Redis和Memcached的区别详解
  • Redis和Memcached的区别详解
Request.ServerVariables 大全

Request.ServerVariables("Url")返回服务器地址Request.ServerVariables("Path_Info")客户端提供的路...

python操作Kafka

目录一、python操作kafka1.python使用kafka生产者2.python使用kafka消费者3.使用docker中的kafka二、python操作kafka细...

Runtime.getRuntime().exec详解

Runtime.getRuntime().exec详解概述Runtime.getRuntime().exec用于调用外部可执行程序或系统命令,并重定向外部程序的标准输入、标准输出和标准错误到缓冲池。...

promise.all详解 promise.all是干什么的
promise.all详解 promise.all是干什么的

promise.all详解promise.all中所有的请求成功了,走.then(),在.then()中能得到一个数组,数组中是每个请求resolve抛出的结果...

2024-10-24 16:21 citgpt

Content-Length和Transfer-Encoding详解
  • Content-Length和Transfer-Encoding详解
  • Content-Length和Transfer-Encoding详解
  • Content-Length和Transfer-Encoding详解
  • Content-Length和Transfer-Encoding详解

取消回复欢迎 发表评论: