mysql面试
范式1:原子性,表中的没一列都是不可分的,不能是数组,集合。
范式2:在第一范式基础上,属性完全依赖于主键。
范式3:非主属性不依赖于其它非主属性。(关系中不包含在其它关系中已包含的非主键信息)
比如Student表(学号,姓名,年龄,性别,所在院校,院校地址,院校电话)
这样一个表结构,就存在上述关系。 学号--> 所在院校 --> (院校地址,院校电话)
这样的表结构,我们应该拆开来,如下。
( 学号,姓名,年龄,性别,所在院校)--(所在院校,院校地址,院校电话)
drop直接删掉表 truncate删除表中数据,再插入时自增长id又从1开始 delete删除表中数据,可以加where字句。
不可回滚 不可回滚 可回滚
视图是虚拟的表,与包含数据的表不一样,视图只包含使用时动态检索数据的查询
视图主要用于简化检索,保护数据,并不用于更新,而且大部分视图都不可以更新。
数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。索引的实现通常使用B树及其变种B+树。
第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。
第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因
唯一索引
唯一索引是不允许其中任何两行具有相同索引值的索引,允许有空值
主键索引,它是一种特殊的唯一索引,不允许有空值。
存储过程
是一组为了完成特定功能的SQL语句集
数据完整性与一致性,开发维护的效率提升,数据完整性与一致性,安全性。
不易调试。不易迁移扩展。
create procedure sp_name()
begin
.........
end
call sp_name()
drop procedure sp_name()
触发器是一个特殊的存储过程,在删除,更新事自动执行
事务
数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。
四大特征:
(1)原子性
事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行。
(2)一致性
事务的一致性指的是在一个事务执行之前和执行之后数据库都必须处于一致性状态。事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。
(3) 隔离性(关于事务的隔离性数据库提供了多种隔离级别)
一个事务的执行不能干扰其它事务。即一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。
(4)持久性
事务完成之后,它对于数据库中的数据改变是永久性的。该修改即使出现系统故障也将一
直保持。
锁模式包括:
l 共享锁:(读取)操作创建的锁。其他用户可以并发读取数据,但任何事物都不能获取数据上的排它锁,直到已释放所有共享锁。
l 排他锁(X锁):对数据A加上排他锁后,则其他事务不能再对A加任任何类型的封锁。获准排他锁的事务既能读数据,又能修改数据。
l 更新锁:。一次只有一个事务可以获得资源的更新 (U) 锁。如果事务修改资源,则更新 (U) 锁转换为排它 (X) 锁。否则,锁转换为共享锁。
乐观锁:相对悲观锁而言,乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。一般的实现乐观锁的方式就是记录数据版本。
悲观锁:顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。
JOIN
左连接,右连接,内连接
left join(左联接): 返回包括左表中的所有记录和右表中联结字段相等的记录。
左外连接(左连接):结果集几包括连接表的匹配行,也包括左连接表的所有行。
SQL:
select
a.a, a.b, a.c, b.c, b.d, b.f
from
a
LEFT
OUT
JOIN
b
ON
a.a = b.c
right join(右联接): 返回包括右表中的所有记录和左表中联结字段相等的记录。
inner join(等值连接): 只返回两个表中联结字段相等的行。(默认)
UNION 操作符
UNION 操作符用于合并两个或多个 SELECT 语句的结果集。
SELECT country, name FROM Websites WHERE country='CN'
UNION
SELECT country, app_name FROM apps WHERE country='CN'
ORDER BY country;
EXCEPT
运算符
EXCEPT
运算符通过包括所有在 TABLE1 中但不在 TABLE2 中的行并消除所有重复行而派生出一个结果表。当
ALL
随
EXCEPT
一起使用时 (
EXCEPT
ALL
),不消除重复行。
select * from student;
select id,name from student;
update student set sex='男' where id=4;
delete from student where id=5;
select * from student where date>'1988-1-2' and date<'1988-12-1';
select * from student where date<'1988-11-2' or date>'1988-12-1';
select * from student where date between '1988-1-2' and '1988-12-1';
select * from student where id in (1,3,5);
#排序 asc 升序 desc 降序 select * from student order by id asc;
elect count(*) from student; #统计表中总数
select count(sex) from student; #统计表中性别总数 若有一条数据中sex为空的话,就不予以统计~
select name,max(age) from c group by sex; #按性别分组查年龄最大值
select max(Price) from Car 取价格的最大值
select Brand from Car group by Brand having count(*)>2 查询所有系列中数量大于2的
select * from Car limit 0,5 跳过几条数据取几条数据
select distinct Brand from Car
增加一个列
Alter
table
tabname
add
column
col type
1、避免在where子句中使用 is null 或 is not null 对字段进行判断。
如:
select id from table where name is null
在这个查询中,就算我们为 name 字段设置了索引,查询分析器也不会使用,因此查询效率底下。为了避免这样的查询,在数据库设计的时候,尽量将可能会出现 null 值的字段设置默认值,这里如果我们将 name 字段的默认值设置为0,那么我们就可以这样查询:
select id from table where name = 0
2、避免在 where 子句中使用 != 或 <> 操作符。
如:
select name from table where id <> 0
数据库在查询时,对 != 或 <> 操作符不会使用索引,而对于 < 、 <= 、 = 、 > 、 >= 、 BETWEEN AND,数据库才会使用索引。因此对于上面的查询,正确写法应该是:
select name from table where id < 0
union all
select name from table where id > 0
这里我们为什么没有使用 or 来链接 where 后的两个条件呢?这就是我们下面要说的第3个优化技巧。
3、避免在 where 子句中使用 or来链接条件。
如:
select id from tabel where name = 'UncleToo' or name = 'PHP'
这种情况,我们可以这样写:
select id from tabel where name = 'UncleToo'
union all
select id from tabel where name = 'PHP'
4、少用 in 或 not in。
虽然对于 in 的条件会使用索引,不会全表扫描,但是在某些特定的情况,使用其他方法也许效果更好。如:
select name from tabel where id in(1,2,3,4,5)
像这种连续的数值,我们可以使用 BETWEEN AND,如:
select name from tabel where id between 1 and 5
5、注意 like 中通配符的使用。
下面的语句会导致全表扫描,尽量少用。如:
select id from tabel where name like'%UncleToo%'
或者
select id from tabel where name like'%UncleToo'
而下面的语句执行效率要快的多,因为它使用了索引:
select id from tabel where name like'UncleToo%'
6、避免在 where 子句中对字段进行表达式操作。
如:
select name from table where id/2 = 100
正确的写法应该是:
select name from table where id = 100*2
7、避免在 where 子句中对字段进行函数操作。
如:
select id from table where substring(name,1,8) = 'UncleToo'
或
select id from table where datediff(day,datefield,'2014-07-17') >= 0
这两条语句中都对字段进行了函数处理,这样就是的查询分析器放弃了索引的使用。正确的写法是这样的:
select id from table where name like'UncleToo%'
或
select id from table where datefield <= '2014-07-17'
也就是说,不要在 where 子句中的 = 左边进行函数、算术运算或其他表达式运算。
8、在子查询中,用 exists 代替 in 是一个好的选择。
如:
select name from a where id in(select id from b)
如果我们将这条语句换成下面的写法:
select name from a where exists(select 1 from b where id = a.id)
这样,查询出来的结果一样,但是下面这条语句查询的速度要快的多。