DB
在执行一条Sql
语句的时候,默认的方式是根据搜索条件进行全表扫描,遇到匹配条件的就加入搜索结果集合。(Database Transaction)
,是指对单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。不会
永久更新面向数据的资源。ACID
(原子性(Atomicity)
、一致性(Consistency)
、隔离性(Isolation)
、持久性(Durability))
属性。事务是数据库运行中的逻辑工作单位,由DBMS
中的事务管理子系统负责事务的处理。(Isolation)
隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。
T1
和T2
,在事务T1
看来,
T2
要么在T1
开始之前就已经结束,T1
结束之后才开始,多个并发事务相互隔离,即一个事务不应该影响其它事务运行效果。
不同的隔离级别:
Read Uncommitted
(读取未提交内容):最低的隔离级别,什么都不需要做,一个事务可以读到另一个事务未提交的结果。所有的并发事务问题都会发生。Read Committed
(读取提交内容):只有在事务提交后,其更新结果才会被其他事务看见。可以解决脏读问题。Repeated Read
(可重复读):在一个事务中,对于同一份数据的读取结果总是相同的,无论是否有其他事务对这份数据进行操作,以及这个事务是否提交。可以解决脏读、不可重复读。Serialization
(可串行化):事务串行化执行,隔离级别最高,牺牲了系统的并发性。可以解决并发事务的所有问题。inner join
, left join
, right join
,full join
inner join(内连接)
: 只返回两个表中联结字段相等的行left join(左联接)
: 返回包括左表中的所有记录和右表中联结字段相等的记录right join(右联接)
: 返回包括右表中的所有记录和左表中联结字段相等的记录full join(外连接)
: 返回两个表中的行事务(Transaction)
是由 一系列对系统中数据进行访问与更新的操作 所组成的一个程序执行逻辑单元。
事务是DBMS
中最基础的单位,它不可分割。
事务具有4个基本特征(ACID)
,分别是:原子性(Atomicity)
、一致性(Consistency)
、隔离性(Isolation)
、持久性(Duration)
,简称ACID
。
原子性(Atomicity)
一致性(Consistency)
A
和用户B
两者的钱加起来一共是5000
,那么不管A
和B
之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000
,这就是事务的一致性。隔离性(Isolation)
T1
和T2
,在事务T1
看来,
T2
要么在T1
开始之前就已经结束,T1
结束之后才开始,Read Uncommitted
(读取未提交内容):最低的隔离级别,什么都不需要做,一个事务可以读到另一个事务未提交的结果。所有的并发事务问题都会发生。Read Committed
(读取提交内容):只有在事务提交后,其更新结果才会被其他事务看见。可以解决脏读问题。Repeated Read
(可重复读):在一个事务中,对于同一份数据的读取结果总是相同的,无论是否有其他事务对这份数据进行操作,以及这个事务是否提交。可以解决脏读、不可重复读。Serialization
(可串行化):事务串行化执行,隔离级别最高,牺牲了系统的并发性。可以解决并发事务的所有问题。持久性(Durability)
JDBC
操作数据库时,在提交事务方法后,提示用户事务操作完成,当我们程序执行完成直到看到提示后,就可以认定事务以及正确提交,即使这时候数据库出现了问题,也必须要将我们的事务完全执行完成,否则就会造成我们看到提示事务处理完毕,但是数据库因为故障而没有执行事务的重大错误。DB
在执行一条Sql
语句的时候,默认的方式是根据搜索条件进行全表扫描,遇到匹配条件的就加入搜索结果集合。唯一性
, 加快数据检索速度
, 加速表的连接
, 加速分组和排序
, 使用优化隐藏器
创建和维护
, 降低维护速度
, 占物理空间
N少用
, N少值
, N特定类型
, 性能需求
text
、image
和bit
数据类型 的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少。数据库的设计范式是数据库设计所需要满足的规范,满足这些规范的数据库是简洁的、结构明晰的,同时,不会发生插入
(insert)
、删除(delete)
和更新(update)
操作异常。
R
的所有属性都不可再分为更基本的数据单位时,称R
是满足第一范式,即属性不可分R
满足第一范式,并且R
的所有非主属性都完全依赖于R
的每一个候选关键属性,称R
满足第二范式R
满足第一范式, 且R
中的任意属性集, 都非传递依赖于R
的任意一个候选关键属性,称R
满足第三范式,即非主属性不传递依赖于键码(1NF)
:列不可再分
(2NF)
: 属性完全依赖于主键
(2NF)
是在第一范式(1NF)
的基础上建立起来的,即满足第二范式(2NF)
必须先满足第一范式(1NF)
。(2NF)
要求数据库表中的每个实例或行必须可以被惟一地区分。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。这个惟一属性列被称为主键(3NF)
: 属性不依赖于其它非主属性, 属性直接依赖于主键
ACID
特性事务(Transaction)
是由 一系列对系统中数据进行访问与更新的操作 所组成的一个程序执行逻辑单元。
事务是DBMS
中最基础的单位,它不可分割。
事务具有4个基本特征(ACID)
,分别是:原子性(Atomicity)
、一致性(Consistency)
、隔离性(Isolation)
、持久性(Duration)
,简称ACID
。
原子性(Atomicity)
一致性(Consistency)
A
和用户B
两者的钱加起来一共是5000
,那么不管A
和B
之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000
,这就是事务的一致性。隔离性(Isolation)
T1
和T2
,在事务T1
看来,
T2
要么在T1
开始之前就已经结束,T1
结束之后才开始,Read Uncommitted
(读取未提交内容):最低的隔离级别,什么都不需要做,一个事务可以读到另一个事务未提交的结果。所有的并发事务问题都会发生。Read Committed
(读取提交内容):只有在事务提交后,其更新结果才会被其他事务看见。可以解决脏读问题。Repeated Read
(可重复读):在一个事务中,对于同一份数据的读取结果总是相同的,无论是否有其他事务对这份数据进行操作,以及这个事务是否提交。可以解决脏读、不可重复读。Serialization
(可串行化):事务串行化执行,隔离级别最高,牺牲了系统的并发性。可以解决并发事务的所有问题。持久性(Durability)
JDBC
操作数据库时,在提交事务方法后,提示用户事务操作完成,当我们程序执行完成直到看到提示后,就可以认定事务以及正确提交,即使这时候数据库出现了问题,也必须要将我们的事务完全执行完成,否则就会造成我们看到提示事务处理完毕,但是数据库因为故障而没有执行事务的重大错误。SQL
MySQL
主要包含四种隔离状态:事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交(read-uncommitted) |
是 | 是 | 是 |
不可重复读(read-committed) |
否 | 是 | 是 |
可重复读(repeatable-read) |
否 | 否 | 是 |
串行化(serializable) |
否 | 否 | 否 |
A
读到了事务B
未提交的数据。A
第一次查询得到一行记录row1
,事务B
提交修改后,事务A
第二次查询得到row1
,但列内容发生了变化。A
第一次查询得到一行记录row1
,事务B
提交修改后,事务A
第二次查询得到两行记录row1
和row2
。MySQL
的MVCC
机制MVCC
是一种多版本并发控制机制,是MySQL
的InnoDB
存储引擎实现隔离级别的一种具体方式,用于实现提交读和可重复读这两种隔离级别。MVCC
是通过保存数据在某个时间点的快照来实现该机制,其在每行记录后面保存两个隐藏的列,分别保存这个行的创建版本号和删除版本号,然后InnoDB
的MVCC
使用到的快照存储在Undo
日志中,该日志通过回滚指针把一个数据行所有快照连接起来。SQL
优化方法有哪些SQL
优化方法
where
、group by
使用到的字段(较频繁地作为查询条件且唯一性不太差),不会在where
中用到的字段不建立索引,因为建立索引也需要系统的开销。*
,用列名代替
select * from user
, 改写 select userID, userName, userSalary from user
;*
的时候,数据库还得查询数据字典,进而解析得到列名,而直接写出列名效率会更高些。%
),该查询数据库引擎会放弃索引进行全表扫描。NULL
值判断,可以给字段添加默认值0
,对0
值进行判断;也不要给数据库留NULL
,使用NOT NULL
填充。(否则会进行全表扫描,影响效率)where
条件中等号的左边进行表达式或函数操作,可以将表达式或函数移到等号右边。(否则会全表扫描)where
子句连接的时候,要把能过滤掉最大数量记录的条件写在最右边。(因为where
是从右往左解析的)truncate
而不用detele
delete
删除表的时候,会扫描整个表再一条一条删除;truncate
会一次性删除整个表的所有内容,不进行扫描,效率高。where
和having
都用的时候,先用where
,再用having
;where
先过滤(数据量变少),再分组,效率高。in
和not in
,会导致全表扫描
between
代替;如果是子查询,用exists
代替。where
和group by
的索引的子段*
,where
连接选择的时候, 将能筛选能力最强的子段放在最右边(从右往左解析)truncate
提到delete
in
和not in
会导致全表查询where
条件中等号的左端使用表达式或函数MySQL
引擎和区别MySQL
引擎
MySQL
中的数据用各种不同的技术存储在文件(或者内存)中。这些技术中的每一种技术都使用不同的存储机制、索引技巧、锁定水平并且最终提供广泛的不同的功能和能力。通过选择不同的技术,你能够获得额外的速度或者功能,从而改善你的应用的整体功能。MySQL
存储引擎主要有:MyIsam
、InnoDB
、Memory
、Blackhole
、CSV
、Performance_Schema
、Archive
、Federated
、Mrg_Myisam
。InnoDB
和Mylsam
。InnoDB
InnoDB
是一个事务型的存储引擎,有行级锁定和外键约束。Innodb
引擎提供了对数据库ACID
事务的支持,并且实现了SQL
标准的四种隔离级别,关于数据库事务与其隔离级别的内容请见数据库事务与其隔离级别这类型的文章。MySQL
后台的完整数据库系统,MySQL
运行时Innodb
会在内存中建立缓冲池,用于缓冲数据和索引。FULLTEXT
类型的索引,而且它没有保存表的行数,当SELECT COUNT(*) FROM TABLE
时需要扫描全表。Innodb
引擎会提升效率。SQL
语句时MySQL
不能确定要扫描的范围,InnoDB
表同样会锁全表。bin-log
日志等)。auto_increment
。InnoDB
也是B+Treee
索引结构。InnoDB
的索引文件本身就是数据文件,即B+Tree
的数据域存储的就是实际的数据,这种索引就是聚集索引。这个索引的key
就是数据表的主键,因此InnoDB
表数据文件本身就是主索引。InnoDB
的辅助索引数据域存储的也是相应记录主键的值而不是地址,所以当以辅助索引查找时,会先根据辅助索引找到主键,再根据主键索引找到实际的数据。所以 Innodb
不建议使用过长的主键 ,否则会使辅助索引变得过大。建议使用自增的字段作为主键,这样B+Tree
的每一个结点都会被顺序的填满,而不会频繁的分裂调整,会有效的提升插入数据的效率。BTree
: 对于m
阶BTree
m
个孩子节点ceil(m/2)
个节点ceil(m/2)
,小于等于m
B+Tree
相对于B-Tree
有几点不同:
Mylsam
MyIASM
是MySQL
默认的引擎,但是它没有提供对数据库事务的支持,也不支持行级锁和外键,因此当INSERT
或UPDATE
数据时即写操作需要锁定整个表,效率便会低一些。MyIsam
存储引擎独立于操作系统,也就是可以在windows
上使用,也可以比较简单的将数据转移到linux
操作系统上去。MyIsam
存储引擎,可以在service
层进行根据自己的业务需求进行相应的控制。insert
和update
的操作比较多的话比较适用。MyISAM
极度强调快速读取操作。MyIASM
中存储了表的行数,于是SELECT COUNT(*) FROM TABLE
时只需要直接读取已经保存好的值而不需要进行全表扫描。MyIASM
也是很好的选择。MyISAM
索引结构:MyISAM
索引用的B+ tree
来储存数据,MyISAM
索引的指针指向的是键值的地址,地址存储的是数据。B+Tree
的数据域存储的内容为实际数据的地址,也就是说它的索引和实际的数据是分开的,只不过是用索引指向了实际的数据,这种索引就是所谓的非聚集索引。InnoDB
和Mylsam
的区别:
MyISAM
类型不支持事务处理等高级处理,而InnoDB
类型支持,提供事务支持已经外部键等高级数据库功能。MyISAM
只支持表锁。InnoDB
支持表锁、行锁 行锁大幅度提高了多用户并发操作的新能。但是InnoDB
的行锁,只是在WHERE
的主键是有效的,非主键的WHERE
都会锁全表的。InnoDB
中不保存表的具体行数,也就是说,执行select count() fromtable
时,InnoDB
要扫描一遍整个表来计算有多少行,但是MyISAM
只要简单的读出保存好的行数即可。注意的是,当count()
语句包含where
条件时,两种表的操作是一样的。MyISAM
类型的表强调的是性能,其执行数度比InnoDB
类型更快。AUTO_INCREMENT
类型的字段,InnoDB
中必须包含只有该字段的索引,但是在MyISAM
表中,可以和其他字段一起建立联合索引。MyISAM
支持全文索引(FULLTEXT)
、压缩索引,InnoDB
不支持。MyISAM
的索引和数据是分开的,并且索引是有压缩的,内存使用率就对应提高了不少。能加载更多索引,而Innodb
是索引和数据是紧密捆绑的,没有使用压缩从而会造成Innodb
比MyISAM
体积庞大不小。InnoDB
存储引擎被完全与MySQL
服务器整合,InnoDB
存储引擎为在主内存中缓存数据和索引而维持它自己的缓冲池。InnoDB
存储它的表&索引在一个表空间中,表空间可以包含数个文件(或原始磁盘分区)。这与MyISAM
表不同,比如在MyISAM
表中每个表被存在分离的文件中。InnoDB
表可以是任何尺寸,即使在文件尺寸被限制为2GB
的操作系统上。InnoDB
必须导出SQL
来备份,LOAD TABLE FROM MASTER
操作对InnoDB
是不起作用的,解决方法是首先把InnoDB
表改成MyISAM
表,导入数据后再改成InnoDB
表,但是对于使用的额外的InnoDB
特性(例如外键)的表不适用。MyISAM
应对错误编码导致的数据恢复速度快。MyISAM
的数据是以文件的形式存储,所以在跨平台的数据转移中会很方便。在备份和恢复时可单独针对某个表进行操作。InnoDB
是拷贝数据文件、备份binlog
,或者用mysqldump
,在数据量达到几十G
的时候就相对痛苦了。Mysql
引擎以及其区别Mysql
数据库中,常用的引擎为Innodb
和MyIASM
Redis
mongodb
和Redis
的区别Redis
数据全部存在内存,定期写入磁盘,当内存不够时,可以选择指定的LRU
算法删除数据。MongoDB
数据存在内存,由linux
系统mmap
实现,当内存不够时,只将热点数据放入内存,其他数据存在磁盘。Redis
支持的数据结构丰富,包括hash
、set
、list
等。MongoDB
数据结构比较单一,但是支持丰富的数据表达,索引,最类似关系型数据库,支持的查询语言非常丰富Redis
的定时机制怎么实现的Redis
服务器是一个事件驱动程序,服务器需要处理以下两类事件:
Redis
服务器通过套接字与客户端(或者其他Redis
服务器)进行连接,而文件事件就是服务器对套接字操作的抽象。服务器与客户端(或者其他服务器)的通信会产生相应的文件事件,而服务器则通过监听并处理这些事件来完成一系列网络通信操作;Redis
服务器中的一些操作(比如serverCron
函数)需要在给定的时间点执行,而时间事件就是服务器对这类定时操作的抽象。Redis
的定时机制就是借助时间事件实现的。id
:时间事件标识号;when
:记录时间事件的到达时间;timeProc
:时间事件处理器,当时间事件到达时,服务器就会调用相应的处理器来处理时间事件。套接字
: 文件事件是对套接字操作的抽象, 当每个套接字准备好执行应答
、写入
、读取
、关闭
等操作时, 就会产生一个文件事件。因为一个服务器通常会连接多个套接字,所以多个文件事件有可能会并发地出现。I/O多路复用程序
: 负责监听多个套接字,并向文件事件分派器传送那些产生了事件的套接字。尽管多个文件事件可能会并发地出现,但I/O
多路复用程序总是会将所有产生事件的套接字都放到一个队列里面,然后通过这个队列,以有序(sequentially)
、同步(synchronously)
、每次一个套接字的方式向文件事件分派器传送套接字。文件事件分派器(dispatcher)
: 接收I/O
多路复用程序传来的套接字,并根据套接字产生的事件的类型,调用相应的事件处理器;事件处理器
: 事件处理器是一个个函数,它们定义了某个事件发生时,服务器应该执行的动作。Redis
是单线程的,但是为什么这么高效呢?Redis
将套接字操作抽象为了文件事件, 当每个套接字准备好执行应答
、写入
、读取
、关闭
等操作时, 就会产生一个文件事件。因为一个服务器通常会连接多个套接字,所以多个文件事件有可能会并发地出现。套接字
: 文件事件是对套接字操作的抽象, 当每个套接字准备好执行应答
、写入
、读取
、关闭
等操作时, 就会产生一个文件事件。因为一个服务器通常会连接多个套接字,所以多个文件事件有可能会并发地出现。I/O多路复用程序
: 负责监听多个套接字,并向文件事件分派器传送那些产生了事件的套接字。尽管多个文件事件可能会并发地出现,但I/O
多路复用程序总是会将所有产生事件的套接字都放到一个队列里面,然后通过这个队列,以有序(sequentially)
、同步(synchronously)
、每次一个套接字的方式向文件事件分派器传送套接字。文件事件分派器(dispatcher)
: 接收I/O
多路复用程序传来的套接字,并根据套接字产生的事件的类型,调用相应的事件处理器;事件处理器
: 事件处理器是一个个函数,它们定义了某个事件发生时,服务器应该执行的动作。Redis
的数据类型有哪些,底层怎么实现?embstr
编码的简单动态字符串、简单动态字符串(SDS)
Redis
的rehash
怎么做的,为什么要渐进rehash
,渐进rehash
又是怎么实现的?redis
是单线程,当K
很多时,如果一次性将键值对全部rehash
,庞大的计算量会影响服务器性能,甚至可能会导致服务器在一段时间内停止服务。不可能一步完成整个rehash
操作,所以redis
是分多次、渐进式的rehash
。redis
时,额外做一步rehash
, 对redis
做读取、插入、删除等操作时,会把位于table[dict->rehashidx]
位置的链表移动到新的dictht
中,然后把rehashidx
做加一操作,移动到后面一个槽位。rehash
, 后台定时任务rehash
调用链,同时可以通过server.hz
控制rehash
调用频率Redis
和memcached
的区别redis
数据类型丰富,支持set liset
等类型;memcache
支持简单数据类型,需要客户端自己处理复杂对象redis
支持数据落地持久化存储;memcache
不支持数据持久存储。)redis
支持master-slave
复制模式;memcache
可以使用一致性hash
做分布式。value
大小不同:memcache
是一个内存缓存,key
的长度小于250
字符,单个item
存储要小于1M
,不适合虚拟机使用redis
使用的是单线程模型,保证了数据按顺序提交;memcache
需要使用cas
保证数据一致性。CAS(Check and Set)
是一个确保并发一致性的机制,属于“乐观锁”范畴;原理很简单:拿版本号,操作,对比版本号,如果一致就操作,不一致就放弃任何操作cpu
利用:redis
单线程模型只能使用一个cpu
,可以开启多个redis
进程