JAVA经典面试--数据库

1. 常用的表字段类型

数值型
  主要分为两个类别:整数、浮点数。数值型数据类型都可分为有符号和无符号

类型 大小 说明
tinyint 1字节
smallint 2字节
meniumint 3字节
int、integer 4字节
bigint 8字节 极大
float 4字节 浮点(单精度)
double 8字节 浮点(双精度)
decimal 对declmal(M,D)如果M>D,为M+2否则为D+2

注:mysql以一个可选的显示宽度指示器的形式对SQL标准进行扩展(例 INT(6)的意思只是说该字段最大只能存储6位数,高于6位的数字存储会进行截断。但是其占用空间不会发生改变)
字符型
  8种基本字符串类型

类型 大小 说明
char 0-255字节 定长
carchar 0-255字节 变长
tinyblob 0-255字节 不超255个字符的二进制字符串
tinytext 0-255字节 短文本字符串
blob 64K字节 二进制形式的长文本数据
text 64K字节 长文本数据
mediumblob 16M字节 二进制形式的中等长度文本数据
mediumtext 16M字节 中等长度文本数据
logngblob 4G 二进制形式的极大文本数据
longtext 4G 极大文本数据

注:如果确切知道字符长度选用char。char由于本身定长特性使其性能高于carchar
时间类型
5种时间数据类型

类型 大小(字节) 格式 说明
Date 3 YYYY-MM-DD 日期
Time 3 HH:MM:SS 时间值或持续时间
Year 1 YYYY 年份值
Datetime 8 YYYY-MM-DD HH:MM:SS 混合日期和时间值
TimeStamp 8 YYYYMMDD HHMMSS 时间戳

注:如果没有对timestamp类型的字段没有明确赋值,或被赋予null值,mysql会自动使用系统当前日期和时间来填充它。
复合类型
Mysql还支持enum、set两种复合类型。虽然在技术上它们仍然是字符串。
enum:只允许从一个集合种取一个值
set:允许从一个集合种取得任意多个值

2. 合理的选择数据类型

选择合理范围内最小的:这样可以有效减小磁盘空间占用以及I/O读写开销
选择相对简单的数据类型:数字类型相对于字符串类型要简单多,尤其是在运算时。
不要使用null:mysql对NULL字段的索引优化不佳,会增加更多的计算难度,同时在保存和处理null时会做更多的工作。
数字不要用字符类型存储:一是占用存储空间更大,二是排序时字符串的9大于22,三是进行运算时mysql会将字符串转为数值类型,致使索引失效。

3. 主键、外键

主键:唯一标注表种的每一行,它可以时一个列或多个列的组合,
  ★ 保证实体的完整性
  ★ 加快数据库的操作速度
外键:其他表的主键或者唯一键
  ★保证数据库数据的一致性和完整性
  ★设置外键约束的两个表具有父子关系,即子表种外键的字段取值范围由父表决定。其关联关系有四种:
    cascade:级联方式,主表delete、update的时候,从表delete、update掉关联记录;
    setnull:置空方式,主表delete、update时,从表将关联记录的外键字段所在列设为null,注意这种方式在设计从表时外键不能设置为not null;
    restrict /no action:禁止方式,先检查外键在从表中是否有关联数据,有则不运行删除(可以先删除从表的);

4. 索引

5. 索引失效的集中情况

  ★ 查询中有函数计算;
  ★ 查询中有模糊查询(不能以%开头但可以以%结尾);
  ★ 查询条件中有or,索引失效,除非所有条件都加上索引;
  ★ 使用不能与(!= 或者 <>)
  ★ is null 或者 is not null
  ★ 字符串不加引号,会导致索引失效 why
  ★ 最左原则,联合索引中遵循最左原则,即如果要使用联合索引,那么前面的索引列一定要包含

6. 慢查询

慢查询指查询时间超过固定阈值的查询记录。mysql默认情况下不开启慢查询

查看状态: show variables like "%slow_query_log%";
手动开启:set global slow_query_log = on;
设置超时时间:set global slow_query_log_time = 10;
设置记录地址:set global slow_query_log_file = "G:\var\slow_log.txt";

:也可直接修改my.ini文件

7. 慢查询优化

1. 数据库开启慢查询,具体方法请查看本文第6点
2. 分析慢查询日志
3. 分析慢查询语句:采用explain分析出慢的原因
4.慢查询优化: 
     1. 添加索引;
     2. 索引失效,排查原因并修改查询语句;
     3. 优化数据库结构,提升查询速度:
         1. 将字段多的表进行拆分;
         2. 增加中间表,将经常联合查询的表,可建立中间表以提升查询效率,将联合查询改为对中间表的单表查询;
         3. 分解关联查询,将联合查询分解为小查询,尽量将逻辑判断放在应用程序中;
         4. 优化LIMIT分页,limit不是直接去偏移量,而是全部取出然后根据偏移量进行截取输出,此种优化是尽可能使用索引覆盖扫描,而不是查询所有列。然后根据需求在做一次关联操作最后返回所需的列;

