这种固定选项值的字段,推荐使用 ENUM 枚举字符串类型,外加 SQL_MODE 的严格模式
在MySQL 8.0.16 以后的版本,可以直接使用check约束机制,不需要使用enum枚举字段类型
而且我们一般在定义枚举值的时候使用"Y","N"等单个字符,并不会占用很多空间。但是如果选项值不固定的情况,随着业务发展可能会增加,才不推荐使用枚举字段。 索引个数限制
错误的设计规范:限制每张表上的索引数量,一张表的索引不能超过 5 个
MySQL 单表的索引没有个数限制,业务查询有具体需要,创建即可,不要迷信个数限制 子查询的使用
错误的设计规范:避免使用子查询
其实这个规范对老版本的 MySQL 来说是对的,因为之前版本的 MySQL 数据库对子查询优化有限,所以很多 OLTP 业务场合下,我们都要求在线业务尽可能不用子查询。
然而,MySQL 8.0 版本中,子查询的优化得到大幅提升,所以在新版本的MySQL中可以放心的使用子查询。
子查询相比 JOIN 更易于人类理解,比如我们现在想查看2020年没有发过文章的同学的数量
SELECT COUNT(*)
FROM user
WHERE id not in (
SELECT user_id
from blog
where publish_time >= "2020-01-01" AND publish_time <= "2020-12-31"
)
可以看到,子查询的逻辑非常清晰:通过 not IN 查询文章表的用户有哪些。
如果用 left join 写
SELECT count(*)
FROM user LEFT JOIN blog
ON user.id = blog.user_id and blog.publish_time >= "2020-01-01" and blog.publish_time <= "2020-12-31"
where blog.user_id is NULL;
可以发现,虽然 LEFT JOIN 也能完成上述需求,但不容易理解。
我们使用 explain查看两条 sql 的执行计划,发现都是一样的
通过上图可以很明显看到,不论是子查询还是 LEFT JOIN,最终都被转换成了left hash Join,所以上述两条 SQL 的执行时间是一样的。即,在 MySQL 8.0 中,优化器会自动地将 IN 子查询优化,优化为最佳的 JOIN 执行计划,这样一来,会显著的提升性能。 总结
阅读完前面的内容相信大家对 MySQL 已经有了新的认知,这些常见的错误可以总结为以下几点: