操作符
GaussDB数据库兼容绝大多数MySQL的操作符,但存在部分差异。如未列出,操作符行为默认为GaussDB原生行为,目前存在MySQL不支持但是GaussDB支持的语句,在MySQL兼容性下,这类语句通常为系统内部使用,因此不建议使用。
操作符差异
- ORDER BY排序对NULL值处理的差异。MySQL在排序时会将NULL值排序在前面;GaussDB默认将NULL值默认排在最后面。GaussDB可以通过NULLS FIRST和NULLS LAST设置NULL值排序顺序。
- 有ORDER BY时,GaussDB输出顺序与MySQL一致。没有ORDER BY时,GaussDB不保证结果有序。
- 使用MySQL操作符时需要用括号表达式严格确保表达式的结合性,否则执行报错。例如:SELECT 1 regexp ('12345' regexp '123');。
- NULL值显示不同。MySQL会将NULL显示为“NULL”;GaussDB将NULL值显示为空值。
mysql> SELECT NULL; +------+ | NULL | +------+ | NULL | +------+ 1 row in set (0.00 sec)
GaussDB输出结果:m_db=# SELECT NULL; ?column? ---------- (1 row)
- 操作符执行后,列名显示不一致。MySQL会将NULL显示为“NULL”;GaussDB将NULL值显示为空值。
- 字符串转double遇到非法字符串时,告警信息不一致。MySQL在常量非法字符串报错,字段非法字符串不报错;GaussDB在常量非法字符串和字段非法字符串都报错。
- 比较操作符返回结果显示不同。MySQL返回1/0;GaussDB返回t/f。
MySQL数据库 |
GaussDB数据库 |
差异 |
---|---|---|
<> |
支持,存在差异 |
MySQL支持索引,GaussDB不支持索引。 |
<=> |
支持,存在差异 |
MySQL支持索引,GaussDB不支持索引、hash连接和合并连接。 |
行表达式 |
支持,存在差异 |
GaussDB: m_db=# SELECT (1,2) <=> row(2,3); ERROR: could not determine interpretation of row comparison operator <=> LINE 1: SELECT (1,2) <=> row(2,3); ^ HINT: unsupported operator. m_db=# SELECT (1,2) < NULL; ?column? ---------- (1 row) m_db=# SELECT (1,2) <> NULL; ?column? ---------- (1 row) m_db=# SELECT (1, 2) IS NULL; ?column? ---------- f (1 row) m_db=# SELECT ISNULL((1, 2)); ?column? ---------- f (1 row) m_db=# SELECT ROW(0,0) BETWEEN ROW(1,1) AND ROW(2,2); ERROR: un support type MySQL: mysql> SELECT (1,2) <=> row(2,3); +--------------------+ | (1,2) <=> row(2,3) | +--------------------+ | 0 | +--------------------+ 1 row in set (0.00 sec) mysql> SELECT (1,2) < NULL; ERROR 1241 (21000): Operand should contain 2 column(s) mysql> SELECT (1,2) <> NULL; ERROR 1241 (21000): Operand should contain 2 column(s) mysql> SELECT (1, 2) IS NULL; ERROR 1241 (21000): Operand should contain 1 column(s) mysql> SELECT ISNULL((1, 2)); ERROR 1241 (21000): Operand should contain 1 column(s) mysql> SELECT NULL BETWEEN NULL AND ROW(2,2); ERROR 1241 (21000): Operand should contain 1 column(s) |
-- |
支持,存在差异 |
MySQL表示对一个操作数进行两次取反,结果等于原操作数;GaussDB表示注释。 |
!! |
支持,存在差异 |
MySQL:!!含义同!,表示取非。 GaussDB:!表示取非操作,当!与!中间存在空格时,表示连续两次取非(! !);当!与!中间没有空格时,表示阶乘(!!)。
说明:
|
[NOT] REGEXP |
支持,存在差异 |
|
LIKE |
支持,存在差异 |
MySQL:LIKE的左操作数只能是位运算或者算术运算或者由括号组成的表达式,LIKE的右操作数只能是单目运算符(不含NOT)或者括号组成的表达式。 GaussDB:LIKE的左右操作数可以是任意表达式。 |
[NOT] BETWEEN AND |
支持,存在差异 |
MySQL:[NOT] BETWEEN AND嵌套使用时从右到左结合。[NOT] BETWEEN AND的第1个操作数和第2个操作数只能是位运算或者算术运算或者由括号组成的表达式。 GaussDB:[NOT] BETWEEN AND嵌套使用时从左到右结合。[NOT] BETWEEN AND的第1个操作数和第2个操作数可以是任意表达式。 |
IN |
支持,存在差异 |
MySQL:IN的左操作数只能是位运算或者算术运算或者由括号组成的表达式。 GaussDB:IN的左操作数可以是任意表达式。 |
! |
支持,存在差异 |
MySQL:!的操作数只能是单目运算符(不含not)或者括号组成的表达式。 GaussDB:!的操作数可以是任意表达式。 |
# |
不支持 |
MySQL支持#注释,GaussDB不支持#注释。 |
BINARY |
支持,存在差异 |
GaussDB中支持的表达式和MySQL并不完全一致(包括一些函数、操作符等)。GaussDB独有的表达式“~”、“IS DISTINCT FROM”等,由于BINARY关键字优先级更高,使用BINARY expr会优先将BINARY与“~”、“IS DISTINCT FROM”的左参数合并,导致报错。 |
取反(-) |
支持,存在差异 |
连续取反次数超过1次时,GaussDB会将其识别为注释,导致返回结果与MySQL存在差异。 |
XOR、|、&、<、>、<=、>=、=、!= |
支持,存在差异 |
MySQL执行机制为执行左操作数后,对结果进行判断是否为空,进而决定是否需要执行右操作数。 GaussDB执行机制是执行左右操作数后,对结果再进行判断是否为空。 当左操作数结果为空,右操作数执行报错时,MySQL不会报错直接返回,GaussDB会执行报错。 MySQL行为: mysql> SELECT version(); +------------------+ | version() | +------------------+ | 5.7.44-debug-log | +------------------+ 1 row in set (0.00 sec) mysql> dROP TABLE IF EXISTS data_type_table; Query OK, 0 rows affected (0.02 sec) mysql> CREATE TABLE data_type_table ( -> MyBool BOOL, -> MyBinary BINARY(10), -> MyYear YEAR -> ); Query OK, 0 rows affected (0.02 sec) mysql> INSERT INTO data_type_table VALUES (TRUE, 0x1234567890, '2021'); Query OK, 1 row affected (0.00 sec) mysql> SELECT (MyBool % MyBinary) | (MyBool - MyYear) FROM data_type_table; +-----------------------------------------+ | (MyBool % MyBinary) | (MyBool - MyYear) | +-----------------------------------------+ | NULL | +-----------------------------------------+ 1 row in set, 2 warnings (0.00 sec) GaussDB行为: m_db=# DROP TABLE IF EXISTS data_type_table; DROP TABLE m_db=# CREATE TABLE data_type_table ( m_db(# MyBool BOOL, m_db(# MyBinary BINARY(10), m_db(# MyYear YEAR m_db(# ); CREATE TABLE m_db=# INSERT INTO data_type_table VALUES (TRUE, 0x1234567890, '2021'); INSERT 0 1 m_db=# SELECT (MyBool % MyBinary) | (MyBool - MyYear) FROM data_type_table; WARNING: Truncated incorrect double value: '4Vx ' CONTEXT: referenced column: (MyBool % MyBinary) | (MyBool - MyYear) WARNING: division by zero CONTEXT: referenced column: (MyBool % MyBinary) | (MyBool - MyYear) ERROR: Bigint is out of range. CONTEXT: referenced column: (MyBool % MyBinary) | (MyBool - MyYear) |
操作符组合示例 |
MySQL数据库 |
GaussDB数据库 |
说明 |
---|---|---|---|
SELECT 1 LIKE 3 & 1; |
不支持 |
支持 |
LIKE的右操作数不能是位运算符组成的表达式。 |
SELECT 1 LIKE 1 +1; |
不支持 |
支持 |
LIKE的右操作数不能是算术运算符组成的表达式。 |
SELECT 1 LIKE NOT 0; |
不支持 |
支持 |
LIKE的右操作数只能是+、-、!等单目操作符或者括号组成的表达式,NOT除外。 |
SELECT 1 BETWEEN 1 AND 2 BETWEEN 2 AND 3; |
从右到左结合 |
从左到右结合 |
建议加上括号明确运算的优先级,防止由于运算顺序的差异导致运算结果产生偏差。 |
SELECT 2 BETWEEN 1=1 AND 3; |
不支持 |
支持 |
BETWEEN的第2个操作数不能是比较操作符组成的表达式。 |
SELECT 0 LIKE 0 BETWEEN 1 AND 2; |
不支持 |
支持 |
BETWEEN的第1个操作数不能是模式匹配操作符组成的表达式。 |
SELECT 1 IN (1) BETWEEN 0 AND 3; |
不支持 |
支持 |
BETWEEN的第1个操作数不能是IN操作符组成的表达式。 |
SELECT 1 IN (1) IN (1); |
不支持 |
支持 |
第2个IN表达式左操作数不能是IN组成的表达式。 |
SELECT ! NOT 1; |
不支持 |
支持 |
!的操作数只能是+、-、!等单目操作符或者括号组成的表达式,NOT除外。 |
索引差异
- GaussDB当前仅支持UBTree和B-tree索引。
- 针对模糊匹配(LIKE操作符),MySQL创建默认索引可以走索引;GaussDB默认的索引不走索引,需要用户使用以下语法指定opclass,比如指定为text_pattern_ops,LIKE操作符才可以走索引。
CREATE INDEX indexname ON tablename(col [opclass]);
- B-tree/UBTree索引场景保持原生GaussDB原有逻辑,即同一操作符族内的类型比较,支持索引扫描,其余索引类型暂未支持。
- 在使用GaussDB JDBC连接数据库时,GaussDB的YEAR类型在含有绑定参数的PBE场景下无法利用索引。
- WHERE子句中,索引字段类型和常量类型操作场景下,GaussDB中索引与MySQL索引支持存在差异,如表3所示。例如以下语句GaussDB不支持索引:
CREATE TABLE t(_int int); CREATE INDEX idx ON t(_int) USING BTREE; SELECT * FROM t WHERE _int > 2.0;
WHERE子句里索引字段类型和常量类型操作场景中,可以使用cast函数将常数类型显式转换为字段类型,以便实现索引。
SELECT * FROM t WHERE _int > cast(2.0 AS signed);
表3 索引支持存在差异 索引字段类型
常量类型
GaussDB是否支持
MySQL是否支持
整型
整型
是
是
浮点型
浮点型
是
是
定点型
定点型
是
是
字符串类型
字符串类型
是
是
二进制类型
二进制类型
是
是
带日期的时间类型
带日期的时间类型
是
是
TIME类型
TIME类型
是
是
带日期的时间类型
可转为带日期的时间类型(如20231130等整型)
是
是
带日期的时间类型
TIME类型
是
是
TIME类型
可转为TIME类型的常量(如203008等整型)
是
是
浮点型
整型
是
是
浮点型
定点型
是
是
浮点型
字符串类型
是
是
浮点型
二进制类型
是
是
浮点型
带日期的时间类型
是
是
浮点型
TIME类型
是
是
定点型
整型
是
是
字符串类型
带日期的时间类型
是
否
字符串类型
TIME类型
是
否
二进制类型
字符串类型
是
是
二进制类型
带日期的时间类型
是
否
二进制类型
TIME类型
是
否
整型
浮点型
否
是
整型
定点型
否
是
整型
字符串类型
否
是
整型
二进制类型
否
是
整型
带日期的时间类型
否
是
整型
TIME类型
否
是
定点型
浮点型
否
是
定点型
字符串类型
否
是
定点型
二进制类型
否
是
定点型
带日期的时间类型
否
是
定点型
TIME类型
否
是
字符串类型
二进制类型
否
是
带日期的时间类型
整型(不可转为带日期的时间类型)
否
是
带日期的时间类型
浮点型(不可转为带日期的时间类型)
否
是
带日期的时间类型
定点型(不可转为带日期的时间类型)
否
是
TIME类型
整型(不可转为TIME类型)
否
是
TIME类型
字符串类型(不可转为TIME类型)
否
是
TIME类型
二进制类型(不可转为TIME类型)
否
是
TIME类型
带日期的时间类型
否
是
YEAR类型
YEAR类型
是
是
YEAR类型
可转为YEAR类型的常量(如2034等整型)
是
是
BIT类型
BIT类型
否
是
表4 是否支持走索引 索引字段类型
常量类型
GaussDB是否走索引
MySQL是否走索引
字符串类型
整型
否
否
字符串类型
浮点型
否
否
字符串类型
定点型
否
否
二进制类型
整型
否
否
二进制类型
浮点型
否
否
二进制类型
定点型
否
否
带日期的时间类型
字符串类型(不可转为带日期的时间类型)
否
否
带日期的时间类型
二进制类型(不可转为带日期的时间类型)
否
否
TIME类型
浮点型(不可转为TIME类型)
否
否
TIME类型
定点型(不可转为TIME类型)
否
否
BIT类型
字符串类型
否
否