一、概念知识
1.主键:数据库表中对储存数据对象予以唯一和完整标识的数据列或属性的组合。一个数据列只能有一个主键,且主键的取值不能缺失,即不能为空值(Null)。
2.超键:在关系中能唯一标识元组的属性集称为关系模式的超键。一个属性可以为作为一个超键,多个属性组合在一起也可以作为一个超键。超键包括主键和候选键
3.候选键:最小超键,即没有冗余的超键。
4.外键:在一个表中存在另一个表的主键,称为这个表的外键。
数据库事务的四个特性:ACID
原子性(atomicity):整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状 态,就像这个事务从来没有执行过一样。
一致性(Correspondence):事务开开始之前和事务结束之后,数据库的完整性约束没有破坏。
隔离性(Isolation):隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行 相同的功能,事务的隔离性将确保每一事务在 系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请 求,使得在同一时间仅有一个请求用于同一数据。
持久性(Durability):在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
视图的作用:
简化复杂的SQL操作,隐藏细节,保护数据。
DML、DDL、DCL的区别
DML操作是可以手动控制事务的开启、提交和回滚的。DDL操作是隐性提交的,不能rollback!
1.DML(data manipulation language)是数据操纵语言:它们是SELECT、UPDATE、INSERT、DELETE,就象它的名字一样,这4条命令是用来对数据库里的数据进行操作的语 言。
2.DDL(data definition language)是数据定义语言:DDL比DML要多,主要的命令有CREATE、ALTER、DROP等,DDL主要是用在定义或改变表(TABLE)的结构,数据类型,表 之间的链接和约束等初始化工作上,他们大多在建立表时使用。
3.DCL(DataControlLanguage)是数据库控制语言:是用来设置或更改数据库用户或角色权限的语句,包括(grant,deny,revoke等)语句。
二、视图不能更新的情况:
1.若视图由两个或两个以上基本表导出,则该视图不允许更新。
原因:因为对视图的更新最终都是在基本表上进行更新,都是把对视图的操作翻译成对基本表的操作。例如表R(A,B),表S(B,C),视图(A,B,C),如果更新视图中的(a1,b1,c1),并不能说明基本表中仅包含(a1,b1),(b1,c1)这两个元组,如果b1为空,那就更加不用说了,所以SQL语言在标准上就禁止了对连接视图的更新。
2.若视图的字段来自字段表达式或常数,则不允许更新updata和insert操作,但是允许delete操作。
原因:和1 的情况类似,不能与基本表中的元组进行一一对应。
3.若视图的字段来自聚合函数,则不允许更新。
原因:和1类似。
4.若视图定义语句含有group by,则视图不允许更新。
原因:和1类似。
5.若视图定义语句含有distince,则视图不允许更新。
原:和1类似。
6.若视图的定义语句含有嵌套查询,而且子查询中涉及的表也是导出该视图的基本表,则该视图不允许更新。
例子:将成绩在平均成绩之上的元组定义成一个视图GOOD_SC: CREATE VIEW GOOD_SC AS SELECT Sno, Cno, Grade FROM SC WHERE Grade> (SELECT AVG(Grade) FROM SC);导出视图GOOD_SC的基本表是SC,内层查询中涉及的表也是SC,所以视图GOOD_SC是不允许更新的。
7.在一个不能更新的视图上定义的视图也是不允许更新的。
三、sql不能适用索引的情况:
1、查询谓词没有使用索引的主要边界,换句话说就是select *,可能会导致不走索引。
比如,你查询的是SELECT * FROM T WHERE Y=XXX;假如你的T表上有一个包含Y值的组合索引,但是优化器会认为需要一行行的扫描会更有效,这个时候,优化器可能会选择TABLE ACCESS FULL,但是如果换成了SELECT Y FROM T WHERE Y = XXX,优化器会直接去索引中找到Y的值,因为从B树中就可以找到相应的值。
2、单键值的b树索引列上存在null值,导致COUNT(*)不能走索引。
如果在B树索引中有一个空值,那么查询诸如SELECT COUNT(*) FROM T 的时候,因为HASHSET中不能存储空值的,所以优化器不会走索引,有两种方式可以让索引有效,一种是SELECT COUNT(*) FROM T WHERE XXX IS NOT NULL或者把这个列的属性改为not null (不能为空)。
3、索引列上有函数运算,导致不走索引
如果在T表上有一个索引Y,但是你的查询语句是这样子SELECT * FROM T WHERE FUN(Y) = XXX。这个时候索引也不会被用到。
4、隐式转换导致不走索引。
索引不适用于隐式转换的情况,比如你的SELECT * FROM T WHERE Y = 5 在Y上面有一个索引,但是Y列是VARCHAR2的,那么Oracle会将上面的5进行一个隐式的转换,SELECT * FROM T WHERE TO_NUMBER(Y) = 5,这个时候也是有可能用不到索引的。
5、表的数据库小或者需要选择大部分数据,不走索引
在Oracle的初始化参数中,有一个参数是一次读取的数据块的数目,比如你的表只有几个数据块大小,而且可以被Oracle一次性抓取,那么就没有使用索引的必要了,因为抓取索引还需要去根据 rowid从数据块中获取相应的元素值,因此在表特别小的情况下,索引没有用到是情理当中的事情。
6、cbo优化器下统计信息不准确,导致不走索引
很长时间没有做表分析,或者重新收集表状态信息了,在数据字典中,表的统计信息是不准确的,这个情况下,可能会使用错误的索引,这个效率可能也是比较低的。
7、使用!=或者<>(不等于),会导致索引失效。
8、表字段的属性导致不走索引,字符型的索引列会导致优化器认为需要扫描索引大部分数据且聚簇因子很大,最终导致弃用索引扫描而改用全表扫描方式。
9、建立组合索引,但查询谓词并未使用组合索引的第一列。
10、like '%liu' 模糊查询含有前置百分号,会导致索引失效。
11,使用not in ,not exist时,会导致索引失效。可以尝试把not in 或者 not exsts改成左连接的方式(前提是有子查询,并且子查询有where条件)。
四、drop、delete和truncate的区别
1.delete执行顺序是每次从表中删除一行数据,并把删除操作作为事务记录在日记中,删除动作是可以恢复的;truncate是一次性删除表中所有数据而不是逐行删除,不会 记录日记文件,删除动作不可以恢复,也不会触发与表相关的删除触发器,删除速度快。
2.truncate会释放原来索引的内容所占的空间,但是不会删除表的索引的定义,所以在表重新插入数据之后,索引仍可以使用。delete则不会释放原来索引内容所占的空 间。另外,truncate会释放表空间,再插入数据时自增长id又从1开始,而delete则不会方式表空间。
3.truncate只能对table使用,而delete可以对table和view使用。
4.truncate和delete只删除数据;而drop删除数据和表结构,还包括表相关的约束、触发器和索引,依赖于该表的函数和存储过程将被保留,但是状态会变为invalid(无效 的)。
5.delete是DML语言,可以回滚;truncate和drop是DDL语言,不可以回滚。、
6.有外键约束的表不能使用truncate,可以用不带where的delete代替;但是如果一定要用truncate的话,可以先让外键约束失效,删除操作结束之后再让外键起效。
让外键失效:SET FOREIGN_KEY_CHECKS = 0;
让外键起效:SET FOREIGN_KEY_CHECKS = 1;
五、连接的几种类型
概括:
1.在没有使用on条件的情况下,join、cross join、inner join、full join(full join不允许在后面添加on条件)返回的结果都是两个表的笛卡尔积。
2.join、cross join、inner join都是可以通过添加on条件来进行筛选的。
3.只有inner join,没有left inner join、right inner join。
4.left join是left outer join的缩写,left join默认是outer属性;right join是right outer join 的缩写,right join默认是outer属性。
5.left join(left outer join)、right join(right outer join)后面必须添加on条件进行筛选,否则会报语法错误。
六、范式
1.第一方式(1NF)
第一范式(1NF)是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值。例如:你不能新建一列属性为parents,列的值里面存放父亲和母亲的名字,父亲 和母亲 的名字是可以分割的。
2.第二方式(2NF)
第二范式(2NF)要求数据库表中的每个实例或行必须可以被惟一地区分。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。这个惟一属性列被称为主关键字或 主 键、主码。
3.第三方式(3NF)
满足第三范式(3NF)必须先满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。例如,存在一个部门信息表,其中每个 部门有部门编号(dept_id)、部门名称、部门简介等信息。那么在员工信息表中列出部门编号后就不能再将部门名称、部门简介等与部门有关的信息再加入员工信息表中。如果不存在部门信息 表,则根据第三范式(3NF)也应该构建它,否则就会有大量的数据冗余。简而言之,第三范式就是属性不依赖于其它非主属性。(我的理解是消除冗余)。
七、数据库优化思路
SQL优化:
1.避免使用!=和<>;not in 和not exists。
2.避免在where后进行Null判断,可以把列的默认值改为0或者其他,而不使用Null。where xx is null为什么会影响效率呢,因为mysql的查询优化器在null值的行数比较多的时候抛弃索引扫描而选择 全表扫描。
3.尽量使用exists来代替in,exists的效率比in高。
例子:
使用IN的SQL:select u.* from user u where u.id in (select uu.id from user uu where uu.name like '%a%');
使用exists的SQL:select u.* from user u where exists (select uu.id from user uu where uu.name like '%a%' and uu.id=u.id);
4.用where字句代替having字句,因为having是在检索出所有数据之后在进行过滤。
八、触发器、函数、存储过程的区别
触发器与存储过程非常相似,触发器也是SQL语句集,两者唯一的区别是触发器不能用EXECUTE语句调用,而是在用户执行Transact-SQL语句时自动触发(激活)执行。触发器是在一个修改了指定表中的数据时执行的存储过程。通常通过创建触发器来强制实现不同表中的逻辑相关数据的引用完整性和一致性。由于用户不能绕过触发器,所以可以用它来强制实施复杂的业务规则,以确保数据的完整性。触发器不同于存储过程,触发器主要是通过事件执行触发而被执行的,而存储过程可以通过存储过程名称名字而直接调用。当对某一表进行诸如UPDATE、INSERT、DELETE这些操作时,SQLSERVER就会自动执行触发器所定义的SQL语句,从而确保对数据的处理必须符合这些SQL语句所定义的规则。