TiDB 库表设计和使用规范
作者: 代晓磊 _Mars 原文来源:https://tidb.net/blog/d61d28a8
库表命名规范
表名规范
字段名规范 禁止使用 mysql 的关键字,比如 order,group、show、slave 等
索引命名规范
注:库名、表名、字段名、索引名都小写,长度都限制在 64 字符以内(TiDB 限制)
表结构设计规范
1、TiDB 表主键
每张表一定要有一个主键,跟 MySQL 建表不同,主键不一定是 int/bigint 自增,如果有写入性能问题更不见建议使用自增主键(写热点),可以使用 UUID、字符串、联合字段来做主键时需要在建表语句后面添加下面 2 个参数来打散 region:
另外对于写入量大的可以使用 auto random 主键来提升写入性能,如下
2、必须标注表和字段的 comment
3、建表时提供表示创建时间和更新时间的 created*at updated*at 字段,并使用 mysql 内建的 CURRENT_TIMESTAMP 作为默认值,数仓的增量数据抽取依赖这 2 个字段。
4、字段能定义为非空的就定义为非空
5、字段设置了 NOT NULL 的,一定要指定默认值,否则字段写入时肯定报错。
6、对于内容类字段优先考虑使用 utf8mb4 编码以支持 emoji 表情文字,如果预期数据量较大,尽量将内容较长且不用于查询的 BLOB、TEXT 列单独建表。
7、关于分区表使用,一般日志类、报表类业务都喜欢用基于时间的 range 分区表 (可以用),Hash 分区(用的少)可以用于大量写入场景下的数据打散,List 分区(5.X 版本才有,实验特性,慎用!)
8、字段类型选择,目的:合适的类型,合适的大小
SQL 使用规范
1、TIDB 索引使用
联合索引使用:如果线上存在复合条件查询,务必通过复合索引,如果 SQL 查询的字段以及 where 条件覆盖到查询中的所有条件字段形成覆盖索引的话,性能更佳。
务必将 ORDER BY 中的列覆盖在索引中,不然很容易出现对性能影响 sort。
不推荐建立过多的索引,禁止冗余的索引、不使用的索引需要及时删除。推荐扩展现有索引,而不是建立新的索引。过多的索引容易影响优化器决策而形成严重性能问题。1) 单张表中索引数量不超过 5 个;
2、SQL 语句编写规范
避免使用 select *,就算要用所有的表字段也建议都列出来,因为如果程序没有 table 字段对应关系的配置,表的字段增加删除都会导致业务取到的结果有问题,另外只查自己想要的字段也能降低 SQL 执行时间中的网络传输时间(可以拿带 text 类型的表对比测试)。
禁止执行没有 where 条件的表 select/DML
避免在查询中使用 OR,OR 两边的条件都需要有索引并且会产生会使用到性能较差的 index merge
对于核心的 OLTP 业务,线上不建议使用 JOIN 操作,有可能引发集群抖动。
对于一些重要数据的“删除”,不推荐使用 DELETE,对于内容类数据优先考虑 update 软删除。
推荐 Batch insert,根据表字段的情况,batch size 控制在一定的数量,不建议太多 (事务过大,引发性能问题或者报错)。
DML SQL 要避免 TiDB 的大事务限制 (单 KV:6M,默认事务 100M 可调)
业务 RD 喜欢 begin;多个 DML SQL;commit;在乐观事务的情况下,默认只支持 5000 条 DML,可以通过 stmt-count-limit 调整。另外也不建议多 DML SQL 一次 commit 这种方式写入数据。
TIDB 的 DDL 不支持多列操作,所以:alter table 不支持添加多个字段、多个索引。
最后强调下:禁止 RD 直连线上 DB 进行 SQL 操作 (如果是 DBA,肯定在职业经历中碰到过 RD 误删除要恢复的事故),公司需要提供自研 or 开源的 SQL 审核和执行平台来解决问题。
3、不能用到索引的 6 种情况
TIDB 与 MySQL 兼容性区别
推进大容量 mysql 或者分库分表业务迁移 TiDB 本来是好事儿,但是还是需要将兼容性区别也列入到 TIDB 规范中,这样业务会提前了解并对自己业务进行修改。
1、TiDB 的自增 id 不连续,存在 id 为 1/30001/60001 的数据都是同一时刻写入的,所以业务基于 id order by 的规则需要调整为基于时间排序。
2、不支持外键、存储过程、触发器、全文索引等
3、排序规则不同 ( collation 是在字符集中比较字符以及字符排序顺序的规则)。在默认的二进制排序规则 ( utf8mb4_bin ) 中,比较 A 和 a 的结果是不一样的,mysql 的排序规则是:utf8mb4_general_ci,where str=‘A’跟‘a’都能查到相同的结果,TiDB 在 4.0 的高版本和 5.X 支持了大小写不区分的排序规则,创建表时需要“显示”设定排序规则。
4、再次强调:TiDB 不能在单条 ALTER TABLE 语句中完成多字段操作。例如,不能在单个语句中添加多个列或索引,否则,可能会输出 Unsupported multi schema change 的错误 ; 这个在使用基于 mysql 的审核平台时会经常遇到,需要修改平台进行兼容。
5、4.0 的 TiDB 不支持添加 / 删除主键,除非开启了 alter-primary-key 配置项 ;
6、不支持将字段类型修改为其超集,例如不支持从 INTEGER 修改为 VARCHAR,或者从 TIMESTAMP 修改为 DATETIME
7、更改 / 修改数据类型时,不支持“有损更改”,比如 bigint→int,varchar(200)→varchar(100)
8、TIDB 的事务限制,单 kv 最大支持 6M,也就是说 mysql 表中 mediumtext 类型 (最大支持 16M) 迁移到 tidb 时可能会因为记录过大而写入失败。
9、TIDB 默认支持 100M size 的事务,这个默认值可以通过配置文件中的配置项 txn-total-size-limit 进行修改,最大支持 10 GB 的事务。
更详细的兼容性区别,详见官网链接 https://docs.pingcap.com/zh/tidb/stable/tidb-limitations
版权声明: 本文为 InfoQ 作者【TiDB 社区干货传送门】的原创文章。
原文链接:【http://xie.infoq.cn/article/cc9b947373ccbb64376ed15b9】。文章转载请联系作者。
评论