TiDB技术分享

AI 摘要 / TL;DR

TiDB技术分享 点击上方“IT那活儿”,关注后了解更多精彩内容!! 前言 1. 目的 本文档旨在为使用 TiDB 数据库的应用和系统提供统一规范参考,标准化 TiDB 数据库 的开发使用及SQL优化流程,提高业务开发系统的规范性和代码的可读性,减轻维护工作量, 提高工作效率。 2. 适用范围 ● TiDB 数据库开发

来源: https://www.ucloud.cn/yun/129680.html 作者: IT那活儿 发布日期: 发布于2023-01-11 13:20

TiDB技术分享

点击上方“IT那活儿”,关注后了解更多精彩内容!!

前言

1. 目的

本文档旨在为使用 TiDB 数据库的应用和系统提供统一规范参考,标准化 TiDB 数据库 的开发使用及SQL优化流程,提高业务开发系统的规范性和代码的可读性,减轻维护工作量, 提高工作效率。

2. 适用范围

● TiDB 数据库开发设计人员

● 数据库管理人员

● 数据库运营人员

● 数据分析人员

● 数据库架构师

3. 注意事项

TiDB 暂时不支持的特性:

● 存储过程

● 触发器

● 自定义函数

● 外键约束

● 全文索引

● 空间索引

● 非 UTF8 字符集

对象命名规范

用于规范数据库对象的名命,如数据库(DATABASE)、表(TABLE)、索引(INDEX)、用户(USER)等的命名约定。

1. 原则

1)命名建议使用具有意义的英文词汇,词汇中间以下划线分隔;

2)命名只能使用英文字母、数字、下划线;

3)避免用 TiDB 的保留字如:group,order 等作为单个字段名;

4)建议所有数据库对象使用小写字母。

2. 数据库命名规范

建议按照业务、产品线或者其它指标进行区分,一般不要超过 20 个字符。如:临时库( db_tmp)、测试库(db_test)。

3. 表

3.1. 表命名规范

1)同一业务或者模块的表尽可能使用相同的前缀,表名称尽可能表达含义。

2)多个单词以下划线分隔,不推荐超过32个字符。

3)建议对表的用途进行注释说明,以便于统一认识。如:

● 临时表(tbl_tmp_crm_relation_0425);

● 备份表(tbl_bak_crm_relation_20170425)。

4)不同业务模块的表多带带建立 DATABASE,并增加相应注释。

5)目前 TiDB 只支持将 lower-case-table-names 值设为 2,即按照大小写来保存表名,按照小 写来比较(不区分大小写)。

3.2. 表的设计

1)在进行 TiDB 表设计过程中,有以下几点需要注意:

● 为了保障主从集群复制以及增量备份的幂等性,表需要有主键。建议采用自然主键,而非业务字段作为主键。TIDB为避免热点问题,可以用AutoRandom替换AUTOINCREMENT,随机分配,采用unsigned bigint 作为该列的列属性。

建议采用聚簇索引,非聚簇索引主键实际为唯一索引,存储仍以隐式的rowid构成。聚簇索引不支持增删改操作。

● 出于为性能考虑,尽量避免存储超宽表,表字段数不建议超过 60 个,建议单行的总数 据大小不要超过 64K,数据长度过大字段最好拆到另外的表。

● 表及字段要加commet属性,方便业务的理解。

● 单表数据规模建议在1000万以内。对于大型业务表,建议建表初期设计分区以及清理备份策略。

● 需要 join 的字段,数据类型保障绝对一致,避免隐式转换。

● 字段属性尽量加上NOT NULL约束以及默认值,使用NULL值会导致如下副作用:

----含义不明,对很多运算符不管用,增加复杂度。

----很难进行查询优化。

----含NULL的复合索引失效。

2)TiDB 字符集默认就是 UTF8 ,而且目前只支持 UTF8:

● 使用 utf8mb4 编码,它是 utf8 的超集,除了将编码改为 utf8mb4 外不需要做其他转换。

