数据库常用知识

这些都是一些学习数据库必须要了解的知识,面试的时候也经常被问到,其实面试题也就是考察对知识的理解和掌握

 

面试中高危考点:索引

索引百度:定义概念:索引是为了加速对表中数据行进行检索而创建的一种分散的存储结构。

数据库索引:

添加的索引之后查询的速度回变快,相当于一本书的目录加快了查询的速度,索引是针对表而建立的,它是由数据页面以外的索引页面组成的,每个索引页面中的行都会含有逻辑指针,以便加速检索物理数据。

 

在数据库关系图中,可以在选定表的“索引/键”属性页中创建、编辑、删除每个索引类型。当保存索引所附加到的表,或保存该表所在的关系图时,索引将保存在数据库中。

 

 

索引的原理:索引就像一本字典加入了目录,加快了查询的速度。

索引的优点:

1。大大加快速度检索的速度。

2.创建唯一性索引,保证数据库中每一行数据的唯一性。

3.加速表和表之间的连接。

 

什么时候使用索引:频繁调用where字句的时候

不适合建立索引的字段: 更新频繁的字段不适合创建索引,不会出现在 where 子句中的字段不应该创建索引。

哪些字段适合建立索引:

占用存储空间少 存储空间固定的的字段更适合选作索引的关键字,。例如,与字符串相比,整数字段占用的存储空间较少,因此,较为适合选作索引关键字。与 text 类型的字段相比, char 类型的字段较为适合选作索引关键字。

 

 

 

 

索引的缺点:

1.索引需要占用物理空间

2.当对表中数据进行增加、删除和修改的时候,索引也要动态维护,降低了数据的维护速度。

MySQL中,布尔类型等价于TINYINT(1)。

 

 

 

 

数据库的优化:

 

1.创建数据库的索引

2.选取适当的字段属性

3.使用内连接来代替子查询

4.事务

5.锁定表 (在使用事务的时候,数据库会被锁定,这相当于是事务的替代,提高效率)

6.使用外键(保证数据的关联性)

7.优化查询语句

8.使用联合查询来代替手动创建的临时表

 

数据库范式

第一范式(1NF)表中的每个域值只能是实体的一个属性或一个属性的一部分。简而言之,第一范式就是无重复的域。

第二范式 (  2NF ) 在第一范式的基础上表中的每个非主属性都依赖于主属性(相当于非主键依赖于主键)

第三范式 (  3NF ) 在第二范式的基础上,表中每个非主属性互不依赖.

 

数据库的事务(面试考点)

事务就是对一系列的数据库操作进行统一的提交或回滚操作,比如说做一个转账功能,要更改帐户两边的数据,这时候就必须要用事务才能算是严谨的做法。要么成功,要么失败,保持数据一致性。如果中间有一个操作出现异常,那么回滚之前的所有操作。 

这样有什么好处呢。 

这样可以防止在一些意外(例如说突然断电)的情况下出现乱数据,防止数据库数据出现问题。这边加了钱,那边却还是一样的数,这就完了。要是开放一个网上交易的平台,这样就会出大问题的! 

还有其他的一些操作,像是要添加多条数据,如果程序要求必须全部正确才能插入的话,事务又起大作用了。 

等等。。。开发中为了避免这种情况一般都会进行事务管理。 

在JDBC中是通过Connection对象进行事务管理的,默认是自动提交事务,可以手工将自动提交关闭,通过commit方法进行提交,rollback方法进行回滚,如果不提交,则数据不会真正的插入到数据库中。 

Hibernate中是通过Transaction进行事务管理,处理方法与JDBC中类似。

Spring中也有自己的事务管理机制,使用TransactionMananger进行管理,可以通过Spring的注入来完成此功能。

 

 

 

 

事物的生命周期:

1数据库初始状态----->开始事物----执行SQL语句--->成功则提交事物,更新数据库,出现异常,则回滚到数据库的初始状态.

 

