数据库热点问题总结

================
悲观锁和乐观锁

================
数据库 乐观锁和悲观锁的机制:
1. 乐观锁是一种思想,具体实现是,表中有一个版本字段,第一次读的时候,获取到这个字段。处理完业务逻辑开始更新的时候,需要再次查看该字段的值是否和第一次的一样。如果一样更新,反之拒绝。
之所以叫乐观,因为这个模式没有从数据库加锁。
2. 悲观锁是读取的时候为后面的更新加锁,之后再来的读操作都会等待。这种是数据库锁乐观锁优点程序实现,不会存在死锁等问题。他的适用场景也相对乐观。
阻止不了除了程序之外的数据库操作。悲观锁是数据库实现,他阻止一切数据库操作。再来说更新数据丢失,所有的读锁都是为了保持数据一致性。乐观锁如果有人在你之前更新了,你的更新应当是被拒绝的,可以让用户从新操作。
悲观锁则会等待前一个更新完成。这也是区别。具体业务具体分析

================
数据库索引

================
建立索引可以加快检索速度
唯一性索引 建索引字段是唯一性非重复的;
主键索引 建索引列是主键
聚集索引 在聚集索引中,表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个聚集索引。如字典默认按字母顺序排序,读者如知道某个字的读音可根据字母顺序快速定位
创建索引
CREATE INDEX index_name ON table_name (column_list)
删除索引
DROP INDEX index_name ONtable_name

================
索引不起作用的情况

================

一旦在数据表的某个或某些列上建立索引,查询时也不一定能够使用。
1.使用比较运算符不当
2.函数的使用
3.联合索引

1.使用比较运算符不当
Oracle是通过比较索引值来实现搜索的,但是,如果使用了不当的比较运算,有可能仍会使用全表扫描。
比如<>,!= 会引起Oracle忽略索引。
2.函数的使用
对于索引列,一旦使用了函数,那么将在查询时无法使用索引。
3.索引不仅可以建立在单列上,而且可以建立在多列上。建立在多列上的索引被称为联合索引。使用联合索引列中的部分列作为查询条件,有可能无法使用到联合索引所带来的性能提升。

================
左连接如何调优

================

on与where的执行顺序,在使用Left (right) join的时候,一定要在先给出尽可能多的匹配on满足条件,减少Where的执行。where比on耗时多
对sql进行优化的原则有哪些?
避免全表扫描,比如用!=,<>
要建立索引,比如where,order by

================
having和group by区别

================

group by 用于分组,select中非聚合函数的字段都必须出现在group by 后
having 对条件进行过滤,一般是对分组后的数据进行筛选,且条件可以是组函数
SELECT region, SUM(population), SUM(area) FROM bbc GROUP BY region
SELECT region, SUM(population), SUM(area) FROM bbc GROUP BY region HAVING SUM(area)>1000000

================
数据完整性

================

数据完整性包括四类:实体完整性、参照完整性、域完整性、用户定义的完整性。
1.实体完整性
实体完整性指表中行的完整性。要求表中的所有行都有唯一的标识符,存储标识符的列称为主键列。保证实体完整性一般使用主键priermay key实现。
2.参照完整性
参照完整性用于表述表之间关系。这种关系一般表现为主从关系。附表中的数据依附于主表数据的存在而存在。参照完整性一般用外键约束来实现。例如,对于客户表与订单表,客户表为主表,而订单表为附表。
订单表中不可能存在某张订单,该订单的客户不在客户表中。如果要删除某个客户。那么该客户的订单也应该删除。
3.域完整性
域完整性是对数据表中列属性的约束,如数据类型、格式、值域范围、是否允许空值等约束,最常见的域约束为非空约束和默认值约束。
域完整性也与实际的逻辑相联系。例如,针对订单的到货日期,对应列值不能为空 receive_date date not null
4.用户自定义完整性
前三种的约束都是由数据库自动完成的,而用户定义完整性则是由用户自定义的约束。这极大增强了数据库的约束的灵活性。例如,针对订单状态只能存在“有效”和“无效”两种
staus varchar2(3) check(status in ‘ACT’,’CXL’))

================
数据一致性

================

数据一致性是指数据库的数据在每一时刻都是稳定且可靠的状态。而事务是保证数据一致性的主要手段。
事务
事务的关键字transaction
一个事务的生命周期应当包括:事务开始、事务执行和事务结束。需要注意的是,Oracle中并不能显式开始一个事务,也不存在这样的语句。事务的开始总是隐式进行的,而事务的结束则可以利用commit或者rollback命令进行终止。
Oracle中控制事务的常用命令包括:

commit  提交事务
rollback  回滚事务
savepoint  
rollback to <savepoint>
set transaction
set constraint

================================

事务的属性
事务本身存在着一些属性,这可以保证事务以某种特定的规则运行。所谓隔离,是指将事务所能看到的数据库状态与其他事务分隔开来。这具有很强的现实意义。
因为数据库总是以动态改变的形式存在的,而事务处理时,往往要求有比较稳定地状态。以下2种事务的属性
read only属性;
read write属性;

