MySQL 兼容性
TiDB 与 MySQL 协议以及 MySQL 5.7 和 MySQL 8.0 的常用功能和语法具有高度兼容性。MySQL 生态系统中的工具(PHPMyAdmin、Navicat、MySQL Workbench、DBeaver 以及 更多)和 MySQL 客户端都可以用于 TiDB。
然而,MySQL 的一些功能在 TiDB 中不被支持。这可能是因为存在更好的解决方案(例如使用 JSON 代替 XML 函数)或当前需求与实现难度不符(例如存储过程和函数)。此外,一些功能在分布式系统中实现起来可能较为困难。
你可以在 TiDB Playground 试用 TiDB 的功能。
不支持的功能
- 存储过程和函数
- 触发器
- 事件
- 用户定义函数
FULLTEXT
语法和索引 #1793SPATIAL
(也称为GIS
/GEOMETRY
)函数、数据类型和索引 #6347- 除
ascii
、latin1
、binary
、utf8
、utf8mb4
和gbk
之外的字符集 - 优化器跟踪
- XML 函数
- X-Protocol #1109
- 列级权限 #9766
XA
语法(TiDB 内部使用两阶段提交,但不通过 SQL 接口暴露)CREATE TABLE tblName AS SELECT stmt
语法 #4754CHECK TABLE
语法 #4673CHECKSUM TABLE
语法 #1895REPAIR TABLE
语法OPTIMIZE TABLE
语法HANDLER
语句CREATE TABLESPACE
语句- "Session Tracker: Add GTIDs context to the OK packet"
- Descending Index #2519
SKIP LOCKED
语法 #18207- Lateral derived tables #40328
- JOIN ON 子查询 #11414
与 MySQL 的差异
自增 ID
在 TiDB 中,自增列的值(ID)在全局范围内唯一,并在单个 TiDB 服务器内递增。为了在多个 TiDB 服务器之间实现 ID 的递增,可以使用
AUTO_INCREMENT
MySQL 兼容模式。但需要注意的是,ID 不一定是连续分配的,因此建议避免混用默认值和自定义值,以防遇到Duplicated Error
错误。你可以使用系统变量
tidb_allow_remove_auto_inc
来允许或禁止移除AUTO_INCREMENT
列属性。若要移除该属性,可以使用ALTER TABLE MODIFY
或ALTER TABLE CHANGE
语法。TiDB 不支持添加
AUTO_INCREMENT
列属性,一旦移除,无法恢复。对于 TiDB v6.6.0 及之前版本,TiDB 中的自增列行为与 MySQL InnoDB 相同,要求它们为主键或索引前缀。从 v7.0.0 开始,TiDB 移除了此限制,允许更灵活的表主键定义。#40580
更多详情请参见 AUTO_INCREMENT
。
mysql> CREATE TABLE t(id INT UNIQUE KEY AUTO_INCREMENT);
Query OK, 0 rows affected (0.05 sec)
mysql> INSERT INTO t VALUES();
Query OK, 1 rows affected (0.00 sec)
mysql> INSERT INTO t VALUES();
Query OK, 1 rows affected (0.00 sec)
mysql> INSERT INTO t VALUES();
Query OK, 1 rows affected (0.00 sec)
mysql> SELECT _tidb_rowid, id FROM t;
+-------------+------+
| _tidb_rowid | id |
+-------------+------+
| 2 | 1 |
| 4 | 3 |
| 6 | 5 |
+-------------+------+
3 rows in set (0.01 sec)
如上所示,由于共享分配器,id
每次递增 2。在 MySQL 兼容模式中,此行为会改变,不再使用共享分配器,因此不会跳号。
性能模式
在 TiDB Cloud 中查看性能指标,可以在 TiDB Cloud 控制台的集群概览页面查看,或使用 第三方监控集成。大多数 性能模式表 在 TiDB 中返回空结果。
查询执行计划
TiDB 中的查询执行计划(EXPLAIN
/EXPLAIN FOR
)的输出格式、内容和权限设置与 MySQL 有显著差异。
在 TiDB 中,MySQL 的系统变量 optimizer_switch
是只读的,不会影响查询计划。虽然可以使用类似 MySQL 的语法添加优化提示,但可用的提示和其实现可能不同。
更多信息请参见 Understand the Query Execution Plan。
内置函数
TiDB 支持大部分 MySQL 的内置函数,但并非全部。你可以使用 SHOW BUILTINS
来获取可用函数的列表。
DDL 操作
在 TiDB 中,所有支持的 DDL 变更都可以在线进行。然而,与 MySQL 相比,TiDB 在 DDL 操作上存在一些主要限制:
使用单个
ALTER TABLE
语句修改多个表结构对象(如列或索引)时,不支持对同一对象进行多次变更。例如,执行ALTER TABLE t1 MODIFY COLUMN c1 INT, DROP COLUMN c1
时,会报Unsupported operate same column/index
错误。不支持用单个
ALTER TABLE
语句修改多个 TiDB 特有的 schema 对象,如TIFLASH REPLICA
、SHARD_ROW_ID_BITS
和AUTO_ID_CACHE
。TiDB 不支持通过
ALTER TABLE
改变某些数据类型。例如,不支持将DECIMAL
类型改为DATE
类型。如果不支持此类数据类型变更,会报Unsupported modify column: type %d not match origin %d
错误。更多详情请参见ALTER TABLE
。ALGORITHM={INSTANT,INPLACE,COPY}
语法在 TiDB 中仅作为断言,不会影响ALTER
的算法。详见ALTER TABLE
。不支持添加/删除
CLUSTERED
类型的主键。关于CLUSTERED
主键的更多信息,请参见 clustered index。不支持不同类型的索引(
HASH|BTREE|RTREE|FULLTEXT
),指定时会被解析后忽略。TiDB 支持
HASH
、RANGE
、LIST
和KEY
分区类型。不支持的分区类型会返回Warning: Unsupported partition type %s, treat as normal table
,其中%s
为具体不支持的分区类型。Range、Range COLUMNS、List 和 List COLUMNS 分区表支持
ADD
、DROP
、TRUNCATE
和REORGANIZE
操作。其他分区操作会被忽略。Hash 和 Key 分区表支持
ADD
、COALESCE
和TRUNCATE
操作。其他分区操作会被忽略。不支持以下分区语法:
SUBPARTITION
{CHECK|OPTIMIZE|REPAIR|IMPORT|DISCARD|REBUILD} PARTITION
更多关于分区的内容,请参见 Partitioning。
表统计信息分析
在 TiDB 中,Statistics Collection 与 MySQL 不同,它会完全重建表的统计信息,这是一项资源消耗较大的操作,耗时较长。而 MySQL/InnoDB 执行的是相对轻量且短暂的操作。
更多信息请参见 ANALYZE TABLE
。
SELECT
语法的限制
TiDB 不支持以下 SELECT
语法:
SELECT ... INTO @variable
SELECT .. GROUP BY expr
不会像 MySQL 5.7 那样隐含GROUP BY expr ORDER BY expr
。
更多详情请参见 SELECT
。
UPDATE
语句
详见 UPDATE
。
视图
TiDB 中的视图不可更新,不支持 UPDATE
、INSERT
和 DELETE
等写操作。
临时表
更多信息请参见 TiDB 本地临时表与 MySQL 临时表的兼容性。
字符集和排序规则
了解 TiDB 支持的字符集和排序规则,请参见 Character Set and Collation Overview。
关于 GBK 字符集的 MySQL 兼容性信息,详见 GBK compatibility。
TiDB 继承表中使用的字符集作为国家字符集。
存储引擎
TiDB 允许创建使用其他存储引擎的表。尽管如此,TiDB 所描述的元数据是针对 InnoDB 存储引擎的,以确保兼容性。
SQL 模式
TiDB 支持大部分 SQL 模式:
- 兼容模式(如
Oracle
和PostgreSQL
)会被解析但忽略。MySQL 5.7 中已弃用,MySQL 8.0 中已移除。 ONLY_FULL_GROUP_BY
模式与 MySQL 5.7 存在细微 语义差异。- MySQL 中的
NO_DIR_IN_CREATE
和NO_ENGINE_SUBSTITUTION
模式在兼容性方面被接受,但不适用于 TiDB。
默认值差异
TiDB 与 MySQL 5.7 和 MySQL 8.0 在默认值上存在差异:
- 默认字符集:
- TiDB 的默认值为
utf8mb4
。 - MySQL 5.7 的默认值为
latin1
。 - MySQL 8.0 的默认值为
utf8mb4
。
- TiDB 的默认值为
- 默认排序规则:
- TiDB 的默认排序规则为
utf8mb4_bin
。 - MySQL 5.7 的默认排序规则为
utf8mb4_general_ci
。 - MySQL 8.0 的默认排序规则为
utf8mb4_0900_ai_ci
。
- TiDB 的默认排序规则为
- 默认 SQL 模式:
- TiDB 的默认 SQL 模式包括:
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
。 - MySQL 的默认 SQL 模式:
- MySQL 5.7 的默认值与 TiDB 相同。
- MySQL 8.0 的默认值包括:
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
。
- TiDB 的默认 SQL 模式包括:
lower_case_table_names
的默认值:- TiDB 的默认值为
2
,且目前只支持2
。 - MySQL 默认值如下:
- 在 Linux 上:
0
,表示按创建表或数据库时指定的大小写存储,名称比较区分大小写。 - 在 Windows 上:
1
,表示表名存储为小写,名称比较不区分大小写。MySQL 在存储和查找时会将所有表名转换为小写。此行为也适用于数据库名和表别名。 - 在 macOS 上:
2
,表示按创建时指定的大小写存储,但在查找时会转换为小写,名称比较不区分大小写。
- 在 Linux 上:
- TiDB 的默认值为
explicit_defaults_for_timestamp
的默认值:- TiDB 的默认值为
ON
,且目前只支持ON
。 - MySQL 默认值:
- MySQL 5.7:
OFF
。 - MySQL 8.0:
ON
。
- MySQL 5.7:
- TiDB 的默认值为
日期和时间
TiDB 支持命名时区,考虑如下:
- TiDB 使用系统中已安装的所有时区规则(通常为
tzdata
包)进行计算。这使得可以使用所有时区名称,无需导入时区表数据。导入时区表数据不会改变计算规则。 - 目前,MySQL 默认使用本地时区,然后依赖系统内置的当前时区规则(例如夏令时开始时)进行计算。若未 导入时区表数据,MySQL 无法通过名称指定时区。
类型系统差异
MySQL 支持但 TiDB 不支持 以下列类型:
SQL_TSI_*
(包括 SQL_TSI_MONTH、SQL_TSI_WEEK、SQL_TSI_DAY、SQL_TSI_HOUR、SQL_TSI_MINUTE 和 SQL_TSI_SECOND,但不包括 SQL_TSI_YEAR)
正则表达式
关于 TiDB 与 MySQL 正则表达式兼容性的信息,包括 REGEXP_INSTR()
、REGEXP_LIKE()
、REGEXP_REPLACE()
和 REGEXP_SUBSTR()
,请参见 Regular expression compatibility with MySQL。
不兼容的已弃用功能
TiDB 不实现 MySQL 中已弃用的特定功能,包括:
CREATE RESOURCE GROUP
、DROP RESOURCE GROUP
和 ALTER RESOURCE GROUP
语句
创建、修改和删除资源组的相关语句参数支持与 MySQL 不同。详情请参见:
与 MySQL InnoDB 的悲观事务(锁)差异
关于 TiDB 和 MySQL InnoDB 在悲观事务(锁)方面的差异,详见 Differences from MySQL InnoDB。