
# TaurusDB库表设计规范
- 所有创建的MySQL表必须为InnoDB引擎，适配MySQL的其他引擎不支持事务。
- 小数类型建议使用DECIMAL，禁止使用FLOAT和DOUBLE。 FLOAT和DOUBLE在存储的时候，存在精度损失的问题，很可能在值比较的时候得到的结果有误。如果存储的数据范围超过DECIMAL的范围，建议将数据拆成整数和小数分开存储。
  
- 禁用保留字，如DESC、RANGE、MATCH、DELAYED等。 社区MySQL 8.0的保留字与关键字请参见[关键字和保留字](https://dev.mysql.com/doc/refman/8.0/en/keywords.html)。
  TaurusDB的保留关键字在兼容社区MySQL8.0的基础上，新增了部分保留关键字，需要在业务使用中避免使用保留关键字来命名。
  TaurusDB新增的关键字和保留字如[表1]所示。
   表1TaurusDB新增的保留关键字 
  | **保留字**      | **相关场景**     |
  |:---|:---|
  | EXTRA_HEALTH | 高可用          |
  | PBS          | 备份恢复         |
  | REDO         | 主从复制         |
  | SLICEID      | 共享存储         |
  | SLOWIO       | 共享存储         |
  | SPACEUSAGE   | 共享存储         |
  | RDS_INSTANT  | 回收站          |
  | RECYCLE_BIN  | 回收站          |
  | RDS_RECYCLE  | 回收站          |
  | RDS_TAC      | 回收站          |
  | RDS_GDB_CTRL | RegionlessDB |
     
  
- 数据表必须有主键，可以使用业务相关，有序且具有唯一性的字段作为主键，也可以使用业务无关的自增长字段作为主键。无主键容易出现主库执行速度慢及复制延迟问题。 当MySQL中的自增主键（例如 AUTO_INCREMENT）达到其数据类型的上限时，会导致新的插入操作失败，参考[MySQL自增主键达到上限的解决方案](https://support.huaweicloud.com/taurusdb_faq/taurusdb_faq_0160.html)处理。
  删除MySQL表时，如果表中有外键，设置了外键关联，删除时会报错"ERROR 1451 (23000): Cannot delete or update parent row: a foreign key constraint fails"，参考[存在外键的表无法删除](https://support.huaweicloud.com/trouble-taurusdb/taurusdb_trouble_0207.html)处理。
  
- 表字段必须有默认值加NOT NULL，数字类型默认值推荐给0，VARCHAR等字符类型默认值推荐空字符串''。
- 分区表存在如下缺点，使用中避免使用分区表，如有需要，可以使用多个独立的表代替。
  - DDL操作需要锁定所有分区，导致所有分区上操作都被阻塞。
  
  - 当表数据量较大时，对分区表进行DDL或其他运维操作难度大风险高。
  
  - 分区表使用较少，存在未知风险。
  
  - 当单台服务器性能无法满足时，对分区表进行分拆的成本较高。
  
  - 当分区表操作不当导致访问所有分区时，会导致严重的性能问题。
   
- 建议表包含两个字段：CREATE_TIME，UPDATE_TIME，且均为DATETIME类型。
  ![](https://support.huaweicloud.com/usermanual-taurusdb/public_sys-resources/note_3.0-zh-cn.png)
  数据仓库拖取数据时可以利用这两个统一字段无需询问业务。
  在数据库出现意外时可以判断数据进入数据库和修改的时间，在极端情况可以帮助数据恢复的判断。
  
- 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。
  
  - 对**序列性比较强的字段**进行分区，查询时加上范围条件效率会非常高。
  
  - 对于有明显的热点的数据，而且除了这部分数据，其他数据很少被访问到，那么可以将热点数据单独放在一个分区。
  
  - 建议使用数据库代理连接数据库，对于一致性要求不高的场景下，将读业务分流到只读节点。对于查询量比较大情况下，可以通过弹性扩展，增加只读节点数量，提升查询性能。
   
 