Spring事物的作用:理解Spring控制数据库事物的提交和回滚,(借助了反射的机制)如果你的你的方法内有异常抛出,Spring会捕获这个异常并且回滚到数据库的初始状态, 如果成功则提交事物,更新数据库 (比如说要添加多条数据,要求必须全部正确才能插入)

数数据库的

事务的4个特性:一致性,持久性,隔离性,原子性

原子性----一个事务中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节.事务在执行过程中发生错误,就会被回滚到事务开始前的状态,就像这个事务从来没有被执行过一样.

一致性---在事务开始之前和事务结束以后,数据库的完整性没有被破坏,即从一个一致性状态转换到另一个一致性状态.

隔离性---当两个或者多个事务并发访问数据库的同一数据所表现出的相互关系.通常李艾说,一个事务要做的修改在最终提交以前,对其他事务是不可见

持久性---在事务完成以后,该事务对数据库所做的更改便持久地保存在数据库之中

 

 

并发事务(同一时间进行的另一个事务)引起的3个安全问题(按顺序记忆):

1)脏读:A事务读取了B事务未提交的数据(一旦B数据回滚,导致A事务读取的数无效)

2)不可重复读,一个事务方法中连续查询了很多次,却得到不同的结果(原因:并发事务在两次查询的中间对数据进行了修改)

3)虚度/幻读,一个事物方法中连续查询了很多次,却得到不同的结果(原因:并发事务在两次查询的中间对数据进行了增删).

 

数据库的四个隔离级别(在面试中被问到了,为解决并发事务安全问题) 级别从低到高排列

1)未提交读:安全级别最低,3个并发事务安全问题都解决不了

2)以提交度:可以解决第一个问题(脏读)

3)可重复读:可以解决前两个问题(脏读和不可重复读).

4)串行(又称为可序列化):全部解决三个问题

 

mysql处理什么数量级的数据时,性能会急剧下降

1.这和Mysql的版本有很大关系,:如果是5.1的话,到了300W数据量的时候,性能就会大幅下降 ,如果是Mysql5.7是几千万数据量之后性能能会大幅下降,之后版本的话,基本就不怎么考虑数据量的问题了.

2.还有要看你使用的场景了,如果是单表的话,500w的数据量就会出现大幅的性能下滑,

 

 

  在中国互联网技术圈流传着这么一个说法:mysql单表数据量大于2000w条,性能会明显下降。所以这设计大数据存储时,多会以此为标准,进行分表操作。

 

 

  首先:这个传说是错的,但是这个结论在产生时有重要意义。

 

 

  传说起源:百度,当年DBA测试Mysql性能时发现,当单表的量在2000w量级的时候,sql操作的性能急剧下降。所以得到该结论。后百度的工程师流动到业界的其它公司,也带去了这个信息,所以就在业界流传开这么一个说法。

 

 

  真相:Mysql为了提高性能,会将表的索引装载到内存中,实现高效操作。当年百度的数据库服务器的内存有限,当单表数据库到达2000w的量级时,内存放不下表的索引了,而需要把部分索引装载到磁盘中,此时出现了性能的明显下降。

下面的乐观锁和悲观锁是我照搬一个CSDN老哥的,对我来说帮助很大,它的博客还有很多Java面试和学习的干货..........

这篇文章上面都是我写的,不想换成转载,勿喷....

---------------------

作者:SnailClimb在CSDN

来源:CSDN

原文:https://blog.csdn.net/qq_34337272/article/details/81072874

 

乐观锁和悲观锁

 

 

乐观锁对应于乐观的人总往着乐观的方向思考,悲观锁对应悲观的人往悲观的方向思考

悲观锁:

总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,每次在拿数据的时候都会上锁,这样别人想拿到这个数据就会被被阻塞到它拿到锁(共享资源每次只给一个线程使用,其他线程阻塞,用完之后再把资源转给其他线程) .传统的关系型数据库很多就用到了这样的锁,如行锁,表锁,读锁,写锁等,都是再操作之前先给他上锁.Java中synchronized和ReentrantLock都是这种悲观锁

