MySQL常见知识点(一)


1.MySQL字段类型

  • 数值型:整型(TINYINT、SMALLINT、MEDIUMINT、INT和BIGINT),浮点型(FLOAT和DOUBLE),定点型(DECIMAL)
  • 字符串类型:CHAR、VARCHAR、TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT、TEXTBLOB、BLOB、MEDIUMBLOB 和 LONGBLOB 等。常用的有CHAR和VARCHAR
  • 时间类型:YEAR、TIME、DATE、DATETIME、TIMESTAMP等

MySQL 常见字段类型总结

整数类型的UNSIGNED属性有什么用?

MySQL中的UNSIGNED属性表示不允许负值的无符号整数,使用UNSIGNED标识可以将正整数的上限提高一倍,因为它不需要储存负数。

比如从0开始的自增主键ID就可以使用UNSIGNED,可以提供多一倍的ID值

CHAR和VARCHAR的区别是什么?

CHAR是定长字符串,VARCHAR是变长字符串。

CHAR在储存时会在右边填充空格以达到指定长度,检索的时候会去掉空格;而VARCHAR只需要1到2个额外字节记录字符串长度,检索时不需要处理。

CHAR适合储存长度较短或者长度都差不多的数据,比如Bcrypt算法,MD5算法加密后的身份证号,手机号之类的信息,而VARCHAR适合记录长度不确定的或差异较大的数据,比如昵称、姓名、文章标题等

CHAR(M)和VARCHAR(M)的M都能代表保存字符的最大值,无论字母、汉字还是数字,都只占一个字符

VARCHAR(100)和VARCHAR(10)的区别是什么?

都是变长类型,最大的储存长度不同,表示最多能存100和10个字符。

虽然二者储存范围不同,但储存相同长度字符串时,所占磁盘空间一样。

不过VARCHAR(100)会消耗更多的内存,这是因为VARCHAR类型在内存中操作时,通常会分配固定大小的内存块来保存值的,即使只使用了字符类型中定义的长度。例如在排序的时候,VARCHAR(100)是按照100这个长度来进行的,会消耗更多内存。

DECIMAL和FLOAT/DOUBLE的区别是什么?

decimal和float/double的区别是:decimal是定点数,可以储存精确的小数值,而其他两个是浮点数,只能储存近似的小数值。

decimal用于储存具有精度要求的小数,例如与货币相关的数据,可以避免浮点数带来的精度损失。

Java中对于decimal 的数据类型是java.math.BigDecimal。

为什么不推荐使用TEXT和BLOB

TEXT类型类似于CHAR(0 - 255)和VARCHAR(0 - 65535),但能储存更长的字符串,即长数据文本,例如博客内容。

类型 可储存大小(字节) 用途
TINYTEXT 2^8 -1(255) 一般文本字符串
TEXT 2^16 -1(65,535) 长文本字符串
MEDIUMTEXT 2^24 -1(16,777,215) 较长文本
LONGTEXT 2^32 -1(4,294,967,295) 极大文本

BLOB一般用作储存二进制大对象,例如图片、音视频等文件

类型 可储存大小 用途
TINYBLOB 0 - 255字节 短文本二进制字符串
BLOB 0 - 65KB 二进制字符串
MEDIUMBLOB 0 - 16MB 二进制形式的长文本数据
LONGBLOB 0 - 4GB 二进制形式的极大文本数据

日常开发中很少使用TEXT类型,但偶尔用到,而BLOB基本不会使用。如果储存的字符串预期长度可以通过VARCHAR来满足,尽量避免TEXT。

数据库规范通常不推荐使用TEXT和BLOB,因为他们有一定缺陷和限制。

  • 不能有默认值
  • 在使用临时表时不能用内存临时表,只能在磁盘上创建临时表
  • 无法直接创建索引,需要指定前缀长度
  • 可能会消耗大量的网络和IO带宽
  • 可能会导致表上的DML操作变慢
  • ……

DATETIME和TIMESTAMP的区别是什么?

DATETIME没有时区信息,TIMESTAMP和时区有关

TIMESTAMP只需要4个字节的储存空间,DATETIME需要8个字节。但同样造成一个问题,TIMESTAMP表示的时间范围会更小

  • DATETIME:1000-01-01 00:00:00 - 9999-12-31 23:59:59
  • TIMESTAMP:1970-01-01 00:00:01 - 2037-12-31 23:59:59

NULL跟’’(空字符串)的区别是什么?