● TiDB 中,utf8mb4 的默认排序规则为 utf8mb4_bin(区分大小写)。

● 4.0 支持 utf8mb4_general_ci(不区分大小写) ,需要初始化集群前配置 new_collations_enabled_on_first_bootstrap = true 。

4. 字段

4.1. 字段命名规范

1)字段命名需要表示其实际含义的英文单词或简写;

2)建议各表之间相同意义的字段应同名;

3)字段需要添加注释,枚举型需指明主要值的含义,如”0 - 离线,1 - 在线”;

4)布尔值列命名为 [is_描述]。如 member 表上表示为 enabled 的会员的列命名为 is_enabled ;

5)字段名不建议超过 30 个字符,字段个数不建议大于 60;

6)尽量避免使用保留字,如 order、from、desc 等,请参考官方保留字。

4.2. 字段的设计

1)整数类型

● TiDB 支持 MySQL 所有的整数类型,包括 INTEGER/INT、TINYINT、SMALLIN、T MEDIUMINT 以及 BIGINT;

● INT:所有整数类型的字段推荐只使用 INT 或者 BIGINT;

● BIGINT:定义中不推荐添加长度;

● 推荐使用 INT(10) UNSIGNED 存储 IPv4 格式 IP 地址;

● TINYINT(1)、TINYINT(4) 都是存储一个字节,并不会因为括号里的数字改变。例如 TINYINT(4) 存储 22 则会显示 0022,因为最大宽度为4,达不到的情况下用0来补充。

2)浮点类型

● TiDB 支持 MySQL 所有的浮点类型,包括 FLOAT、DOUBLE,DECIMAL、NUMERIC 等。

● DECIMAL(M,D):推荐使用 DECIMAL 类型。float 和 double 在存储的时候,存在精度 损失的问题,很可能在值的比较时,得到不正确的结果。DECIMAL 在与 VARCHAR、 CHAR 类型比较时会转换为 DOUBLE 类型进行比较,也存在精度损失问题,建议在进 行比较时使用显示类型转换,如 CAST 避免精度损失。

3)日期时间类型

● TiDB 支持 MySQL 所有的日期时间类型,包括 DATE、DATETIME、TIMESTAM、P TIME 以及 YEAR;

● DATE:所有只需要精确到天的字段全部使用 DATE 类型,而不应该使用 TIMESTAMP 或者DATETIME 类型;

● DATETIME:所有需要精确到时间(时分秒)的字段均使用 DATETIME,不要使用 TIMESTAMP 类型;

● 时间字段使用时间日期类型,不要使用字符串类型存储。否则无法利用日期函数对日 期字段进行操作,而需要使用字符串函数进行复杂的操作。

4)处理日期和时间类型时,请记住下面这些:

● 尽管 TiDB 尝试解释不同的格式,日期部分必须是按 年-月-日 的顺序(比如,’ 98-09-04’),而不是 月-日-年 或者 日-月-年 的顺序;

● 要求年份必须是四位数字。日期值中包含两位数字的年份是有歧义的,TiDB 按下面规则解释:范围在 70-99 之间的被转换成 1970-1999 范围在 00-69 之间的被转换成 2000-2069 。

5)字符串类型

● TiDB 支持 MySQL 所有的字符串类型,包括 CHAR、VARCHAR、BINARY、 VARBINARY、BLOB、TEXT、ENUM 以及 SET;

● VARCHAR(N):所有动态长度字符串全部使用 VARCHAR 类型,N 表示的是字符数不 是字节数,比如 VARCHAR(256),需要根据实际的宽度来选择 N,N 尽可能小;

● CHAR:仅仅只有单个字符的字段使用 CHAR(1) 类型,例如性别字段;

● TEXT:仅仅当字符数量可能超过 20000 个的时候,才建议使用TEXT类型来存放字符 类数据,因为所有 TiDB 数据库都会使用 UTF8 字符集。所有使用 TEXT 类型的字段 建议和原表进行分拆,与原表主键多带带组成另外一个表进行存放;

