戳蓝字“CSDN云计算”关注我们哦!

转自 | 孤独烟

引言

大家应该知道烟哥最近要(tiao 咳咳咳),嗯,不可描述!
随手讲其中一部分知识,都是一些烟哥自己平时工作的总结以及经验。大家看完,其实能避开很多坑。而且很多问题,都是面试中实打实会问到的!
比如

OK,具体有下面这些问题

  • 1、为什么一定要设一个主键?

  • 2、你们主键是用自增还是UUID?

  • 3、主键为什么不推荐有业务含义?

  • 4、表示枚举的字段为什么不用enum类型?

  • 5、货币字段用什么类型?

  • 6、时间字段用什么类型?

  • 7、为什么不直接存储图片、音频、视频等大容量内容?

  • 8、字段为什么要定义为NOT NULL?

其实上面这些问题,我最早想法是,每个问题都可以啰嗦出一篇文章。后来由于良心发现,烟哥就决定用一篇文章将这些问题都讲明白。
当然,我给的回答可能并非标准答案,毕竟是自己的一些工作总结。各位读者有更好的回答,也欢迎交流!

这里我要说一下,我用mysql只用过innodb存储引擎,其他的引擎真没用过。因此我的回答,都是基于innodb存储引擎中的。

正文

问题1:为什么一定要设一个主键?
回答:因为你不设主键的情况下,innodb也会帮你生成一个隐藏列,作为自增主键。所以啦,反正都要生成一个主键,那你还不如自己指定一个主键,在有些情况下,就能显式的用上主键索引,提高查询效率!

问题2:主键是用自增还是UUID?
回答:肯定答自增啊。innodb 中的主键是聚簇索引。如果主键是自增的,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页。如果不是自增主键,那么可能会在中间插入,就会引发页的分裂,产生很多表碎片!。
上面那句话看不懂没事,大白话一句就是:用自增插入性能好!

另外,附一个测试表给你们,表名带uuid的就是用uuid作为主键。大家看一下就知道性能差距了:

如上图所示,当主键是UUID的时候,插入时间更长,而且占用空间更大!

额,大家千万不要忘了,当你回答自增主键后,想一下《自增主键用完该怎么办?》

ps:这个问题,你要是能把UUID讲出合理的理由也行。

问题3:主键为什么不推荐有业务含义?
回答:有如下两个原因

  • (1)因为任何有业务含义的列都有改变的可能性,主键一旦带上了业务含义,那么主键就有可能发生变更。主键一旦发生变更,该数据在磁盘上的存储位置就会发生变更,有可能会引发页分裂,产生空间碎片。

  • (2)带有业务含义的主键,不一定是顺序自增的。那么就会导致数据的插入顺序,并不能保证后面插入数据的主键一定比前面的数据大。如果出现了,后面插入数据的主键比前面的小,就有可能引发页分裂,产生空间碎片。

问题4:表示枚举的字段为什么不用enum类型?
回答:在工作中表示枚举的字段,一般用tinyint类型。
那为什么不用enum类型呢?下面两个原因
(1)ENUM类型的ORDER BY操作效率低,需要额外操作
(2)如果枚举值是数值,有陷阱
举个例子,表结构如下

CREATE TABLE test (foobar ENUM('0', '1', '2'));

此时,你执行语句

mysql> INSERT INTO test VALUES (1);

查询出的结果为

foobar

0

就产生了一个坑爹的结果。
插入语句应该像下面这么写,插入的才是1

mysql> INSERT INTO test VALUES (`1`);

问题5:货币字段用什么类型?
回答:如果货币单位是分,可以用Int类型。如果坚持用元,用Decimal
千万不要答floatdouble,因为float和double是以二进制存储的,所以有一定的误差。
打个比方,你建一个列如下

