MySQL复习问题总结

MySQL复习问题总结

    • 1.数据库基础
    • 2.数据库事务
    • 3.数据库索引
    • 4.数据库优化
    • 5.SQL实战(无答案)

1.数据库基础

①什么是数据库三范式?
范式:数据库遵循的规范,各种范式呈递次规范,范式越高数据库冗余越小。
第一范式:确保每一列的的原子性(每一列的数据都不可再分);
第二范式:非关键字段必须依赖关键字段(一旦主键确定,其他非主键跟着被确定),要求每个表只描述一件事;
第三范式:非关键字段都不依赖其他非关键字段(非关键字段之间不存在依赖关系),在2NF基础上消除传递依赖。
注意:数据库的范式是典型“时间换空间”策略,范式越高查询速度越慢。

②说说char(n) varchar(n) int(n)数字n的意义?
char与varchar中的n都表示所占空间的字节数。
char类型定长(不足补空格),所以char中的n就是它实际所占空间字节数;
varchar中的n表示预留空间大小,实际所占空间由具体数据确定;
char虽然付出空间代价,但是它获得了时间(定长易查),查询速度快于varchar;
另外char类型只适合存储0-255字节的数据。
int中的n仅仅与显示有关,与实际存储所占空间大小无关。
即是int(n)和int存储数据所占空间大小相同;
int(n)中的n表示最短显示n个字符,不足用你指定的数字填充(如:int(n) zerofill)。

③MYSQL的两种存储引擎(InnoDB MyISAM)区别?
InnoDB:支持事务,支持外键,支持行级锁,不支持全索(5.5v)
MyISAM:不支持事务,不支持外键,支持表级锁,支持全文索引

④MySQL主从复制流程以及作用?
原理:主数据库开启一个二进制日志文件记录所有sql。
从数据库启动两个线程一个日志文件。
I/O线程登录主数据库监听其二进制日志文件,并将新增的sql写入本地的中继日志文件中,sql线程监听中继日志文件,更新数据库实现主从数据同步。
作用:作数据热备,以防数据丢失;
降低磁盘I/O的频率,提高单个机器的I/O性能
实现读写分离,提高响应速度。

⑤如何设计一对一,一对多,多对多的等情况下的两张表?
例表:Student Tearch Class
一对一:一个班只有一个班主任老师,一个班主任只管一个班 --> Tearch(tno,cno) Class(cno)
一对多:一个班级可以有多个学生,一个学生只能在一个班级 --> Student(sno,cno) Class(cno)
多对多:一个学生可以有多个老师,一个老师可以有多个学生 --> Xi(xno,sno,tno)

⑥MySQL中having和where有啥区别?
having:用于分组后筛选(常配合group by使用),后面可以用聚合函数(max,min,avg,sum,count);
where:用于分组前筛选,执行顺序大于聚合函数,所以后面不能使用聚合函数;
个人总结:能用where的语句一般能用having替换,能用having的语句不一定能用where替换。

⑦join on,join left on,join right on效果差异?
内连接:[inner] join…on,只匹配左右表中满足条件的数据行;
左外连:left join…on,匹配左表中所有数据行以及右表中满足条件的数据行(补NULL);
右外连:right join…on,匹配左表中满足条件的数据行(补NULL)以及右表中所有数据行;
全连接:full [out] join…on,匹配左右两表中的所有数据行(没有的都补NULL);
交叉连接(笛卡尔积):join,左表中的每一数据行与右表中的所有数据行组合(很少用)。
注意:Oracle数据库支持full join,mysql是不支持full join的,但仍然可以通过左外连接+ union+右外连接实现。

⑧函数、存储过程以及触发器的区别?
函数:具有针对性,一般是简单的功能;
存储过程:一组SQL语句集,相当于打包好的sql语法,相比于函数其针对性较弱,单可以实现复杂的功能;
触发器:一种特殊的存储过程,触发条件后自行调用(如销量加1库存量自动减1)。
(1) 存储过程的创建:

//声明语句分割符(MySQL默认为;)
DELIMITER $
// 创建存储过程pro并声明INT型输入参数m输出参数n
CREATE PROCEDURE pro (IN m INT,OUT n INT)
	BEGIN
		IF m%3==0 THEN
			set n=m*3;
		ELSE m%3==1 THEN
			set n=m;
		ELSE
			// 将查询结果赋值给变量
			SELECT score INTO n FROM Score WHERE sno=m;
	END $

(2) 存储过程的调用和删除:

//调用存储过程
CALL pro(13,@m);
//打印输出变量m
SELECT @m;
//删除存储过程
DROP PROCEDURE pro;