● 不建议使用 ENUM、SET 类型,尽量使用 TINYINT 来代替。

5. 索引

5.1. 索引命名规范

1)主键索引:

pk_[表名称简写]_[字段名简写]。

2)唯一索引:

uk_[表名称简写]_[字段名简写]。

3)普通索引:

idx_[表名称简写]_[字段名简写] 4)多单词组成的 column_name,取尽可能代表意义的缩写。

5.2. 索引设计

1)选择区分度大的列建立索引,不在低基数列上建立索引,例如:“性别”,“是否是 XXX”;

2)单张表的索引数量控制在 5 个以内,避免冗余索引;

3)索引中的字段数建议不超过 5 个;

4)唯一索引建议由 3 个或更少的字段组成;

5)尽量不要在频繁更新的列上创建索引;

6)对于确定需要组成组合索引的多个字段,建议将选择性高的字段靠前放;

7)最左前缀原则,使用联合索引时,从左向右匹配,比如索引 idx_c1_c2_c3 (c1,c2,c3,)相当 于创建了 (c1)、(c1,c2)、(c1,c2,c3) 三个索引,where 条件包含上面三种情况的字段比较则可 以用到索引,但像 where c1=a and c3=c 只能用到 c1 列的索引,像 c2=b and c3=c 等情况就 完全用不到这个索引;

8)很长的 VARCHAR 字段建立索引时,指定索引长度,没必要对全字段建立索引,根据 实际 文本区分度决定索引长度即可。idx_table_name (name(10));

9)定期删除一些长时间未使用过的索引;

10)ORDER BY,GROUP BY,DISTINCT 的字段需要添加在索引的后面,形成覆盖索引;

11)不建议在 where 条件索引列上使用函数,会导致索引失效,如 lower(email);

12)使用 like 模糊匹配,% 不要放首位,会导致索引失效。

5.3. TiDB 中的索引

索引也是数据,也要占用存储空间。和表中的数据一样,TiDB 中表的索引在存储引擎 中也被作为 kv 来存储,一行索引是一个 kv 对。例如一张有 10 个索引的表,每插入一行数据 的时候,会写入 11 个 kv 对。

TiDB 支持主键索引,唯一索引,也支持二级索引,构成以上索引的可以是单一列,也 可以是多个列(复合索引)。TiDB 目前(v5.0)还不支持反向/双向索引,全文索引,分区表的全局索引。

TiDB 中在查询的谓词是 =,>,=,<=,like ‘...%’,not like ‘.,..i%n,’ not in,<>,!=, is null,is not null,between…and … 时能够使用索引,使用与否由优化器来决策。TiDB 中在查询的谓词是 like ‘%...’,like ‘%...%’,not like ‘%..,.’not like ‘%...%’,<=> 时 ,都无法使用索引。目前版本(v5.0)还没有对 <=> 做处理,无法像 is null 一样使用索引。

数据库对象设计

1. 账号权限

TiDB 在数据库初始化时会生成一个 root@% 的默认账户,生产环境建议调整 root 用户为强密码,且不对外开放。线上所需用户建议按照用户或者业务场景划分,根据实际情况对每个用户授予相应权限,例如:

1root超级用户全局管理,禁止对外开放
2dba数据库管理员数据库 DBA
3app应用开发应用开发
4tempuser临时统计线上业务临时统计,只读用户
5other其他用户第三方人员访问

2. 角色

角色是一系列权限的集合。用户可以创建角色、删除角色、将权限赋予角色;也可以将角色授予给其他用户,被授予的用户在启用角色后,可以得到角色所包含的权限。

2.1. 创建角色

CREATE ROLE app_developer, app_read, app_write;

角色会被保存在 mysql.user 表中,角色名称的主机名部分(如果省略)默认为 %。如果表中有同名角色或用户,角色会创建失败并报错。创建角色的用户需要拥有 CREATE ROLE 或 CREATE USER 权限。