read only属性
一旦将某个事务设置为 read only,将无法在事务内进行修改数据库的操作。
命令 set transaction read only;
事务代码行
read write 属性
read write属性可以将事务设置为可读、可写状态。这实际是事务的默认状态,因此,该属性的显示设定,并没有太大的现实意义。
set transaction read write
一旦使用set transaction read write 命令,那么该命令之前,不能出现set transaction命令之外的其他命令。

================================

事务的隔离级别
serializable隔离级别;
read commit 隔离级别;
serializable隔离级别
serializable 隔离级别是指串行化事务。串行化事务可以实现与只读事务相同的功能-隔离其他事务对数据库状态的影响。但是串行化事务允许在其中执行任何DML操作,包括删除、修改、插入数据等。
在默认情况下,一个事务可以识别其他事务针对数据库的修改,而这种修改仅限于已经提交到数据库的修改。使用了串行化事务,那么,其他事务已经提交的修改也将被隔离。
这里所说的隔离,实际是对于查询操作来说,也就是串行化事务的处理过程中,无法查看到其他事务的修改。
read commit隔离级别
read commit 隔离级别是事务默认隔离级别,即只能读取其他事务已经提交的修改。对于尚未提交的修改,只有实现该修改的事务本身可以进行读取。

================================
事务处理原则
事务处理原则可以概括为ACID
原子性(Atomicity):整个事务不可分割,要么全部执行,要么都不执行。
一致性(Consistency):事务一旦提交生效,会将数据库从一种状态转变为另一种状态。而且转变之后的状态是合理和可接受的。
隔离性(Isolation):在事务处理的过程中,事务处理的效果对于其他事务,是完全透明的。只有提交之后,其效果才能为其他事务所识别。即前面提到的read commited的隔离级别
持久性(Durablity):一旦提交了事务处理,那么事务处理的效果将永久生效。

原子性
Oracle中事务处理遵循原子性。无论事务中包含多少语句,要么提交所有工作,要么废除所有工作。需要注意的是,利用savepoint和roll back savepoint回滚部分操作并非特例,这是因为利用rollback savepoint 也是用户指定的动作。可以看做是事务处理中的普通命令。
一致性
Oracle中的是无语必须保证数据的一致性。数据一致性
事务可以包含多条语句,并可以在事务开始执行时将约束设置为延迟校验。以外键约束为例,可以成功避开无法更新父表主键和子表外键的尴尬。但是,提交时,延迟校验将生效。
持久性
数据存储于磁盘等介质。
隔离性
事务的隔离性是指,在事务的处理过程中,针对各事务之间的相互影响,所提出的对应策略。因为各是无语所执行的动作不同,因此,如果各事务之间相互影响,将使得最终的数据库处于不可预知的状态。SQL92归纳出了三种读取方式来概括可能出现的情况。
1.脏读取
脏读取意味着,可以读取来自外界其他动作对数据库的修改,而这种修改尚未提交,未提交的数据有可能回滚。也就是说,读取的数据并非真正有效的数据,这将直接破坏数据一致性。
2.不可重复读
不可重复读意味着,如果用户在某一时刻读取了一条记录,那么,在下一时刻再次读取时,该记录已经发生改变。其状态类似于“人不能两次踏入同一条河流”。不可重复读并非不可接受的,相反,不可重读是一种正常的数据库状态。这与脏读是有本质区别的。
3.影像读取
影像读取意味着,如果用户在某一时刻执行了一个查询,在下一时刻再次执行相同查询时,可能会有新的数据加入,但是,已经读取的数据是不会改变的, 只是查询所获得结果集更大而已。

SQL92标准定义了4种层次的事务处理的隔离性。这4种隔离层次是针对三种读取方式是否允许而设定的。它们分别是: 未提交读取(Read Uncommited)、已提交读取(Read Commited)、可重复读取(Repeatable Read) 和 串行读取(Serializable)。
隔离层次与读取方式关系表

隔离层次 脏读取 不可重复读 影像读取
未提交读取(Read Uncommited) 允许 允许 允许
已提交读取(Read Commited) 禁止 允许 允许
可重复读取(Repeatable Read) 禁止 禁止 允许
串行读取(Serializable) 禁止 禁止 禁止

三种读取方式实际是针对能否读取数据库中的变化而设定的。从表中可以看出,随着隔离层次的提高,读取方式的范围越来越小。这意味着隔离层次越高,对于数据库变化的反映越迟钝,而串行读取则不允许数据库中的任何变化反映到当前会话中
Oracle 中事务使用了两种SQL标准的隔离层次-已提交读取和串行读取。已提交读取是Oracle事务的默认隔离层次,即之前提到的read commited级别。串行读取则是serializable级别。

猜你喜欢

转载自blog.csdn.net/sdtvyyb_007/article/details/80010656