1.索引:是对数据库表中要查询的字段建立索引其实就是把该字段按照一定的方式排序的结构。
索引的意义:是用于提高数据库表的数据查询速度的。
①主索引:主索引是一种只能在数据库表中建立不能在自由表中建立的索引。在指定的字段或表达式中,主索引的关键字绝对不允许有重复值。
②候选索引:和主索引类似,它的值也不允许在指定的字段或表达式中重复。一个表中可以有多个候选索引。
③唯一索引:唯一索引允许关键字取重复的值。当有重复值出现时,索引文件只保存重复值的第1次出现。提供唯一索引主要是为了兼容早期的版本。
④普通索引:普通索引允许关键字段有相同值。在一对多关系的多方,可以使用普通索引。
(1)索引概述
数据库索引是用于提高数据库表的数据访问速度的。想要理解索引原理必须清楚一种数据结构「平衡树」(非二叉),也就是b tree或者 b+ tree,重要的事情说三遍:“平衡树,平衡树,平衡树”。当然, 有的数据库也使用哈希桶作用索引的数据结构 。然而,主流的RDBMS都是把平衡树当做数据表默认的索引数据结构的。
(2)特点
a)避免进行数据库全表的扫描,大多数情况,只需要扫描较少的索引页和数据页,而不是查询所有数据页。而且对于非聚集索引,有时不需要访问数据页即可得到数据。
b)聚集索引可以避免数据插入操作,集中于表的最后一个数据页面。
c)在某些情况下,索引可以避免排序操作。
使用索引:
1. 在数据量超过几百行之后就应该考虑建立索引,在主键上建立索引,保证数据的唯一性和组织表中的数据排列结构
2. 在经常使用到的查询列上建立索引,比如 where name = “wang” ,经常做这样的查询,那么name上就应该建立索引
3. 在经常进行范围查询的列上建立索引(可以建立聚簇索引,让索引的顺序和数据的物理存放顺序一致,这样大大的加快的查找的速度,变随机查找为顺序查找)
4. 在经常用在连接的列上,在连接字段列上建立索引,这些列主要是一些外键,可以加快连接的速度;
5. 在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间;
不该使用索引:
1. 数据量太小不要建立索引,因为维护的代价要高于建立索引之后优化的代价
2. 经常频繁更新的列不要建立索引,因为一旦更新,就要对索引也要随之更新,如果更新的代价比查询的代价高,那就不要建立索引
3. 不经常被引用、查询的列不要建立索引,因为没有必要
4. 对于那些列的取值很少(比如性别),或者text等类型的大文本字段不要建立索引,大文本字段的索引也会很长,影响查询
(3)聚集索引和非聚集索引的区别
在聚集索引中,表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个聚集索引。如果某索引不是聚集索引,则表中行的物理顺序与键值的逻辑顺序不匹配。与非聚集索引相比,聚集索引通常提供更快的数据访问速度。聚集索引和非聚集索引的区别,如字典默认按字母顺序排序,读者如知道某个字的读音可根据字母顺序快速定位。因此聚集索引和表的内容是在一起的。如读者需查询某个生僻字,则需按字典前面的索引,举例按偏旁进行定位,找到该字对应的页数,再打开对应页数找到该字。这种通过两个地方而查询到某个字的方式就如非聚集索引。
非聚集索引和聚集索引的区别在于, 通过聚集索引可以查到需要查找的数据, 而通过非聚集索引可以查到记录对应的主键值 , 再使用主键的值通过聚集索引查找到需要的数据。
2.数据库的3中基本语言
DML(data manipulation language)是数据操纵语言:它们是SELECT、UPDATE、INSERT、DELETE,就象它的名字一样,这4条命令是用来对数据库里的数据进行操作的语言。
DDL(data definition language)是数据定义语言:DDL比DML要多,主要的命令有CREATE、ALTER、DROP等,DDL主要是用在定义或改变表(TABLE)的结构,数据类型,表之间的链接和约束等初始化工作上,他们大多在建立表时使用。
DCL(DataControlLanguage)是数据库控制语言:是用来设置或更改数据库用户或角色权限的语句,包括(grant,deny,revoke等)语句。
3.完整性.
实体完整性指表中行的完整性
域完整性指列的值域的完整性,如数据类型、格式、值域范围、是否允许空值等等
参照完整性基于外键与被引用主键之间的关系,确保键值在所有表中的一致性
4.数据库中的锁
(1)为什么要引入锁
多个用户同时对数据库的并发操作时会带来以下数据不一致的问题:
丢失更新:A,B两个用户读同一数据并进行修改,其中一个用户的修改结果破坏了另一个修改的结果,比如订票系统 。
脏读:A用户修改了数据,随后B用户又读出该数据,但A用户因为某些原因取消了对数据的修改,数据恢复原值,此时B得到的数据就与数据库内的数据产生了不一致 。
不可重复读:A用户读取数据,随后B用户读出该数据并修改,此时A用户再读取数据时发现前后两次的值不一致
并发控制的主要方法是封锁,锁就是在一段时间内禁止用户做某些操作以避免产生数据不一致
丢失修改:两个事务T1和T2读入同一数据并修改,T2提交的结果破坏了T1提交的结果,导致T1的修改被丢失。
不可重复读:指事务T1读取数据后,事务T2执行更新操作,使T1无法再现前一次读取结果。
读"脏"数据:指事务T1修改某一数据,并将其写回磁盘,事务T2读取同一数据后,T1由于某种原因被撤消,这时T1已修改过的数据恢复原值,T2读到的数据就与数据库中的数据不一致,则T2读到的数据就为"脏"数据,即不正确的数据。
(2)锁的分类
共享锁(Shared lock) ;
更新锁(Update lock) :为解决死锁,引入更新锁;
排他锁(独占锁,Exclusive Locks):这个简单,即其它事务既不能读,又不能改排他锁锁定的资源。
意向锁就是说在屋(比如代表一个表)门口设置一个标识,说明屋子里有人(比如代表某些记录)被锁住了。另一个人想知道 屋子 里是否有人被锁,不用进屋子里一个一个的去查,直接看门口标识就行了。
计划锁(Schema Locks)
(3)如何避免死锁
1 使用事务时,尽量缩短事务的逻辑处理过程,及早提交或回滚事务;
2 设置死锁超时参数为合理范围,如:3分钟-10分种;超过时间,自动放弃本次操作,避免进程悬挂;
3 优化程序,检查并避免死锁现象出现;
4 .对所有的脚本和SP都要仔细测试,在正是版本之前。
5 所有的SP都要有错误处理(通过@error)
6 一般不要修改SQL SERVER事务的默认级别。不推荐强行加锁
(4)如何提高并发效率
悲观锁:利用数据库本身的锁机制实现。通过上面对数据库锁的了解,可以根据具体业务情况综合使用事务隔离级别与合理 的手工指定锁的方式比如降低锁的粒度等减少并发等待。
乐观锁:利用程序处理并发。原理都比较好理解,基本一看即懂。方式大概有以下3种
对记录加版本号.
对记录加时间戳.
对将要更新的数据进行提前读取、事后对比。
数据库乐观锁与悲观锁
- 悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作
- 乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。
5.范式
第一范式:原子性,字段不可分割
第二范式:没有包含在主键中的列必须完全依赖于主键,而不能只依赖于主键的一部分。
第三范式:不能存在传递依赖
6.写法顺序:select--from--where--group by--having--order by
执行顺序:from--where--group by--having--select--order by
7.层次模型:用树状<层次>结构来组织数据的数据模型
网状模型:用有向图表示实体和实体之间的联系的数据结构模型
关系模型:使用表格表示实体和实体之间关系的数据模型
8.一个表可以建立 多个普通索引,多个唯一索引,多个候选索引,一个主索
9.数据库的主从复制
一、什么是主从复制?
主从复制,是用来建立一个和主数据库完全一样的数据库环境,称为从数据库;主数据库一般是准实时的业务数据库。
二、主从复制的作用(好处,或者说为什么要做主从)重点!
1、做数据的热备,作为后备数据库,主数据库服务器故障后,可切换到从数据库继续工作,避免数据丢失。
2、架构的扩展。业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问的频率,提高单个机器的I/O性能。
3、读写分离,使数据库能支撑更大的并发。在报表中尤其重要。由于部分报表sql语句非常的慢,导致锁表,影响前台服务。如果前台使用master,报表使用slave,那么报表sql将不会造成前台锁,保证了前台速度。
三、主从复制的原理(重中之重,面试必问):
1.数据库有个bin-log二进制文件,记录了所有sql语句。
2.我们的目标就是把主数据库的bin-log文件的sql语句复制过来。
3.让其在从数据的relay-log重做日志文件中再执行一次这些sql语句即可。
4.下面的主从配置就是围绕这个原理配置
5.具体需要三个线程来操作:
1.binlog输出线程:每当有从库连接到主库的时候,主库都会创建一个线程然后发送binlog内容到从库。在从库里,当复制开始的时候,从库就会创建两个线程进行处理:
2.从库I/O线程:当START SLAVE语句在从库开始执行之后,从库创建一个I/O线程,该线程连接到主库并请求主库发送binlog里面的更新记录到从库上。从库I/O线程读取主库的binlog输出线程发送的更新并拷贝这些更新到本地文件,其中包括relay log文件。
3.从库的SQL线程:从库创建一个SQL线程,这个线程读取从库I/O线程写到relay log的更新事件并执行。
可以知道,对于每一个主从复制的连接,都有三个线程。拥有多个从库的主库为每一个连接到主库的从库创建一个binlog输出线程,每一个从库都有它自己的I/O线程和SQL线程。
步骤一:主库db的更新事件(update、insert、delete)被写到binlog
步骤二:从库发起连接,连接到主库
步骤三:此时主库创建一个binlog dump thread线程,把binlog的内容发送到从库
步骤四:从库启动之后,创建一个I/O线程,读取主库传过来的binlog内容并写入到relay log.
步骤五:还会创建一个SQL线程,从relay log里面读取内容,从Exec_Master_Log_Pos位置开始执行读取到的更新事件,将更新内容写入到slave的db.
四.数据库的优化
① SQL语句及索引的优化
SQL语句的优化:
1、尽量避免使用子查询
2、避免函数索引
3、用IN来替换OR
4、LIKE前缀%号、双百分号、_下划线查询非索引列或*无法使用到索引,如果查询的是索引列则可以
5、读取适当的记录LIMIT M,N,而不要读多余的记录
6、避免数据类型不一致
7、分组统计可以禁止排序sort,总和查询可以禁止排重用union all
8、避免随机取记录
9、禁止不必要的ORDER BY排序
10、批量INSERT插入
11、不要使用NOT等负向查询条件
12、尽量不用select *
13、区分in和exists
索引的优化:
1、Join语句的优化:
2、避免索引失效
② 数据库表结构的优化:使得数据库结构符合三大范式与BCNF
③ 系统配置的优化
④ 硬件的优化
六.数据库中事务的相关知识
(1)、事务的基本要素(ACID)
1、原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。
2、一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。
3、隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。
4、持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。
(2)、事务的并发问题
1、脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据
2、不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。
3、幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。
小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表
(3)、MySQL事务隔离级别
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
读未提交(read-uncommitted) | 是 | 是 | 是 |
不可重复读(read-committed) | 否 | 是 | 是 |
可重复读(repeatable-read) | 否 | 否 | 是 |
串行化(serializable) | 否 | 否 | 否 |
七。mysql数据库引擎
MySQL存储引擎MyISAM与InnoDB区别
MyISAM索引与InnoDB索引的区别?
InnoDB索引是聚簇索引,MyISAM索引是非聚簇索引。
InnoDB的主键索引的叶子节点存储着行数据,因此主键索引非常高效。
MyISAM索引的叶子节点存储的是行数据地址,需要再寻址一次才能得到数据。
InnoDB非主键索引的叶子节点存储的是主键和其他带索引的列数据,因此查询时做到覆盖索引会非常高效
八.按照规范的设计方法,一个完成的数据库设计一般分为以下六个阶段:
1. 需求分析: 分析用户的需求,包括数据、功能和性能需求;
2. 概念结构设计:主要采用E-R模型进行设计,包括画E-R图;
3. 逻辑结构设计:通过将E-R图转换成表,实现从E-R模型到关系模型的转换,进行关系规范化;
4. 数据库物理设计:主要是为所设计的数据库选择合适的存储结构和存储路径;
5. 数据库的实施:包括编程、测试和试运行;
6. 数据库运行和维护:系统的运行和数据库的日常维护