CREATE TABLE `t` (
  `price` float(10,2) DEFAULT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8

然后insert给price列一个数据为1234567.23,你会发现显示出来的数据变为1234567.25,精度失准!

问题6:时间字段用什么类型?
回答:此题无固定答案,应结合自己项目背景来答!把理由讲清楚就行!
(1)varchar,如果用varchar类型来存时间,优点在于显示直观。但是坑的地方也是挺多的。比如,插入的数据没有校验,你可能某天就发现一条数据为2013111的数据,请问这是代表2013年1月11日,还是2013年11月1日?
其次,做时间比较运算,你需要用STR_TO_DATE等函数将其转化为时间类型,你会发现这么写是无法命中索引的。数据量一大,是个坑!

(2)timestamp,该类型是四个字节的整数,它能表示的时间范围为1970-01-01 08:00:01到2038-01-19 11:14:07。2038年以后的时间,是无法用timestamp类型存储的。
但是它有一个优势,timestamp类型是带有时区信息的。一旦你系统中的时区发生改变,例如你修改了时区

SET TIME_ZONE = "america/new_york";

你会发现,项目中的该字段的值自己会发生变更。这个特性用来做一些国际化大项目,跨时区的应用时,特别注意!

(3)datetime,datetime储存占用8个字节,它存储的时间范围为1000-01-01 00:00:00 ~ 9999-12-31 23:59:59。显然,存储时间范围更大。但是它坑的地方在于,他存储的是时间绝对值,不带有时区信息。如果你改变数据库的时区,该项的值不会自己发生变更!

(4)bigint,也是8个字节,自己维护一个时间戳,表示范围比timestamp大多了,就是要自己维护,不大方便。

问题7:为什么不直接存储图片、音频、视频等大容量内容?
回答:我们在实际应用中,都是用HDFS来存储文件。然后mysql中,只存文件的存放路径。mysql中有两个字段类型被用来设计存放大容量文件,也就是textblob类型。但是,我们在生产中,基本不用这两个类型!
主要原因有如下两点

  • (1)Mysql内存临时表不支持TEXT、BLOB这样的大数据类型,如果查询中包含这样的数据,在排序等操作时,就不能使用内存临时表,必须使用磁盘临时表进行。导致查询效率缓慢

  • (2)binlog内容太多。因为你数据内容比较大,就会造成binlog内容比较多。大家也知道,主从同步是靠binlog进行同步,binlog太大了,就会导致主从同步效率问题!

因此,不推荐使用textblob类型!

问题8:字段为什么要定义为NOT NULL?
回答:OK,这问题从两个角度来答
(1)索引性能不好

Mysql难以优化引用可空列查询,它会使索引、索引统计和值更加复杂。可空列需要更多的存储空间,还需要mysql内部进行特殊处理。可空列被索引后,每条记录都需要一个额外的字节,还能导致MYisam 中固定大小的索引变成可变大小的索引。                                                                                 —— 出自《高性能mysql第二版》

(2)查询会出现一些不可预料的结果
这里举一个例子,大家就懂了。假设,表结构如下

create table table_2 (
     `id` INT (11) NOT NULL,
    name varchar(20) NOT NULL
)

表数据是这样的

id

name

1

孤独烟

3

null

5

肥朝

7

null

你执行语句

select count(name) from table_2;

你会发现结果为2,但是实际上是有四条数据的!类似的查询问题,其实有很多,不一一列举。
记住,因为null列的存在,会出现很多出人意料的结果,从而浪费开发时间去排查Bug.

总结

希望大家有所收获!
别说了,心好痛!我去找房子了!

福利

扫描添加小编微信,备注“姓名+公司职位”,加入【云计算学习交流群】,和志同道合的朋友们共同打卡学习!

推荐阅读:

  • 做了中台就不会死吗?每年至少40%开发资源是被浪费的!

  • 美女主播变大妈:在bug翻车现场说测试策略

  • 漫画高手、小说家、滑板专家……解锁程序员的另一面!

  • 手把手教你如何用Python模拟登录淘宝

  • 鸿蒙霸榜 GitHub,从最初的 Plan B 到“取代 Android”?

  • 每天超50亿推广流量、3亿商品展现,阿里妈妈的推荐技术有多牛?

真香,朕在看了!

mysql表设计要注意什么?相关推荐

  1. 网络云盘项目——Redis部署、MySQL部署、MySQL表设计

    一.本文目的 本项目分为6篇博客文章完成: 1.项目总体介绍:https://blog.csdn.net/qq_41453285/article/details/107871393. 2.Redis部 ...

  2. mysql 优惠卷表设计_这些年MySQL表设计踩过的坑!

    本文首发于个人微信公众号<andyqian>,期待你的关注! 前言 有朋友在后台留言.希望我能说说我在数据库表设计时踩过的坑.那么,我们今天就来聊聊我在数据库表设计时踩过的坑,以及现在对数 ...

  3. 21 个 MySQL 表设计的经验准则

    前言 作为后端开发,我们经常需要设计数据库表. 今天给大家分享 21 个设计 MySQL 表的经验准则,希望对大家有所帮助. 1. 命名规范 数据库表名.字段名.索引名等都需要命名规范,可读性高(一般 ...

  4. 21个MySQL表设计的经验准则

    前言 作为后端开发,我们经常需要设计数据库表.整理了21个设计MySQL表的经验准则,分享给大家,大家看完一定会有帮助的. 1.命名规范 数据库表名.字段名.索引名等都需要命名规范,可读性高(一般要求 ...

  5. feed mysql表设计_Feed流系统设计实践(一)

    关系内容Feed流 关系内容Feed流简单介绍 在当前任何具有社交场景的app应用中,用户之间会因为很多行为产生关系,例如微信好友的关系,当前各种陌生人社交软件喜欢的关系,微博粉丝与博 主的关系,当前 ...

  6. 【MySQL】MySQL表设计的经验(建议收藏)

    文章目录 前言 1. 命名规范 2. 选择合适的字段类型 3. 主键设计要合理 4. 选择合适的字段长度 5. 优先考虑逻辑删除,而不是物理删除 6. 每个表都需要添加这几个通用字段如主键.creat ...

  7. 数据库 mysql 表设计,数据删除

    文章目录 视频 表设计 一对一 一对一,附加表加外键,外键唯一. 一对多 一对多,两张表,多的表加外键 多对多 多对多,三张表,关系表两个外键 表删除数据 先删除子表(外键),再删除父表(主键) 视频 ...

  8. mysql表设计 列命名_MYSQL数据库字段命名及设计规范

    1.设计原则 1) 标准化和规范化 数据的标准化有助于消除数据库中的数据冗余.标准化有好几种形式,但 Third Normal Form(3NF)通常被认为在性能.扩展性和数据完整性方面达到了最好平衡 ...

  9. 抽奖活动mysql表设计_购物商城数据库设计-商品表设计

    大家好,今天我们来设计一下购物商城的商品表. 我们的目标是表结构能够满足下面这张图的搜索: 在设计表之前,我们先来了解下商品中的两个概念:SPU和SKU SPU SPU(Standard Produc ...

  10. mysql表设计原子性_数据库表设计-原子性

    好的数据结构会影响速度.好的数据库表设计会影响数据库操作效率.特别是数据多的时候,如果表的结构不好的话操作的时候条件(where后的内容)会变的非常复杂. SQL是关系数据库中用到的一种语言.所以,为 ...

最新文章

  1. Docker 搭建elasticsearch 7.6.x集群
  2. Toward Multimodal Image-to-Image Translation(BicycleGAN)图像一对多转换测试
  3. (微信公众号开发《一》OAuth2.0网页授权认证获取用户的详细信息,实现自动登陆)http://blog.csdn.net/liaohaojian/article/details/70175835
  4. zoj 3705 Applications
  5. python遍历data、并输出结果_获取python运行输出的数据并解析存为dataFrame实例
  6. 和AI机器人Alice的一段聊天记录
  7. 三面美团Java岗,java架构师线下培训
  8. 2012微软校园招聘笔试题
  9. 关于 it行业未来 的个人判断
  10. [2019杭电多校第八场][hdu6667]Roundgod and Milk Tea
  11. keepalived基本应用解析
  12. POJ2187 Beauty Contest
  13. CC2540和CC2541蓝牙芯片将升级为蓝牙5.0
  14. 计算机网络原理之运输层
  15. 关于下载文件以及在swagger-ui中遇到的坑
  16. 齐岳多吡啶萘酰亚胺荧光树形分子(PDPN),三萘嵌二苯二酰亚胺类近红外有机光功能分子定制,4-氨基-1, 8-萘酰亚胺类化合物
  17. 360点睛销售开放平台-身份认证-java版
  18. error: Unable to load contents of file list: '/Users/.../Products/Debug-appletvos/myapp.app/Info....
  19. SSM+人才交流平台 毕业设计-附源码221022
  20. element ui dialog custom-class不生效最终解决办法

热门文章

  1. mysql降序后去重_Mysql 数据记录去重后按字段排序
  2. c语言休眠函数useconds类型,带你了解C语言中的Sleep函数(附代码)
  3. 如何反映两条曲线的拟合精度_你知道850加工中心定位精度的检测有哪些吗?
  4. c语言库快速幂函数,C语言 - 快速幂 - 迭代法+递归法 - 详细讲解
  5. 庄小威、陈志坚等9位科学家分享2100万美元奖金:2019年科学突破奖公布
  6. 雷军99亿人民币薪酬创世界纪录,相当于100个库克
  7. 6大设计原则之开闭原则
  8. flink常见算子的一些操作
  9. 基于ansj_seg和nlp-lang的简单nlp工具类
  10. bellman ford 算法 判断是否存在负环