(3)触发器的创建和删除

创建语法格式:CREATE TRIGGER <触发器名> BEFORE/AFTER <触发事件> ON <表名><触发类型> [when <触发条件>] <触发动作体>;
触发事件:INSERT/UPDATE/DELETE,是对表进行增改还是删?
触发类型:for each row/statement,行级触发器/语句触发器
删除语法格式:DROP TRIGGER <触发器名> ON <表名>;

⑨简单说一说drop、delete与truncate的区别?
drop:清空数据又删除表,直接删除数据页,不支持事务回滚,运行速度最快;
truncate:清空数据保留表,直接删除数据页,不支持事务回滚,运行速度快;
delete:清空数据保留表,逐行删除数据行并记录日志,支持事务回滚,运行速度慢。
注意:truncate删除不会触发任何delete触发器,不能删除带外键的表。

⑩说MySQL、MongoDB、Redis以及HBase的对比?
MongoDB:文档存储,数据结构自由,定位“灵活”;
MySQL:SQL数据库,数据结构化,定位“严格”;
HBase:列存储,数据结构自由,定位“大”;
Redis(内存数据库):键-值存储,数据结构自由,定位“快”。

⑪数据库的级联操作是什么?
联级操作:主键表中被参考列发生变化(ON UPDATE/DELETE),外键表中相应字段的变化规则(RESTRICT/CASCADE/SET NULL)。
RESTRICT:拒绝更新删除(默认);
CASCADE:保持一致;
SET NULL:设置NULL;
SET DEFAULT:设置默认值(目前InnoDB不支持)。

如:FOREIGN KEY (user_id) REFERENCES t_user (id) ON UPDATE CASCADE ON DELETE CASCADE;

2.数据库事务

①事务四大特性(ACID)?
原子性(A):要么全部执行成功,要么都不执行;
一致性(C):事务并发执行所得结果,与按某个顺序串行执行的结果相一致;
隔离性(I):并发事务之间是相互隔离的,互不影响;’
持久性(D):事务一旦提交,则改变是永久的。

②数据库四大隔离级别?
Read uncommitted(可读未提交的数据):
不能防止任何隔离型问题(脏读,不可重复读,幻读);
Read commit(读已经提交的数据):
可以防止脏读问题,但是不能防止不可重复读/幻读问题(oracle)
Repeatable read(可重复读):
可以防止脏读/不可重复读,不能防止幻读(mysql)
Serializable(串行化):
数据库被设计为单线程,可以防止上述所有问题

③事务并发会带来哪些问题?怎么解决?
脏读:事务A读取到事务B未提交的数据;
不可重复读:事务A读取到事务B已经提交的数据(UPDATE/DELETE);
幻读:事务A读取到事务B新增的数据(INSERT)。
以上三种问题可以通过提高隔离级别来解决
第一类丢失更新(回滚丢失,标准定义的所有隔离级别都不允许出现此现象):事务A撤销时,将事务B已经提交的数据覆盖(A:1000-100 撤销;B:1000+100提交 --> 1000 );
第二类丢失更新(覆盖丢失,采用悲观锁法/乐观锁法/提高隔离级别解决):事务A覆盖事务B已经提交的数据(A:1000+100 提交;B:1000-100提交 --> 1100)。

④数据库的锁(共享锁 排他锁),锁思想( 悲观锁 乐观锁),以及锁现象(活锁 死锁)?
数据库的隔离机制通过加锁来实现:对于可重复读隔离级别,读操作加共享锁,写操作加排他锁(排斥任意锁),事务A读取数据加共享锁,事务B写数据要求加排他锁被拒绝,所以事务再读时数据依然没有改变,实现可重复读隔离级别。
悲观锁思想:悲观的认为每次读取数据后数据都会被修改,所以一开始就加锁防止数据被修改[SELECT…FOR UPDATE]。适合于写次数较多的表,不需要重复处理,但锁开销大且系统吞吐量低。如表锁,行锁,读锁,写锁。
乐观锁思想:乐观的认为每次读取数据后数据都不会被修改而不加锁,更新数据前做一次查询确认,如果数据未被修改则更新数据,如果数据被修改则本次更新失败,再次尝试…适用于写次数较少的表,可以减少锁开销,提高系统吞吐量,但可能需要重复处理。如CAS技术(内存位置,预期原值,新值,只有内存位置和预期原值匹配,处理器才会更新对应位置的值为新值)。
死锁现象:多个事务各自锁定一些资源,而要求锁定对方的资源,从而造成相互等待的现象。解决思路:避免死锁和检测死锁打破死锁。
活锁现象:多事务并发,某个事务一直处于等待的现象,避免活锁的简单方法是先来先服务策略。