2.2. 角色授权

为 app_read 角色授予数据库 app_db 的读权限:

GRANT SELECT ON app_db.* TO app_read@%;

2.3. 角色赋给用户

使用 GRANT 授予用户对应的角色。

GRANT app_read TO dev1@localhost;

2.4. 默认角色

角色在授予给用户之后,并不会生效;只有在用户启用了某些角色之后,才可以使用角色拥有的权限。

可以对用户设置默认启用的角色;用户在登录时,默认启用的角色会被自动启用。

比如将 app_read 和 app_wirte 设置为 rw_user1@localhost 的默认启用角色:

SET DEFAULT ROLE app_read, app_write TO rw_user1@localhost;

将 dev1@localhost 的所有角色,设为其默认启用角色:

SET DEFAULT ROLE ALL TO dev1@localhost;

2.5. 启用角色

为当前用户启用角色 app_read 和 app_write ,仅在当前 session 有效:

SET ROLE app_read, app_write;

启用当前用户的默认角色:

SET ROLE DEFAULT

启用授予给当前用户的所有角色:

SET ROLE ALL

不启用任何角色:

SET ROLE NONE

启用除 app_read 外的角色:

SET ROLE ALL EXCEPT app_read

SQL 开发规范

1. 建表删表规范

1.1. 基本原则:表的建立在遵循表命名规范前提下,建议业务应用内部封装建表删表语句增加判断逻辑,防止业务流程异常中断。

1.2. 详细说明:create table if not exists table_name 或 者 drop table if exists table_name 语句建议增加 if 判 断,避免应用侧由于表的改动造成的异常中断。

1.3. 不支持 create table as select 语法,需要改写为表结构复制 create table like … 和将数据写入的 insert into select … 的组合语句。

2. select * 使用规范

2.1. 基本原则:禁止使用 select * 进行查询。

2.2. 详细说明:按需求选择合适的字段列,杜绝直接 SELECT * 读取全部字段,减少网络带宽消耗,有效利用 覆盖索引。

3. Region 热点

region 热点可能的原因:

● 这条 SQL 涉及到的 region 的 leader 全部在这个 TiKV 上;

● 这条 SQL 只涉及到一个 region,并且有大量的请求使用同样或者类似的 SQL。

3.1. 基本原则:如果表的数据量比较小,数据存储大概率只涉及到一个 region,大量请求对该表进行写入或者读取都会造成该 region 热点,可以通过手工拆分 region 方式进行调整,也可以在建表时预先进行 split region。

3.2. 详细说明:如何有效避免热点?

●Handle ID 设计 避免连续自增主键的设计,建议采用AutoRandom替换AUTOINCREMENT,随机分配;

● TiDB Partition 通过设置表分区方式来避免热点,支持按照 Hash 以及按照 Range 分区。

4. 字段上使用函数规范

4.1. 基本原则:在取出字段上可以使用相关函数,但是在 Where 条件中的过滤条件字段上严禁使用任何函数, 包括数据类型转换函数。

4.2. 详细说明:

● 错误的写法:

``` select gmt_create from ... where date_format(gmt_create,%Y%m%d %H:%i:%s) = 20090101 00:00:0 ```

● 正确的写法:

``` select date_format(gmt_create,%Y%m%d %H:%i:%s) from .. . where gmt_create = str_to_date(20090101 00:00:00,%Y%m%d %H:%i:s);```

5. 数据删除规范

5.1. 基本原则:

删除表中全部的数据时,使用 TRUNCATE 或者 DROP 后重建方式,不要使用 DELETE;

5.2. 详细说明:

DELETE,TRUNCATE 和 DROP 都不会立即释放空间,对于 TRUNCATE 和 DROP操作,在 达到 TiDB 的 GC (garbage collection) 时间后(默认 10 分钟),TiDB的 GC 机制会删除数据 并释放空间。对于 DELETE 操作 TiDB 的 GC 机制会删除数据,但不会释放空间,而是当后 续数据写入 RocksDB 且进行 compact 时对空间重新利用。

