本文已参与「新人创作礼」活动,一起开启掘金创作之路。
数据库是软件开发中非常重要的一环,数据是这个时代真正值钱的东西。本期就来讨论关于数据库在面试中会遇到的一些问题,其中包含个人一些理解,由于本人学识有限,难免会有纰漏之处,还望读者能多多包涵。
上一期(传送门)讲了主要的SQL指令,继续看。
一、 in和exists:如果子表比主表小,用in;如果子表比主表大,用exists。当主表数据与子表数据一样大时,in与exists效率差不多,可任选一个使用。例如:
select * from A where id in(select id from B)上诉sql语句是B表驱动A表,会先执行括号内的子查询,再执行主查询,相当于先将B表的数据一把查出来至于内存中,遍历B表的数据,再去查A表。
select a.* from A a where exists(select 1 from B b where a.id=b.id)该sql语句是A表驱动B表,
小结:in首先会查询其右边子句结果,根据子句结果匹配左边结果是否满足,所以对于内部子句结果比较小的适合使用in;exists首先会去查询 exists左边的结果,然后根据左边记录去查询是否满足右边,所以适合左边结果比较小的。 in只能适用于一个字段,而exsits适用于1个或多个字段。not in 和not exists:如果查询语句使用了not in,那么内外表都进行全表扫描,没有用到索引;而not extsts的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快。
二、数据类型。 数据类型是必考一个知识点。不论是C语言、Java、python、SQL、JavaScript等等,都有自己的数据类型。MySQL的数据类型大致可分为三类:数值、日期/时间和字符串(字符)类型。
数值类型又分为整型、浮点型和定点数。
| MySQL整型 | 含义(有符号) |
|---|---|
| tinyint(m) | 1个字节 范围(-128~127) |
| smallint(m) | 2个字节 范围(-32768~32767) |
| mediumint(m) | 3个字节 范围(-8388608~8388607) |
| int(m) | 4个字节 范围(-2147483648~2147483647) |
| bigint(m) | 8个字节 范围(+-9.22e10的18次方) |
取值范围如果加了unsigned,则最大值翻倍,如tinyint unsigned的取值范围为(0~256)。
| MySQL浮点型 | 含义 |
|---|---|
| float(m,d) | 单精度浮点型 8位精度(4字节) m总个数,d小数位 |
| double(m,d) | 双精度浮点型 16位精度(8字节) m总个数,d小数位 |
设一个字段定义为float(6,3),如果插入一个数123.45678,实际数据库里存的是123.457,但总个数还以实际为准,即6位。整数部分最大是3位,如果插入数12.123456,存储的是12.1234,如果插入12.12,存储的是12.1200。
浮点型在数据库中存放的是近似值,而定点类型在数据库中存放的是精确值。decimal(m,d) 参数m<65 是总个数,d<30且 d<m 是小数位。
字符串类型也有好几种,如下表:
| MySQL字符串类型 | 含义 |
|---|---|
| char(n) | 固定长度,最多255个字符 |
| varchar(n) | 固定长度,最多65535个字符 |
| tinytext | 可变长度,最多255个字符 |
| text | 可变长度,最多65535个字符 |
| mediumtext | 可变长度,最多2的24次方-1个字符 |
| longtext | 可变长度,最多2的32次方-1个字符 |
| blob | 0-65535 字节 二进制形式的长文本数据,二进制大对象 |
1.char(n) 若存入字符数小于n,则以空格补于其后,查询之时再将空格去掉。所以char类型存储的字符串末尾不能有空格,varchar不限于此。
2.char(n) 固定长度,char(4)不管是存入几个字符,都将占用4个字节,varchar是存入的实际字符数+1个字节(n<=255)或2个字节(n>255), 所以varchar(4),存入3个字符将占用4个字节。
3.char类型的字符串检索速度要比varchar类型的快。
最后就是日期和时间,如下表:
| MySQL日期时间 | 含义 |
|---|---|
| date | 日期 '2022-04-11' |
| time | 时间 '12:25:36' |
| datetime | 日期时间 '2022-04-11 22:06:44' |
| timestamp | 时间戳, 自动存储记录修改时间 |
若定义一个字段为timestamp,该字段里的时间会随着该行其他字段的修改而自动刷新,所以这个数据类型的字段可以存放这条记录最后被修改的时间。
三、MySQL的约束。在MySQL种常见的约束如下:
主键约束 :primary key 用于保证该字段的值具有唯一性并且非空。例如学生表的学号。
唯一性约束:unique key 用于保证该字段的值具有唯一性,可以为空。例如注册用户的手机号,身份证号等。
外键约束:foreign key用于限制两个表的关系,保证该字段的值必须来自于主表的关联列的值,在从表添加外键约束,用于引用主表中某些的值。例如学生表的专业编号
非空约束:not null用于保证该字段的值不能为空。
默认值约束:default用于保证该字段有默认值,如性别
还有一种CHECK:检查约束,检查字段的值是否为指定的值,但是MySql不支持。
四、存储过程。MySQL5.0版本开始支持存储过程,存储过程就是一组SQL语句集,经编译创建并保存在数据库中,用户可通过指定存储过程的名字并给定参数(需要时)来调用执行,可以实现一些比较复杂的逻辑功能,有点像Java语言中的方法。
主要目的就是两点:执行速度快、减少代码重复。此外,在安全性上会更好一点。因为在通过网络调用存储过程时,只对执行过程的调用是可见的。无法看到表和数据库对象名称,不能嵌入SQL 语句,有助于避免 SQL 注入攻击。
ok,本期就到这里,下一期继续讲解数据库方面的知识点,敬请关注。