mysql datetime 后面带了很多0_面试官:MySQL 表设计要注意什么?

作者 孤独烟来自公众号:孤独烟

引言

大家应该知道烟哥最近要(tiao 咳咳咳),嗯,不可描述!

随手讲其中一部分知识,都是一些烟哥自己平时工作的总结以及经验。大家看完,其实能避开很多坑。而且很多问题,都是面试中实打实会问到的!

比如

34bf0376c0048f37176125ef3672cd4e.png

OK,具体有下面这些问题

  • 1、为什么一定要设一个主键?
  • 2、你们主键是用自增还是UUID?
  • 3、主键为什么不推荐有业务含义?
  • 4、表示枚举的字段为什么不用enum类型?
  • 5、货币字段用什么类型?
  • 6、时间字段用什么类型?
  • 7、为什么不直接存储图片、音频、视频等大容量内容?
  • 8、字段为什么要定义为NOT NULL?

其实上面这些问题,我最早想法是,每个问题都可以啰嗦出一篇文章。后来由于良心发现,烟哥就决定用一篇文章将这些问题都讲明白。

当然,我给的回答可能并非标准答案,毕竟是自己的一些工作总结。各位读者有更好的回答,也欢迎交流!

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

正文

问题1:为什么一定要设一个主键?

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

问题2:主键是用自增还是UUID?

回答:肯定答自增啊。innodb 中的主键是聚簇索引。如果主键是自增的,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页。如果不是自增主键,那么可能会在中间插入,就会引发页的分裂,产生很多表碎片!。

上面那句话看不懂没事,大白话一句就是:用自增插入性能好!

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

cc7df6a87e8f082477494a3005debcf8.png

如上图所示,当主键是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);

查询出的结果为

foobar0

就产生了一个坑爹的结果。

插入语句应该像下面这么写,插入的才是1

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

问题5:货币字段用什么类型?

回答:如果货币单位是分,可以用Int类型。如果坚持用元,用Decimal。

千万不要答float和double,因为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中有两个字段类型被用来设计存放大容量文件,也就是text和blob类型。但是,我们在生产中,基本不用这两个类型!

主要原因有如下两点

  • (1)Mysql内存临时表不支持TEXT、BLOB这样的大数据类型,如果查询中包含这样的数据,在排序等操作时,就不能使用内存临时表,必须使用磁盘临时表进行。导致查询效率缓慢
  • (2)binlog内容太多。因为你数据内容比较大,就会造成binlog内容比较多。大家也知道,主从同步是靠binlog进行同步,binlog太大了,就会导致主从同步效率问题!

因此,不推荐使用text和blob类型!

问题8:字段为什么要定义为NOT NULL?

回答:OK,这问题从两个角度来答

(1)索引性能不好

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

(2)查询会出现一些不可预料的结果

这里举一个例子,大家就懂了。假设,表结构如下

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

表数据是这样的

969f10b3e57c23edd3d58a9a1445f027.png

你执行语句

select count(name) from table_2;

你会发现结果为2,但是实际上是有四条数据的!类似的查询问题,其实有很多,不一一列举。

记住,因为null列的存在,会出现很多出人意料的结果,从而浪费开发时间去排查Bug.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/564390.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

poi 顺序解析word_JavaPOI解析word提取数据到excel

Java POI解析Word提取数据存储在Excel一、了解POIPOI以前有了解,这次需求是解析word读取其中标题,还有内容赛选获取自己想要的内容经过两天的学习,开始熟悉Java这么读取word和解析。本文中运用是读取整个页面模块的range,通过对ra…

android studio viewo,Android Studio 之 ViewModel

ViewModel 是 JetPack 类库中的一个功能,可以保存控件的状态 ,在整个Activity 生命周期中,状态不会失效如屏幕翻转时,状态可保留,不会失效!与 LiveData 配合使用!配合 Room 进行 Sqlite 操作数据…

git安装 perl ubuntu_ubuntu下安装git

最近在做自己的个人博客项目,部署在阿里云主机上,系统为ubuntu 16.04.4。项目开发在自己的Windows电脑上,每次项目进行改动后都需要手动上传文件到服务器上,感觉很是麻烦。所以准备在服务器上安装git并关联github账号,…

android 图片传递,如何使用包在Android活动之间传递图像(位图)?