乐观锁:

总假设最好的情况,每次去拿数据的时候都认为别人不会改变,所以不会上锁,但是会在更新的时候判断一下在这期间有没有人更新过这个数据,使用版本号机制和CAS算法实现,乐观锁适用于多读的类型,这样可以提高吞吐量.

 

两种锁的使用场景

 

两种锁都各有优点,但是都是不可或缺的,乐观锁适用于多读的场景,即这些冲突很少发生的操作,这样可以节省锁的开销,加大整个系统的吞吐量.如果是多写的操作,一般会经常发生冲突,这个时候我们就需要将数据进行不停进行重复操作,这样反倒降低了性能,所以一般多写的操作还是使用悲观锁比较好

 

乐观的两种实现方式:

 

1.版本号机制

实际上,一般是在数据表中加上一个数据版本号version字段,表示数据被修改的次数,当数据被修改时,version值会加一。每次进行修改的时候,会先读取数据,也会读取它的版本号,若是修改的时候版本号和当前数据库的版本号冲突,则重复上述操作,直到成功.

 

2.CAS算法

即compare and swap(比较与交换),是一种有名的无锁算法。无锁编程,即不使用锁的情况下实现多线程之间的变量同步,也就是在没有线程被阻塞的情况下实现变量的同步,所以也叫非阻塞同步(Non-blocking Synchronization)。CAS算法涉及到三个操作数

  • 需要读写的内存值 V
  • 进行比较的值 A
  • 拟写入的新值 B

当且仅当 V 的值等于 A时,CAS通过原子方式用新值B来更新V的值,否则不会执行任何操作(比较和替换是一个原子操作)。一般情况下是一个自旋操作,即不断的重试。

用自己的话简练一下:就是V的值是A,准备赋值的时候发现它仍然是A值,可以赋值.

 

乐观锁的缺点:

1.ABA问题

若是一个变量除此读取的时候是A值,准备赋值的时候读取的也是A值,能证明它没有被其他线程修改过吗?显然是不能的,因为在这段时间内,他们很可能被其他线程修改过,又被改回来了.但是CAS显然是不会判断出来的,

2.循环时间开销大

自旋CAS (也就是不成功就一直循环直到成功)如果长时间不成功,会给CPU带来非常大的执行开销,

3.只能保证一个共享变量的原子操作

CAS只对单个变量有效,对多个共享变量是没有效果的.

 

CAS与synchronized的使用情景

简单的来说CAS适用于写比较少的情况下(多读场景,冲突一般较少),synchronized适用于写比较多的情况下(多写场景,冲突一般较多)

 

对于资源竞争较少(线程冲突较轻)的情况,使用synchronized同步锁进行线程阻塞和唤醒切换以及用户态内核态间的切换操作额外浪费消耗cpu资源;而CAS基于硬件实现,不需要进入内核,不需要切换线程,操作自旋几率较少,因此可以获得更高的性能。

对于资源竞争严重(线程冲突严重)的情况,CAS自旋的概率会比较大,从而浪费更多的CPU资源,效率低于synchronized。

补充: Java并发编程这个领域中synchronized关键字一直都是元老级的角色,很久之前很多人都会称它为 “重量级锁” 。但是,在JavaSE 1.6之后进行了主要包括为了减少获得锁和释放锁带来的性能消耗而引入的 偏向锁 和 轻量级锁 以及其它各种优化之后变得在某些情况下并不是那么重了。synchronized的底层实现主要依靠 Lock-Free 的队列,基本思路是 自旋后阻塞,竞争切换后继续竞争锁,稍微牺牲了公平性,但获得了高吞吐量。在线程冲突较少的情况下,可以获得和CAS类似的性能;而线程冲突严重的情况下,性能远高于CAS。

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值