隔离级别

TiDB 支持的隔离级别是 Snapshot Isolation(SI),和 RepeatabRleead(RR) 隔离级别 基本等价。

大事务限制

基于日志的数据库在面对大事务时,需要手动调大可用日志的容量,以避免日志被单 一事务占满。TiDB 处理大事务的性能相较于处理并发的小事务的性能要差,因此 TiDB 中对于事务 量设定了一些限制:

● 最大单行记录容量为 120MB(v5.0 及更高的版本可通过 tidb-server 配置项 performance.txn-entry-size-limit 调整,低于 v5.0 的版本支持的单行容量为 6MB);

● 支持的最大单个事务容量为 10GB(v4.0 及更高版本可通过 tidb-server 配置项 performance.txn-total-size-limit 调整,低于 v4.0 的版本支持的最大单个事务容量为 100MB)。

结果集不稳定

1. group by

出于便捷的考量,MySQL “扩展” 了 group by 语法,使 select 子句可以引用未在 group by 子句中声明的非聚集字段,也就是 non-full group by 语法,在其他数据库中,这被认为是一种语法错误,因为这会导致结果集不稳定。想保障 group by 语句结果集的稳定,请使用 full group by 语法。

2. order by

在 SQL 的语义中,只有使用了 order by 语法才会保障结果集的顺序输出。而单机数据 库由于数据都存储在一台服务器上,在不进行数据重组时,多次执行的结果往往是稳定的,有些数据库(尤其是 MySQL InnoDB 存储引擎)还会按照主键或索引的顺序进行结果集的输出。TiDB 是分布式数据库,数据被存储在多台服务器上,另外 TiDB 层不缓存数据页,因此不含 order by 的 SQL 语句的结果集展现顺序容易被感知到不稳定。想要按顺序输出的结果集,需 明确的把要排序的字段添加到 order by 子句中,这符合 SQL 的语义。

TiDB 中的各种超时

1. GC 超时

TiDB的事务的实现采用了 MVCC(多版本并发控制)机制,当新写入的数据覆盖旧的数据时,旧的数据不会被替换掉,而是与新写入的数据同时保留,并以时间戳来区分版本。TiDB 通过定期 GC 的机制来清理不再需要的旧数据。默认配置下 TiDB 可以保障每个 MVCC 版本(一致性快照)保存 10 分钟,读取时间超 过 10 分钟的事务,会收到报错GC life time is shorter than transaction duration 当用户确信自己需要更长的读取时间时,比如在使用了 Mydumper 做全量备份的场景 中(Mydumper 备份的是一致性的快照),可以通过调整 TiDB 中 mysql.tidb 表中的 tikv_gc_life_time 的值来调大 MVCC 版本保留时间,需要注意的是 tikv_gc_life_time 的配置是立刻影响全局的,调大它会为当前所有存在的快照增加生命时长,调小它会立即缩短所有快照的生命时长。过多的 MVCC 版本会拖慢 TiKV 的处理效率,在使用 Mydumper 做完全量备份 后需要及时把 tikv_gc_life_time 调整回之前的设置。

2. 事务超时

含 DML 语句的事务,除了受tikv_gc_life_time 限制之外,还受到另外一个参数 max-txn-time-use 的影响,这个参数位于 tidb-server 的配置文件 tidb.toml 中,用于控制单个事 务允许的最大执行时间。该参数的默认值为 590(秒),需要注意必须控制该参数的值小于 tikv_gc_life_time 的值。形如 insert into t10 select * from t1 的 SQL 语句,即使执行时间没有达到 tikv_gc_life_time 限制,但超过了 max-txn-time-use 的限制,会由于超时而回滚。

3. SQL 超时