3.数据库索引

①使用索引(有序的数据结构)的优缺点?
优点:实现目标数据快速定位,加速表与表之间的连接,极大提高数据库读性能;
缺点:常见索引和维护索引都需要时间,较低数据库写性能,索引需要占用一定的物理空间。

②什么样的字段适合创建索引?哪些情况下索引会失效?
经常查询、排序、分组、去重以及作表连接的字段
创建索引的字段应该NOT NULL,取值离散大(重复低),长度小
失效情况:以%开头的LIKE语句,模糊匹配;OR语句前后没有同时使用索引;数据类型出现隐式转换(如varchar不加单引号可能自动转换为int类型);不符合最左匹配原则(abc索引,条件不能缺a,有a顺序无所谓,mysql查询优化器自动优化)的多索引。

③为什么说B+Tree比B-Tree更适合做数据库的索引?
B-Tree:平衡多路查找树。树中每一个节点最对多含m个孩子;除根结点和叶子结点外,其它每个结点至少有ceil(m / 2)个孩子;若根节点不是叶子节点(整棵树不是只有一个节点),则根节点至少有两棵子树;所有叶子结点都出现在同一层,叶子结点不包含任何关键字信息(都指向NULL);有n个孩子的非叶子节点恰好有n-1个关键字,且是按从小到大顺序排列。
B+Tree:B树的变形树。n棵子树的节点都含有n个关键码;所有的叶子节点都包含了全部的关键码信息,并且以从小到大顺序连接;非终端节点可以看成是索引部分,结点中仅含有其子树根结点中最大(或最小)关键码。
B+Tree相比于B-Tree的最大好处(根本原因):只需要遍历叶子节点就可以实现整棵树的遍历,而B树只能中序遍历所有节点,效率太低;B+树支持range-query非常方便,而B树不支持。

④索引有哪些分类?
唯一性:普通索引和唯一索引(索引值可以为NULL);
数目:单一索引和复合索引;
物理存储划分:聚集索引(必须唯一,迅速将大范围缩为小范围,然后再这个小范围扫描);非聚集索引(把大范围转为小地图,通过地图位置找到数据)。

注意:主键是一种特殊的唯一索引,它可以是聚集索引,也可以使非聚集索引;
     默认创建的是聚集索引,但也可以显式指定为非聚集索引。

4.数据库优化

①表结构优化
表设计遵循三大范式
选择合适的数据类型

②索引优化
在经常查询、排序、分组、去重以及作表连接的字段创建索引
注意索引失效的情况

③sql语句优化
优化insert语句:一次插入多值
应尽量避免在 where 子句中使用!=或<>操作符
应尽量避免在 where 子句中对字段进行null值判断
优化嵌套查询:子查询可以被更有效率的连接(Join)替代
很多时候用 exists 代替 in 是一个好的选择

5.SQL实战(无答案)

create table dept(				-- 部门表
	deptno int primary key,		-- 部门编号
	deptname varchar(50),		-- 部门名称
	loc varchar(50)				-- 部门位置
);
create table emp(				-- 员工表
	empno int primary key,		-- 员工编号
	empname varchar(50),		-- 员工姓名
	job varchar(50),			-- 职位
	mgr int,					-- 直属上级
	hiredate date,				-- 受雇日期
	sal int,					-- 薪资
	comm int,					-- 奖金
	deptno int,					-- 所在部门编号
	foreign key(deptno) references dept(deptno)
);

1.列出部门名称和这些部门的员工信息`,同时列出那些没有员工的部门。

2.列出薪资比关羽高的所有员工。

3.列出所有员工的姓名及其直接上级的姓名。

4.列出最低薪资大于1500的各种职位及从事此职位的员工人数。

5.列出在销售部职位的员工的姓名,假定不知道销售部的部门编号。

6.列出与曹操从事相同职位的所有员工及部门名称。

7.列出薪资高于在销售部(已知部门编号为30)就职的所有员工的薪资的员工姓名和薪资、部门名称。

8.列出在每个部门职位的员工数量、平均工资。

9.查出至少有一个员工的部门。显示部门人数、部门编号、部门名称、部门位置。

10.列出受雇日期早于直接上级的所有员工的编号、姓名、部门名称。

11.列出所有职员的姓名及其部门名称,部门的人数。

新人写博客,有错误请多多指教!

你可能感兴趣的:(数据库,MySQL,数据库,事务)