NULL跟‘’(空字符串)是两个不同的值,区别如下:

  • NULL代表一个不确定的值,就算是两个NULL,也不一定相等,用Select NULL=NULL 返回的是false,但使用DISTICT、GROUP BY、ORDER BY时,NULL又会被认为是相等的。
  • ‘’的长度是0,是不占用空间的,而NULL是需要占用空间的。
  • NULL会影响聚合函数的结果,比如AVG,SUM,MIN,MAX等聚合函数会忽略NULL值。COUNT取决于传参,如果传的是,COUNT()会统计所有值,而如果只传列名,COUNT(列名),那么会忽略NULL值,统计非空个数。
  • 查询NULL值时只能用IS NULL和IS NOT NULL,不能用运算符 ==,!=,<,>来比较,而‘’空字符串可以使用这些运算符比较的。

Boolean类型如何表示?

MMySQL中没有专门的布尔类型,而是用TINYINT(1)类型来表示,储存0或1表示false和true

MySQL的基础架构

MySQL简要架构图

从上图可以看出,MySQL主要由以下几个部分构成:

  • 连接器:身份认证和权限相关(登录MySQL的时候)
  • 查询缓存:执行查询语句的时候先查询缓存。(MySQL8.0后移除,因为这个功能不实用)
  • 分析器:没有命中缓存,则经过分析器,开始词法分析,语法分析,检查是否有语法错误
  • 优化器:按照MySQL认为最优化的方案去执行。
  • 执行器:执行语句,然后从存储引擎返回数据。执行语句前会判断是否有权限,如果没有权限,就会报错。
  • 插件式存储引擎:主要负责数据的存储和读取,采用的是插件式架构,支持多种引擎,比如InnoDB,MyISAN,Memory等。

MySQL存储引擎

MySQL支持哪些存储引擎,默认使用哪一个?

MySQL支持多种存储引擎,可以通过SHOW ENGINES 命令来查看MySQL支持的所有存储引擎。

查看 MySQL 提供的所有存储引擎

如图是MySQL 8.x 版本,当前MySQL的默认引擎是InnoDB,并且,在所有支持的存储引擎中,只有InnoDB是事务性存储引擎,也就说只有InnoDB支持事务。

在MySQL5.5之前MyISAM是默认的存储引擎,5.5之后,InnoDB是默认的存储引擎。可以通过 SELECT VERSION(); 查看MySQL版本。也可以通过 SHOW VARIABLES LIKE “%strong_engine%”命令直接查看当前的存储引擎。

InnoDB存储引擎官方介绍:https://dev.mysql.com/doc/refman/8.0/en/innodb-storage-engine.html

MySQL的存储引擎架构了解吗?

MySQL的存储引擎架构采用的是插件式架构,支持多种存储引擎,我们设置可以基于不同的表设置不同的存储引擎以适应不同的场景需要。存储引擎是基础表的,不是基于数据库的。

下图是具有可插拔存储引擎的MySQL架构:

MySQL储存引擎架构

还可以通过MySQL定义的存储引擎实现标准接口来编写一个专属于自己的存储引擎。这些非官方提供的存储引擎可以称为第三方存储引擎,区别于官方存储引擎。像目前默认的InnoDB引擎就是第三方引擎,由于过于优秀,后来被Oracle收购了。

Oracle官方提供的MySQL文档:https://dev.mysql.com/doc/dev/mysql-server/latest/

MyISAM和InnoDB有什么区别?

MyISAM是MySQL5.5版本之前的默认存储引擎。但跟InnoDB比较,最重要的是不支持事务和不支持行级锁,崩溃后无法安全恢复。以下来分几点说明它们的区别:

1.是否支持行级锁

MyISAM支持表级锁(table-level locking),InnoDB支持行级锁(row-level locking)和表级锁,默认是行级锁。所以在并发写的时候,InnoDB性能会更好。

2.是否支持事务

MyISAM不提供事务支持。

InnoDB提供事务支持,实现了SQL标准定义了四个隔离级别,具有提交和回滚事务的能力。并且InnoDB默认使用的REPEATABLE-READ(可重复读)隔离级别是可以解决幻读问题发生(基于MVCC和Next-Key Lock)。

3.是否支持外键

MyISAM不支持外键,InnoDB支持。

外键对于维护数据一致性非常有帮助,但是对性能有一定的损耗。因此通常情况下,我们不建议在实际生产项目中使用外键,在业务代码中约束即可。阿里的《Java开发手册》中也明确规定,禁止使用外键,在应用层面解决。不过不使用外键会对数据的一致性造成威胁,请根据项目实际情况使用外键。


文章作者: HT
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 HT !