TiDB 还提供了一个系统变量来限制单条 SQL 语句的执行时间:max_execution_time, 它的默认值为 0,表示无限制。max_execution_time 目前对所有类型的 statement 生效,并非只 对 SELECT 语句生效。其单位为 ms,但实际精度在 100ms 级别,而非更准确的毫秒级别。

MySQL Connector/J 推荐版本

1. TiDB 服务端兼容

TiDB 服务端兼容 MySQL 5.7,客户端推荐使用 5.1.36 或更高版本 的 5.1.x jdbc 驱动。

2. JDBC 参数设置

Java 应用常用的数据库连接池包括 weblogic、c3p0、Druid等。使用连接池配置数据源 时,需要配置一系列参数,其中比较重要的包括 jdbc 的 url 配置,超时探活机制等。充分认识并理解各项参数有助于让 TiDB 发挥出更高的性能。

一个建议的 url 配置如下:

spring.datasource.url=JDBC:mysql://{TiDBIP}:{TiDBPort}/{DBName}?characterEncoding= utf8&useSSL=false&useServerPrepStmts=true&prepStmtCacheSqlLimit=10000000000&useCon figs=maxPerformance&rewriteBatchedStatements=true&defaultfetchsize=-214783648

序列(Sequence)

序列是一种数据库对象,应用程序通过调用某个序列可以产生递增的序列值,应用程序可以灵活的使用这个序列值为一张表或多张表赋值,也可以使用序列值进行更复杂的加工,来实现文本和数字的组合,来赋予代理键以一定的跟踪和分类的意义。TiDB 从 v4.0 版本开 始提供序列功能,详情请参考官方文档。

语法:

CREATE [TEMPORARY] SEQUENCE [IF NOT EXISTS] sequence_name[ INCREMENT [ BY | = ] increment ][ MINVALUE [=] minvalue | NO MINVALUE | NOMINVALUE ][ MAXVALUE [=] maxvalue | NO MAXVALUE | NOMAXVALUE ][ START [ WITH | = ] start ][ CACHE [=] cache | NOCACHE | NO CACHE][ CYCLE | NOCYCLE | NO CYCLE][ ORDER | NOORDER | NO ORDER][table_options]
参数默认值描述
TEMPORARYFALSETiDB 暂时不支持 TEMPORARY 选项,仅在语法上做兼容。
INCREMENT1指定序列的步长。其正负值可以控制序列的增长方向。
MINVALUE1 或 -9223372036854775807指定序列的最小值。当 INCREMENT > 0 时,默认值为 1;当 INCREMENT < 0 时,默认值为 -9223372036854775807。
MAXVALUE9223372036854775806 或 -1指定序列的最大值。当 INCREMENT > 0 时,默认值为 9223372036854775806;当 INCREMENT < 0 时,默认值为 -1。
STARTMINVALUE 或 MAXVALUE指定序列的初始值。当 INCREMENT > 0 时,默认值为 MINVALUE; 当 INCREMENT < 0 时,默认值为 MAXVALUE。
CACHE1000指定每个 TiDB 本地缓存序列的大小。
CYCLENO CYCLE指定序列用完之后是否要循环使用。在 CYCLE 的情况下,当 INCREMENT > 0 时,序列用完后的后续起始值为 MINVALUE;当 INCREMENT < 0 时,序列用完后的后续起始值为 MAXVALUE。
ORDERNO ORDERTiDB 暂时不支持 ORDER 选项,仅在语法上做兼容。

1. SEQUENCE函数

主要通过表达式函数来操纵序列的使用。

● NEXTVAL 或 NEXT VALUE FOR

本质上都是 nextval() 函数,获取序列对象的下一个有效值,其参数为序列的 identifier。

● LASTVAL

lastval() 函数,用于获取本会话上一个使用过的值。如果没有值,则为 NULL,其参数为序列的 identifier。

● SETVAL

setval() 函数,用于设置序列的增长。其第一参数为序列的 identifier,第二个参数为 num。

2. 示例

2.1. 创建一个默认参数的序列对象

