关系型数据库实践

关系型数据库是绝大多数系统的数据核心,这个关键设施也往往是性能的瓶颈。以下是一些使用建议。

按业务场景设计表结构

业务场景: 一个mysql的用户表,1000万条记录,如何查询出当天生日的用户?

表结构通用规则

  • 所有字段必须非空而且有默认值。
  • 一般都有创建时间和更新时间字段,mysql5.6+ 支持数据库本身更新此字段。
  • 尽可能不使用TEXT、BLOB类型.
  • 表字符集尽量选择UTF8MB4,mysql的utf8不是标准的字符集,utf8mb4可以存储表情字符。
  • 索引字段尽可能使用int/long, 索引为字符型不能超过32个字符。
  • 注释尽量清楚
  • 建表的时候应该考虑最终的数据量,mysql单表应该不超过1000万,分布式数据库按业务字段分区。
  • 不使用外键,尽量少用联合唯一束缚。联合主键酌情使用。

查询最佳实践

互联网业务场景,数据库瓶颈一般出现在查询。

  • 查询一般不关联超过3个表。
  • 查询扫码记录数超过10万条,必须命中索引。
  • 避免使用inner join,left join 语句中的主表应该是结果数据量最少的表。
  • where语句最左原则,最靠近where的条件应该是索引,应该是可以最大限度缩小查询范围的条件。
  • 避免破坏索引的不规范语句,比如id=‘1’,类型转换会忽略索引,比如 like %xxx%,模糊匹配也会破坏索引。
  • 尽量少用数据库特殊函数,影响性能也不好迁移。
  • 尽量少用group by/max/sum,如果是高频调用的sql, 意味着表结构不合理。
  • 禁止使用 select *,不知道需要返回的字段,意味着不理解业务。

通用最佳实践

  • 查询语句复杂,往往是缺状态字段或者缺统计表。
  • 应该手写sql,反对使用所谓面向对象的orm中间件,比如hibernate,mybaits-plus。
  • 单个api的sql语句一般不超过3条。 3次以上数据库交互,响应速度就很差。
  • 读写分离,实时性要求不高的查询,应该走从库。互联的mysql 一般是1主3+从.
  • 数据强一致,并且并发高的情况下(间隙锁),事务提交不能解决问题的话,考虑乐观事务(version字段)以及分布式全局锁(redis/zookeeper)

技术管理-管理、人性与OKR
元宇宙的一些判断