当前位置: 首页 > 工具软件 > DBProxy > 使用案例 >

BProxy用户使用手册(3)使用教程(2)DBProxy兼容的SQL语法

孙震博
2023-12-01
    1. DBProxy兼容的SQL语法

目前DBProxy兼容绝大多数MySQL语法。但是对于特殊配置、环境下的某些MySQL语法有一定的限制,限制会在本节列出。

      1. SQL语句支持限制
        1. 不支持的语句

序号

不支持的语句

1

lock table(s)

2

flush table with read lock

3

flush table for export

4

lock binlog for backup

5

lock table for backend

6

handleropen/read

7

DDL语句

8

prepare语句

        1. for update限制

select for update 也可能会走从库,使用select for update 必须在显示事务中。

        1. update/delete操作限制

不支持没有where条件的update ,delete操作。

        1. load data限制

目前不支持load data。

        1. set option限制

connector/J 5.1.18之前的驱动会发送该类语句。

      1. 后台DB连接池带来的限制
        1. session级系统变量限制

版本

限制

0.0.1

不支持set session级别的变量,因为后端的连接会重用,除set autocommit外

0.0.2

支持set session级别的变量,仍然有以下限制:
1. 不支持set transaction isolation level
2. 不支持set character set
3. 不支持set collation_connection
4. 不支持set password
5. 不支持set insert_id
6. 不支持用户自定义变量

0.1.0 之后

支持了set transaction isolation level
其他不支持的变量仍旧限制

        1. 获取上下文语句的限制

对于found_rows、row_count以及show warning、select last_insert_id等获取上下文信息的语句,仅在产生该类信息的语句(比如SQL_CALC_FOUND_ROWS语句、insert auto increment等)正确执行后立即执行有效,否则结果无效。

        1. temporary表限制

temporary表的相关操作执行结果可能错误,temporary表在不同的session中查询结果不同。

        1. cur/prepare功能限制

不支持原生的cursor、prepare等功能。

对于prepare语句的处理机制主要有以下两种:

        (1) prepare时不向server端发送prepare命令,而是在execute时生成完成的SQL,直接发往server执行。
        (2) prepare时向server端发送prepare命令,execute时发送execute命令。

        各个驱动中的具体处理机制如下:

        - PHP(PDO):默认为第一种方式,在PDO_ATTR_EMULATE_PREPARES和PDO_MYSQL_ATTR_DIRECT_QUERY都设置为0时,采用第二种方式

        - PHP(mysqli):采用第二种方式

        - JDBC:useServerPrepStmts=false时(默认值),采用第一种方式。

        1. 客户端驱动有关的限制

序号

限制

1

不支持客户端驱动(jdbc、pdo等)直接发送use dbname语句,可通过相应的更改db接口修改(比如Connection.setCatalog())
此限制仅限于0.0.2及之前版本,0.1.0之后的版本没有这个限制

2

不支持客户端驱动执行COM_CHANGE_USER和COM_SET_OPTION命令

        1. 连接属性设置

版本

限制

0.0.1

不支持连接串中设置属性,其中useAffectedRows默认为FALSE

0.0.2

支持连接串中的参数设置,但仍然有以下限制:
1. 不支持CLIENT_COMPRESS
2. 不支持CLIENT_CONNECT_ATTRS
3. 不支持CLIENT_SSL和CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA
4. 不支持CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS
5. 连接协议仅支持CLIENT_PROTOCOL_41
6. 密码验证协议仅支持mysql_native_password协议

0.0.2之后

仍旧继承0.0.2的限制

      1. DBProxy配置方面的限制

序号

限制

1

不能设置多个主库,或者在已有主库再增加主库

2

所有的后端db节点,都需要有相同的用户名及密码

3

配置mysql的IP权限时,必须保证所有用户在DBProxy所在的机器具有权限

      1. 分表的限制

序号

限制

1

where 条件:
1. 在select,update,delete操作分表时,必须有分表键的where条件,不含where条件或者where条件中没有分表键则不会进行分表处理
2. where条件中只考虑分表字段第一次出现的col1=xx或者col1 in (values ...)的情况
3. where 条件是IN操作符,如果查询条件涉及多个分表,DBProxy会对结果进行merge
select * from tbl where col1 in (1,2,3), 如果1在tbl_1,2在tbl_2,3在tbl_3
当前查询相当于select * from tbl_1 where col1 = 1, select * from tbl_2 where col1 = 2, select * from tbl_3 where col1 = 3,并将三个结果集合并后返回
4. where 条件是=操作符,如果分表键出现在多个条件中,只会按照第一次出现的值来求分表名,而不会处理其它条件
示例:select * from tbl where col1 = 1 or col1=2, DBProxy只会选择col1=1来判断

2

不支持range查询

3

Insert操作,如果没有显式的指定列名,则会按照value list的第一个值来计算。比如Insert values(c1,c2,c3),则按照c1来计算分表。如果是多行插入,则只根据第一组数据来选择分表。分表值不能是表达式、函数等

4

InsertBatch操作时,只会根据第一个value进行计算属于哪一张分表,然后把整条SQL直接发到这分表中,不管其余的value是否也属于这个分表
INSERT INTO tbl VALUES(1st), (2nd),(3rd) ,只会按1st进行计算,不会去计算2nd, 3rd

5

update修改分表字段的值时,只会修改值,不会根据修改后的值再对数据进行迁移

6

不支持跨子表查询的Limit、Sort、Group by和Union操作。目前DBProxy只是简单合并转发后台的结果集

7

不支持分表中含有自增列(使用自增列不会报错,但要考虑到各个分表间自增列值重复的问题,例如:自增列不能作为分表键)

8

不支持JOIN语句中含有多个分表

9

如果更新语句涉及到多个子表,则中间某个子表的更新出错,则只回滚当前子表的更新,已成功的子表则不会回滚

 类似资料: