更新时间:2024-11-06 GMT+08:00

GaussDB(for MySQL)库表设计规范

  • 所有创建的MySQL表必须为InnoDB引擎,适配MySQL的其它引擎不支持事务。
  • 小数类型建议使用DECIMAL,禁止使用FLOAT和DOUBLE。

    FLOAT和DOUBLE在存储的时候,存在精度损失的问题,很可能在值比较的时候得到的结果有误。如果存储的数据范围超过DECIMAL的范围,建议将数据拆成整数和小数分开存储。

  • 禁用保留字,如DESC、RANGE、MATCH、DELAYED等。

    社区MySQL 8.0的保留字与关键字请参见关键字和保留字

    GaussDB(for MySQL)的保留关键字在兼容社区MySQL8.0的基础上,新增了部分保留关键字,需要在业务使用中避免使用保留关键字来命名。

    GaussDB(for MySQL)新增的关键字和保留字如表1所示。
    表1 GaussDB(for MySQL)新增的保留关键字

    保留字

    相关场景

    EXTRA_HEALTH

    高可用

    PBS

    备份恢复

    REDO

    主从复制

    SLICEID

    共享存储

    SLOWIO

    共享存储

    SPACEUSAGE

    共享存储

    RDS_INSTANT

    回收站

    RECYCLE_BIN

    回收站

    RDS_RECYCLE

    回收站

    RDS_TAC

    回收站

    RDS_GDB_CTRL

    RegionlessDB

  • 数据表必须有主键,可以使用业务相关,有序且具有唯一性的字段作为主键,也可以使用业务无关的自增长字段作为主键。
  • 表字段必须有默认值加NOT NULL,数字类型默认值推荐给0,VARCHAR等字符类型默认值推荐空字符串''。

    无主键不仅容易导致主库执行速度慢和复制延迟问题。

  • 避免使用分区表,如有需要,可以使用多个独立的表代替。

    分区表的缺点:

    • DDL操作需要锁定所有分区,导致所有分区上操作都被阻塞。
    • 当表数据量较大时,对分区表进行DDL或其他运维操作难度大风险高。
    • 分区表使用较少,存在未知风险。
    • 当单台服务器性能无法满足时,对分区表进行分拆的成本较高。
    • 当分区表操作不当导致访问所有分区时,会导致严重的性能问题。
  • 建议表包含两个字段:CREATE_TIME,UPDATE_TIME, 且均为DATETIME类型。

    数据仓库拖取数据时可以利用这两个统一字段无需询问业务。

    在数据库出现意外时可以判断数据进入数据库和修改的时间,在极端情况可以帮助数据恢复的判断。

  • VARCHAR是可变长字符串,不预先分配存储空间,长度不要超过2048。

    如果存储长度大于此值,定义字段类型为TEXT,或者独立出来一张表,用主键来对应,避免影响其他字段索引效率。

  • 表单行行内长度不得超过1024字节。
  • 控制单表字段数量,字段上限50个。
  • 如果存储的字符串长度几乎相等,使用CHAR定长字符串类型。
  • 字段允许适当跨表冗余,以避免关联查询,提高查询性能,但必须考虑数据一致。

    冗余字段应遵循:

    • 不是频繁修改的字段。
    • 不是VARCHAR超长字段和TEXT字段。
  • 合适的存储长度(不建议使用LONG TEXT, BLOB等长类型字段),不但节约数据库表空间、节约索引存储,更重要的是提升检索速度。
  • 所有的字符存储与表示,均以UTF-8或者utf8mb4编码,表和字段需要有注释信息。
  • 尽量避免使用大事务。

    如果在一个事务里进行多个SELECT或UPDATE语句,如果是高频事务,会严重影响MySQL并发能力,因为事务持有的锁等资源只在事务ROLLBACK/COMMIT时才能释放。但同时也要评估数据写入的一致性。

  • 由于全文索引局限性较多,不建议使用全文索引功能。
  • 对于超大表,还需要遵循以下规范。
    • 尽量使用TINYINT、SMALLINT、MEDIUM_INT作为整数类型而非INT,如果非负则加上UNSIGNED,总体来看就是,在满足业务演进的前提下,字段类型尽量短。
    • VARCHAR的长度只分配真正需要的空间。

      示例:

      CREATE TABLE T1 (A VARCHAR(255));

      优化为:

      CREATE TABLE T1 (A VARCHAR(满足业务的长度));

    • 使用枚举或整数代替字符串类型。
    • 尽量使用TIMESTAMP而非DATETIME。
    • 单表不要有太多字段,建议在20以内。
    • 尽量不用UNIQUE,由程序保证约束。
    • 用整型来存IP。
    • 序列性比较强的的字段进行分区,查询时加上范围条件效率会非常高;
    • 对于有有明显的热点的数据,而且除了这部分数据,其他数据很少被访问到,那么可以将热点数据单独放在一个分区。
    • 建议使用数据库代理连接数据库,对于一致性要求不高的场景下,将读业务分流到只读节点。对于查询量比较大情况下,可以通过弹性扩展,增加只读节点数量,提升查询性能。