按照EboMike的建议,我将位图保存在一个名为MyImage在我的应用程序的内部存储中,无法访问我的其他应用程序。这部分的代码如下:public String createImageFromBitmap(Bitmap bitmap) {String fileName "myImage";//no .png or .jpg…

php调用restful接口_分享一个PHP调用RestFul接口的函数

/*** [http 调用接口函数]* Date 2016-07-11* Author GeorgeHao* param string $url [接口地址]* param array $params [数组]* param string $method [GET\POST\DELETE\PUT]* param array $header [HTTP头信息]* param integer $timeout [超时时间]* return [type] [接口返回数…

graphpad如何换柱状图与折线图能否混合一起_excel柱状图加折线图组合怎么做,原来是这样的...

今天小编教大家如Excel柱状图加折线图组合怎么做。操作方法01以下图表格为例,我们就用这个年份、销量和增长率来做个柱状图与折线图的组合形式图表。首先,拖动鼠标,选中销量和增长率两项的所有数据。02选中数据后,点击上面菜单栏中…

ucache灾备云报价_UCACHE灾备云功能

(IDC彭帅)未来互联网、移动互联网、物联网、工业互联网行业将迎来迅猛发展,作为数据安全最后一道防线,灾备技术具有巨大的应用前景。当前,企业的每一个业务系统所关心的最主要问题就是业务如何连续运转的问题,这其中,既…

html下拉框选择后自动刷新,html select 下拉框刷新页面后保留上一次选择的值

常用场景组合条件查询点击查询/刷新页面,包括input输入框\复选框等在内的组件都可以通过前端设置value"{{id}}",后台发送的数据包括对应的字段,从而实现刷新后保留上一次的值,提高用户体验,但是发现select不…

极域电子书包课堂管理系统_朝阳群众说小康 | 从黑板课本到VR互动课堂、电子书包,朝阳的课堂如此有趣!...

教育变迁一支粉笔、一块黑板、一本教材曾经是教师上课沿袭了几十年的“三大法宝”随着时代发展当科技遇上了教育课堂上又会擦出什么样的火花呢?今天,小朝带你走进咱朝阳的校园一探究竟不一young的朝阳教育近日,教育部“基于教学改革、融合信息…

MySQL的优点

MySQL 使用的 SQL 语言是用于访问数据库的最常用的标准化语言。 由于 MySQL 数据库体积小、速度快、总体拥有成本低、开放源代码,其有着广泛的应用,一般中小型网站的开发都选择 MySQL 作为网站数据库。由于其社区版的性能卓越,因此搭配 PHP …

鸿蒙行车记录仪,百度导航新增行车记录仪功能 可消除碰瓷风险

年关将至,市区内各类大型商场、超市、菜市场等地人流密集,此类地点非常容易出现意外状况,市民在驾车出行时千万要提高注意力,警惕碰瓷者倒在你面前。如果事先装载行车记录仪,就能避免一桩“冤案”的发生。日前&#xf…

安装引导黑屏_给电脑安装系统老是装不上,重启就黑屏,原来是这项设置在作怪!...

很多人和我反映说:给电脑安装系统重启电脑后就黑屏无法正确解压系统,这个问题大家有没有遇到呢?遇到这个问题的人可能会认为自己电脑的硬盘坏了,明明已经把需要的Windows操作系统拷贝到硬盘已经成功了,重启电脑准备解压…

MySQL创建数据库

MySQL 中&#xff0c;我们可以使用 CREATE DATABASE 语句创建数据库&#xff0c;语法格式如下&#xff1a; CREATE DATABASE [IF NOT EXISTS] <数据库名> [[DEFAULT] CHARACTER SET <字符集名>] [[DEFAULT] COLLATE <校对规则名>];[ ]中的内容是可选的。语…

如果表不存在则创建_当创建一个文件的时候,操作系统发生了什么

操作文件是我们平时经常有的操作。但是我们可能并不是很了解他们原理&#xff0c;比如为什么删除一个很大的文件&#xff0c;会非常快&#xff1f;创建一个文件的时候&#xff0c;系统发生了什么&#xff1f;为什么删除的文件&#xff0c;还可以恢复&#xff1f;知其然知其所以…

两个html页面之间通讯,面试官:前端跨页面通信,你知道哪些方法?

引言在浏览器中&#xff0c;我们可以同时打开多个Tab页&#xff0c;每个Tab页可以粗略理解为一个“独立”的运行环境&#xff0c;即使是全局对象也不会在多个Tab间共享。然而有些时候&#xff0c;我们希望能在这些“独立”的Tab页面之间同步页面的数据、信息或状态。正如下面这…

MySQL查看或显示数据库

MySQL 中&#xff0c;可使用 SHOW DATABASES 语句来查看或显示当前用户权限范围以内的数据库。查看数据库的语法格式为&#xff1a; SHOW DATABASES [LIKE 数据库名];语法说明如下&#xff1a; LIKE 从句是可选项&#xff0c;用于匹配指定的数据库名称。LIKE 从句可以部分匹配…

默认选中_双击dwg图纸,怎么设置默认天正打开?

文尾左下角阅读原文看视频教程好课推荐&#xff1a;零基础CAD&#xff1a;点我CAD室内&#xff1a;点我 周站长CAD&#xff1a;点我CAD机械&#xff1a;点我 Bim教程&#xff1a;点我CAD建筑&#xff1a;点我CAD三维&#xff1a;点我全屋定制&#xff1a;点我 ps教程&#xff1…

MySQL修改数据库

MySQL 中&#xff0c;使用 ALTER DATABASE 来修改已经被创建或者存在的数据库的相关参数。修改数据库的语法格式为&#xff1a; ALTER DATABASE [数据库名] { [ DEFAULT ] CHARACTER SET <字符集名> | [ DEFAULT ] COLLATE <校对规则名>}语法说明如下&#xff1a…

临颖一高2021高考成绩查询,临颍一高举办2021年决战高考百日冲刺誓师大会

原标题&#xff1a;临颍一高举办2021年决战高考百日冲刺誓师大会3月4日&#xff0c;县一高举办2021年决战高考百日冲刺誓师大会&#xff0c;擂响了百日冲刺的战鼓&#xff0c;全校5800余名师生参加誓师大会。誓师大会在激昂雄壮的国歌声中拉开了序幕。县一高校长巩海生满怀深情…

ddos源码 ntp_详解 NTP反射型DDos攻击

简介NTP Reply Flood Attack (NTP射型Ddos 攻击)以下简称NTP_Flood是一种利用网络中 NTP服务器的脆弱性(无认证&#xff0c;不等价数据交换&#xff0c;UDP协议)&#xff0c;来进行DDos行为的攻击&#xff0c;本文将就此种攻击的产生原因&#xff0c;利用方法等进行阐述&#x…