MySQL理论系列
- 列举常见的关系型数据库和非关系型都有那些?
关系型RDBMS:有表结构,存取数据前必先定义表结构,存数据必须按照字段的类型或者约束来
典型代表:MySQL,Oracle,DB2,SQL server(银行业常用)
非关系型(爬虫类常用):存取数据都是采用key:value的形式
非关系型:Mongodb,redis,memcache(较不常用)
- MySQL常见数据库引擎及比较?
常见innodb,myisam,memory,blackhole几种存储引擎,
最常用的为innodb innodb:亦为默认存储引擎,支持事务,行锁设计,外键
t1.frm (frame) t1.ibd (innodb data); 存入硬盘
myisam:t2.MYD (myisam data) t2.MYI (myisam index) t2.frm (frame); 存入硬盘
blackhole: t3.frm
memory: t4.frm; 存入内存,关闭服务端后,数据清空
- 简述数据三大范式?
第一范式(1NF):确保每一列的原子性(如果每一列都是不可再分的最小数据单元,则满足第一范式。)
第二范式:非键字段必须依赖于键字段(第二范式要求每个表只描述一件事。)
第三范式:在1NF基础上,除了主键以外的其它列都不传递依赖于主键列,或者说: 任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)
- 什么是事务?MySQL如何支持事务?
什么是事务: 开启一个事务可以包含一些sql语句,这些sql语句要么同时成功;要么一个都别想成功,称之为事务的原子性
事务的作用:转账等,屏蔽因网络传输部分失效而带来的影响
BEGIN 或START TRANSACTION:显式地开启一个事务
COMMIT:也可以使用COMMIT WORK,不过二者是等价的。COMMIT会提交事务,并使已对数据库进行的所有修改成为永久性的
ROLLBACK:也可以使用ROLLBACK WORK,不过二者是等价的。回滚会结束用户的事务,并撤销正在进行的所有未提交的修改
SAVEPOINT identifier:SAVEPOINT允许在事务中创建一个保存点,一个事务中可以有多个SAVEPOINT
RELEASE SAVEPOINT identifier:删除一个事务的保存点,当没有指定的保存点时,执行该语句会抛出一个异常
ROLLBACK TO identifier:把事务回滚到标记点
SET TRANSACTION:用来设置事务的隔离级别。InnoDB存储引擎提供事务的隔离级别有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ和SERIALIZABLE
delimiter //
create PROCEDURE p5(
OUT p_return_code tinyint
)
BEGIN
DECLARE exit handler for sqlexception #如果出现错误,执行
BEGIN
-- ERROR
set p_return_code = 1;
rollback;
END;
DECLARE exit handler for sqlwarning #如果出现警告,执行
BEGIN
-- WARNING
set p_return_code = 2;
rollback;
END;
START TRANSACTION; #事务的应用
update user set balance=900 where id =1;
update user123 set balance=1010 where id = 2;
update user set balance=1090 where id =3;
COMMIT;
-- SUCCESS
set p_return_code = 0; #0代表执行成功
END //
delimiter ;
- 简述数据库设计中一对多和多对多的应用场景?
a、 左表与右表之间是否有多对一的关系 (多个员工属于一个部门)
b、 右表与左表之间是否有多对一的关系 (多个部门拥有一个员工)
i、a True & b False 多对一
ii、a False & b True 多对一
iii、a True & b True 多对多
iv、a False & b False 一对一
- 如何基于数据库实现商城商品计数器?
DROP TABLE access_counter;
CREATE TABLE access_counter(
solt INT NOT NULL PRIMARY KEY,
cnt INT NOT NULL
);
DELIMITER $
DROP PROCEDURE IF EXISTS `proc1`$
CREATE PROCEDURE `proc1`()
BEGIN
DECLARE i INT;
SET i=0;
WHILE i<100 DO
INSERT INTO access_counter VALUES(i,0);
SET i=i+1;
END WHILE;
END$
DELIMITER ;
CALL proc1();
SELECT * FROM access_counter;
07. 简述触发器、函数、视图、存储过程?
视图、触发器、事务、存储过程、函数、流程控制皆是在库下面建立
触发器:在满足对某张表数据的增、删、改的情况下,自动触发的功能称之为触发器
为何要用触发器: 触发器专门针对我们对某一张表数据增insert、删delete、改update的行为,这类行为一旦执行就会触发触发器的执行,即自动运行另外一段sql代码
函数:mysql内置的函数只能在sql语句中使用,mysql> select date_format(sub_time,'%Y-%m'),count(id) from blog group by date_format(sub_time,'%Y-%m');
什么是视图:通过查询得到一张虚拟表,保存下来,下次可直接使用
为什么要用视图: 如果要频繁使用一张虚拟表,可以不用重复查询
如何用视图:create view teacher2course as select * from teacher inner join course on teacher.tid = course.teacher_id;
删除视图:drop view teacher2course;
强调:在硬盘中,视图只有表结构文件(.frm),没有表数据文件(.idb); 其在后台对应的是一条sql语句;视图通常是用于查询,尽量不要修改视图中的数据
#在mysql中函数是不能单独使用的,必须放在sql语句中使用;但存储过程是可以单独使用的
存储过程:存储过程包含了一系列可执行的sql语句,存储过程存放于MySQL中,通过调用它的名字可以执行其内部的一堆sql
08. MySQL索引种类
primary key(聚集索引):叶子节点存放的一整条数据,
unique,index key(辅助索引):叶子节点存放的是:{名字:名字所在那条记录的主键的值};覆盖索引,回表操作
09. 索引在什么情况下遵循最左前缀的规则?
mysql中对a or b or c。。的形式,会从左至右依次查询
10. 主键和外键的区别?
primary key就等同于not null unique(约束);加速查询;innodb 用主键(一种索引)字段为依据组织数据,形成一种树型结构,从而加速查询
key(索引)为mysql中一种特殊的数据结构
a、unique 约束条件,加速查询
b、primary key 约束条件,加速查询,innodb组织数据结构的依据
c、index key 加速查询
d、foreign key 没有加速查询功能
11. MySQL常见的函数?
聚合函数group function(一般与分组连用)
select post,max(salary) from emp group by post; #取不出组内的元素name, age..,只能取组名(分组依据)或用聚合函数
select post,min(salary) from emp group by post;
select post,avg(salary) from emp group by post;
select post,sum(salary) from emp group by post;
select post,count(id) from emp group by post;
#group_concat(分组之后用):把想要用的信息取出;字符串拼接操作
select post,group_concat(name) from emp group by post;
select post,group_concat(name,"_SB") from emp group by post;
select post,group_concat(name,": ",salary) from emp group by post;
select post,group_concat(salary) from emp group by post;
补充concat(不分组时用):字符串拼接操作
select concat("NAME: ",name) as 姓名,concat("SAL: ",salary) as 薪资from emp;
12. 列举 创建索引但是无法命中索引的8种情况。
1)如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因)
2)对于多列索引,不是使用的第一部分(第一个),则不会使用索引
3)like查询是以%开头
4) 如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引
5) 如果mysql估计使用全表扫描要比使用索引快,则不使用索引
6) 没有查询条件,或者查询条件没有建立索引
7) 在查询条件上没有使用引导列
8) 查询的数量是大表的大部分,应该是30%以上。
9) 索引本身失效
10) 查询条件使用函数在索引列上,或者对索引列进行运算,运算包括(+,-,*,/,! 等) 错误的例子:select * from test where id-1=9; 正确的例子:select * from test where id=10;
11) 对小表查询
12) 提示不使用索引
13) 统计数据不真实
14) CBO计算走索引花费过大的情况。其实也包含了上面的情况,这里指的是表占有的block要比索引小。
15) 隐式转换导致索引失效.这一点应当引起重视.也是开发中经常会犯的错误. 由于表的字段tu_mdn定义为varchar2(20),但在查询时把该字段作为number类型以where条件传给Oracle,这样会导致索引失效. 错误的例子:select * from test where tu_mdn=13333333333; 正确的例子:select * from test where tu_mdn='13333333333';
16) 1,<> 2,单独的>,<,(有时会用到,有时不会)
17) like "%_" 百分号在前.
18) 表没分析.
19) 单独引用复合索引里非第一位置的索引列.
20) 字符型字段为数字时在where条件里不添加引号.
21) 对索引列进行运算.需要建立函数索引.
22) not in ,not exist.
23) 当变量采用的是times变量,而表的字段采用的是date变量时.或相反情况。
24) B-tree索引is null不会走,is not null会走,位图索引is null,is not null 都会走
25) 联合索引is not null 只要在建立的索引列(不分先后)都会走, in null时 必须要和建立索引第一列一起使用,当建立索引第一位置条件是is null 时,其他建立索引的列可以是is null(但必须在所有列 都满足is null的时候),或者=一个值; 当建立索引的第一位置是=一个值时,其他索引列可以是任何情况(包括is null =一个值),以上两种情况索引都会走。其他情况不会走。
13. 如何开启慢日志查询?
开启慢查询日志,可以让MySQL记录下查询超过指定时间的语句,通过定位分析性能的瓶颈,才能更好的优化数据库系统的性能。
在/etc/my.cnf中修改
14. 数据库导入导出命令(结构+数据)?
http://www.cnblogs.com/zcw-ios/articles/3319480.html
15. 数据库优化方案?
16. char和varchar的区别?
char: 定长
varchar: 变长
#不推荐混用,如果混用需定长在前、变长在后。
create table t12(x char(4)); # 超出4个字符则报错,不够4个字符则用空格补全成4个字符
create table t13(y varchar(4)); #超出4个字符则报错不够4个字符那么字符有几个就存几个
name char(5)
# 缺点:浪费空间
# 优点:存取速度都快
egon alex lxx wxx yx
name varchar(5)
# 缺点:存取速度都慢
# 优点:节省空间(it depends); 需要一个头(1-2个字节)存长度# 2bytes可存65535个字符,mysql中所有字符串(char)中字符数皆不超过65535
(1bytes+egon)(1bytes+alex)(1bytes+lxx)
17. 简述MySQL的执行计划?
id是一组数字,表示查询中执行select子句或操作表的顺序。
如果id相同,则执行顺序从上至下。
如果是子查询,id的序号会递增,id越大则优先级越高,越先会被执行。
id如果相同,则可以认为是一组,从上往下顺序执行,所有组中,id越高,优先级越高,越容易执行。
selecttype有simple,primary,subquery,derived(衍生),union,unionresult。
simple表示查询中不包含子查询或者union。
当查询中包含任何复杂的子部分,最外层的查询被标记成primary。
在select或where列表中包含了子查询,则子查询被标记成subquery。
在from的列表中包含的子查询被标记成derived。
若第二个select出现在union后,则被标记成union,若union在from子句的子查询中,外层的select被标记成derived。
从union表获取结果的select被标记成union result。
type叫访问类型,表示在表中找到所需行的方式,常见类型有
all,index,range,ref,eq_ref,const,system,NULL 性能从左至右由差至好。
ALL,即full table scan,mysql将遍历全表来找到所需要的行。
index为full index scan,只遍历索引树。
range表示索引范围扫描 ,对索引的扫描开始于一点,返回匹配的值域的行,常见于between,<,>的查询。
ref为非唯一性索引扫描,返回匹配某个单独值的所有行,常见于非唯一索引即唯一索引的非唯一前缀进行的查找。
const,system表示当对查询部分进行优化,并转化成一个常量时,使用这些类型访问。比如将主键置于where列表中,mysql就能把该查询置成一个常量。system是const的一个特例,当查询表中只有一行的情况下使用的是system。
NULL表示在执行语句中,不用查表或索引。
possiblekey表示能使用哪个索引在表中找到行,查询涉及到的字段上若存在索引,则该索引被列出,但不一定被查询使用。
18. 在对name做了唯一索引前提下,简述以下区别:
select * from tb where name = ‘Oldboy’
select * from tb where name = ‘Oldboy’ limit 1
limit 1显示一条