8. 数据库设计--三大范式

数据库设计时需要考虑数据冗余,查询和更新速度,字段的数据类型是否合理等,所以建立科学的、规范的数据库是需要满足一些规范来优化数据库数据存储方式,在关系型数据库中这些规范就成为范式。
第一范式:要求数据库的每一列都是不可分割的原子数据项,简记为1NF;
第二范式:在1NF的基础上,所有非主属性都完全依赖于每一个候选关键属性,称R满足第二范式,简记为2NF;第二范式确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)
第三范式:在2NF的基础上,任何非主属性不依赖于其他非主属性,简记为3NF。第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。
注:关系实质上是一张二维表,其中每一行都是一个元组,每一列都是一个属性。
参考博文:https://www.cnblogs.com/wsg25/p/9615100.html

9. 分页、分页优化

三种分页方式:
★ 第一种:limit m,n
  其含义为扫描满足条件的m+n行,撇去前面的m行,返回最后的n行。如果m值非常大时,扫描的效率是非常低下的。
  传统limit m,n 其相对偏移量一直都是第一页,这样的话越翻到后面,效率越差。

select * from dept order by deptno desc limit 3,3;

★ 第二种:limit m
  这种方式不管翻多少页都只会扫描m条数据,但是仅能实现上一页/下一页,无法跳页。

select * from dept where deptno > 1020 order by deptno asc limit 20 //下一页
select * from dept where deptno < 1000 order by deptno desc limit 20 //上一页

★ 第三种:优化 limit m,n
  如果limit m,n 不可避免的话,就要优化效率,尽可能缩小m值。
  优化方法:记录当前页id的最大值和最小值,计算跳转页面和当前页面的相对偏移,由于页面相近,这个偏移量不会很大,这样的话m值相对较小,大大减少扫描的行数。

如果当前是第10页,每页20条。当前最大条目id是2519,最小的为2500;
则第10页的sql如下:
   select * from tb_goods_info where auto_id >= 2500 order by auto_id asc limit 0,20;
第9页:
   select * from tb_goods_info where auto_id < 2500 order by auto_id desc limit 0,20
第8页:
   select * from tb_goods_info where auto_id < 2500 order by auto_id desc limit 20,20;
第11页:
   select * from tb_goods_info where auto_id > 2519 order by auto_id asc limit 0,20;
第12页:
   select * from tb_goods_info where atuo_id > 2519 order by auto_id asc limit 20,20;

参考博文: https://www.cnblogs.com/hechenhao/p/8082065.html

10. 表的联合查询

join、union
union:该操作符用于合并两个或多个select语句的结果集。union会默认合并相同列,如果不合并可用union all
  
注:
union内部的select语句必须拥有相同数量的列。列也必须拥有相似的数据类型,同时,每条select语句中的列的顺序必须相同。
join:连接两张表。类型:join、left join、right join、inner join、full join等
笛卡尔积(cross join):join基础,要理解join首先要理解笛卡尔积。笛卡尔积就是将A表的每一条记录与B表的每一条记录强行拼在一起。所以,如果A表有n条记录,B表有m条记录,笛卡尔积产生的结果就是产生n*m表记录。
  ★ inner join:内连接,求两张表的交集;
  ★ left join:左连接,求两张表的交集外加左表剩下的数据;
  ★ right join:右连接,求两张表的交集外加右表剩下的数据;
  ★ outer join(full join):外连接,求两张表的并集;(注:mysql不支持outer join)
  ★ natural join:mysql自己判断完成连接过程,不需要指定连接条件。mysql会使用表内的相同字段作为作为连接条件(比较的是行,仅在两行完全相同时进行输出,否则输出null)

参考博文:https://www.cnblogs.com/canger/p/9760217.html

11. JOIN常用操作

★  左连接:select * from t1 left join t2 on t1.id = t2.id;
★  右连接:select * from t1 right join t2 on t1.id = t2.id;
★  内连接:select * from t1 inner join t2 on t1.id = t2.id;
★  左表独有:select * from t1 left join t2 on t1.id = t2.id where t2.id is null;
★  右表独有:select * from t1 right join t2 on t1.id = t2.id where t1.id is null;
★  全连接:
          oracle:select * from t1 full join t2 on t1.id=t2.id;
          mysql:select * from t1 left join t2 on t1.id = t2.id union select * from t1 right join t2 on t1.id = t2.id;
★  并集去交集:select * from t1 left join t2 on t1.id = t2.id where t2.id is null union select * from t1 right join t2 on t1.id = t2.id where i1.id is null;
★  自然连接:select * from t1 natural join t2;
★  自然连接-左连接:select * from t1 natural left join t2;
★  自然连接-右连接:select * from t1 natural right join t2;

12. 悲观锁、乐观锁

你可能感兴趣的:(JAVA经典面试--数据库)