CREATE SEQUENCE seq;Query OK, 0 rows affected (0.06 sec)

2.2. 使用 nextval() 函数获取序列对象的下一个值

SELECT nextval(seq);+--------------+| nextval(seq) |+--------------+| 1 |+--------------+1 row in set (0.02 sec)

2.3. 使用 lastval() 函数获取本会话上一次调用序列对象所产生的值

SELECT lastval(seq);+--------------+| lastval(seq) |+--------------+| 1 |+--------------+ row in set (0.02 sec)

2.4. 使用 setval() 函数设置序列对象当前值的位置

SELECT setval(seq, 10);+-----------------+| setval(seq, 10) |+-----------------+| 10 |+-----------------+1 row in set (0.01 sec)

2.5. 使用 next value for 语法获取序列的下一个值

SELECT next value for seq;+--------------------+| next value for seq |+--------------------+| 11 |+--------------------+1 row in set (0.00 sec)

其他操作

1. ADD COLUMN

ALTER TABLE.. ADD COLUMN 语句用于在已有表中添加列。在 TiDB 中,ADD COLUMN 为在线操作,不会阻塞表中的数据读写。

● 不支持在一条语句中同时添加多列;

● 不支持将新添加的列设为 PRIMARY KEY;

● 不支持将新添加的列设为 AUTO_INCREMENT。

2. ADD INDEX

ALTER TABLE.. ADD INDEX 语句用于在已有表中添加一个索引。在 TiDB 中,ADD INDEX 为在线操作,不会阻塞表中的数据读写。

● 不支持 FULLTEXT,HASH 和 SPATIAL 索引;

● 不支持降序索引(类似于 MySQL 5.7);

● 目前尚不支持在一条中同时添加多个索引;

● 无法向表中添加 CLUSTERED 类型的 PRIMARY KEY。

3. ALTER TABLE

3.1 ALTER TABLE 语句用于对已有表进行修改,以符合新表结构。ALTER TABLE 语句可用于:

●  ADD,DROP,或 RENAME 索引;

●  ADD,DROP,MODIFY 或 CHANGE 列。

3.2 TiDB 中的 ALTER TABLE 语法主要存在以下限制:

● 不支持在单个 ALTER TABLE 语句中进行多个更改;

● 不支持主键列上 Reorg-Data 类型的变更;

● 不支持分区表上的列类型变更;

● 不支持生成列上的列类型变更;

● 不支持部分数据类型(例如,部分时间类型、Bit、Set、Enum、JSON 等)的变更,因为 TiDB 中的 CAST 函数与 MySQL 的行为存在兼容性问题;

● 不支持空间数据类型。

4. ALTER INDEX

ALTER INDEX 语句用于修改索引的可见性,可以将索引设置为 Visible 或者 Invisible。设置为 Invisible 的索引即不可见索引 (Invisible Index) 由 DML 语句维护,不会被查询优化器使用。

5. CHANGE COLUMN

ALTER TABLE.. CHANGE COLUMN 语句用于在已有表上更改列,包括对列进行重命名,和将数据改为兼容类型。

从 v5.1.0 版本起,TiDB 开始支持 Reorg 数据的类型变更,包括但不限于:

● 从 varchar 转换为 bigint;

● decimal 精度修改;

● 从 varchar(10) 到 varchar(5) 的长度压缩。

6. MySQL 兼容性

● 不支持在单个 ALTER TABLE 语句中进行多个更改;

●不支持主键列上 [Reorg-Data](/sql-statements/sql-statement-modify-column.md#Reorg-Data Change) 类型的变更;

● 不支持分区表上的列类型变更;

● 不支持生成列上的列类型变更;

● 不支持部分数据类型(例如,部分时间类型、Bit、Set、Enum、JSON 等)的变更,因为TiDB 中 CAST 函数与 MySQL 的行为存在兼容性问题。

本 文 原 创 来 源:IT那活儿微信公众号(上海新炬王翦团队)