三种常见的MySQL数据库设计最佳实践

曾经有一位开发者说过一句话,很有道理:一个功能的实现,在数据量或并发量比较小的时候,怎么样都可以,但一旦将数据量和并发量逐步扩大,问题就会逐步显现出来了。

这篇文章,就带大家梳理一下,在MySQL的数据库表设计中常见的三类错误。

选择适合数据类型和长度

当我们把一个表的ID列定义为INT数据类型时,那么就要思考一个问题,这个表的数据量是否会随着业务的发展而快速增长。

当这个表只是一个简单的配置表或基础数据表时,设置为INT类型或许没有问题。当一个表存储的是历史记录或日志记录时,数据量必然会随着业务的发展而快速增长,该列的空间会很快被耗尽,导致系统部分功能不可用。

针对此种情况,可提前预测业务发展,将ID字段设置为BIGINT类型。

这一条规则不仅适用于数值类型,还适用于字符串类型。例如,如果试图在一个VARCHAR(255) 的列中写入一个包含300个字符的字符串,而MySQL正处于严格模式(Strict Mode,默认为开启状态),那么MySQL会返回错误并拒绝写入。如果MySQL没有开启严格模式,超过长度的数据会被截断,从而导致可能重要的数据丢失。

与数据不足问题相反,列数据的存储空间过多也可能是问题所在。虽然不会像存储空间不足的情况那样严重,但过度预留空间会带来存储和性能方面的影响。

比如,假设我们需要存储一个五位的编码,这种情况可以使用 INT 数据类型(存储 32 位整数)来存储,但这样分配的存储远远超过实际需求。此时,使用 SMALLINT 会是更好的选择,因为它存储的是 16 位整数,足够存储这个五位的编码。

存储分配过多会引起的两方面问题:

  • 存储空间:过度分配类型对单个字段来说存储成本变化可能不是非常显著,但对于大型表、高频读取或写入的场景来说,会对磁盘 I/O 和缓存效率产生影响。
  • 索引性能:当字段被用于索引时,字段的存储类型大小直接影响索引的存储和查询性能。使用较小的数据类型能提高索引效率。

所以,在选择数据类型时我们需要考虑:不仅要满足当前数据量的需求,还要能支持未来潜在的增长。

缺失索引或冗余索引

索引在 MySQL 中通过构建一个经过优化的结构来加速数据访问,使查询更快地返回符合条件的数据。如果没有利用索引,当执行未分页或未定义LIMIT的查询时,MySQL 会对表执行扫描操作。这意味着它会从表的第一行开始逐行读取,直到找到匹配条件的所有行。如果某个被频繁访问的大表没有使用索引,从表扫描会带来巨大的性能损失。

关于索引部分的内容,可以参考前面的文章,特别是《学习MySQL绕不开的两个基础概念:聚集索引与非聚集索引》一文。

但与此同时,如果索引过多也会带来另一方面的问题。

创建的每个索引都会占用额外的存储空间,因此冗余或未使用的索引会直接增加存储成本。此外,当表中的数据被更新或插入时,MySQL 会更新这些索引及其相关统计信息,以确保索引的准确性。这可能是一项耗时的操作,可能导致不良的用户体验。

关于索引增加存储成本部分,可参考阅读《MySQL之进阶:一篇文章搞懂MySQL索引之B+树》一文。

选择合适的存储结构

过去十多年,越来越多的公司选择使用NoSQL来存储半结构化数据,以满足快速处理大量数据的需求。这类数据存储已经有很多专业解决方案,但实际上 MySQL 在这方面也很有能力。当隔壁字段需要采用半结构化数据存储,又没必要引入NoSQL时,可考虑采用MySQL提供的能力来存储。

大多数存储在数据库中的半结构化数据通常是以JSON的形式表示。最简单的方式是将JSON字符串存储在TEXT类型的列中,但这并不是最佳选择。

MySQL支持一种专门用于存储JSON的列类型:JSON。这种类型会将JSON数据以高效的二进制格式存储。

使用JSON而非TEXT类型有两个关键好处:

  • 第一,最为广泛使用的MySQL存储引擎 InnoDB 原生支持基于JSON对象内容的查询和过滤,这避免了在应用代码中手动过滤结果的需求。
  • 第二,MySQL还支持基于JSON数据创建索引,使得查询更加高效,可以加速基于JSON数据返回结果的操作。

关于MySQL的JSON类型创建索引可参考阅读《如何为MySQL中的JSON字段设置索引》一文。

小结

有一定开发经验的朋友都知道,数据库是系统最容易形成性能瓶颈问题的点,因此,针对数据库的设计和深思熟虑绝对是值得在前期投入的事。否则,一旦有大量线上数据,再进行修改将是一件非常复杂和有风险的事。希望这篇文章能够为大家提供帮助,同时也能启发大家去思考更多的数据库设计优化。

相关推荐
寒士obj2 小时前
MyCat实现分库分表
数据库
没有bug.的程序员2 小时前
MySQL 安全与权限管理:从基础到生产级安全实践
java·mysql·安全·adb·权限
LunarCod2 小时前
Hexo搭建/部署个人博客教程
后端·hexo·个人博客·vercel
Savvy..2 小时前
Redis 黑马点评-商户查询缓存
数据库·redis·缓存
可DRAK鸦|・ω・`)2 小时前
ArcGIS数据迁移问题汇总(postgresql)
数据库·postgresql
奶糖 肥晨2 小时前
批量重命名技巧:使用PowerShell一键整理图片文件命名规范
android·服务器·数据库
数据与人3 小时前
MySQL 8.0 InnoDB ReplicaSet 完整配置指南与切换
数据库·mysql·adb
IT_陈寒3 小时前
Vue 3.4 实战:这7个Composition API技巧让我的开发效率飙升50%
前端·人工智能·后端
合作小小程序员小小店4 小时前
web网页开发,在线%推荐算法学院培养计划,图书推荐,基于Python,FlaskWeb,用户和物品推荐MySql
python·mysql·算法·flask·推荐算法