客户端 -->解析优化-->缓存-->存储引擎
并发控制
1、串行(队列)执行
2、读(共享锁) 写(排他锁)锁
锁粒度
1、表锁
2、行锁
行锁实现层在存储引擎上,mysql不同的存储引擎实现不尽相同
事务
ACID
Atomic/consistency/isolation/durability
隔离级别:一个事务执行修改还未提交,其他事务看到的还是修改前的数据。
隔离级别[
读未提交 : 没有提交的数据也会被读取到,脏读
读已提交 :没有提交的数据,即使执行了修改也不会读取到
重复读 :幻读,即在一个事务中读取相同行数据,即使数据行发生了改变,读到的数据是一致的,只读取统一版本号。
事务串行:事务之间按照串行执行。
]
死锁
事务之间循环等待提交释放行锁
死锁解决机制:
1、等待超时死锁异常
2、回滚最小事务
多版本并发控制 MvCC
multi-version-concurrent-controll
MVcc是行级锁的变种,在很多情况下避免了加锁操作,因此开销更低。
存储引擎执行一个事务时,系统事务版本号会 +1,事务的版本号为系统事务版本号。
重复读使用mvcc的实现:
select-->查找创建版本号小于等于当前事务版本号的且删除标识未定义或删除版本号大于当前事务号。
insert-->新建一条数据,并记录系统事务版本号
delete-->为删除的行记录删除版本号
update-->将原记录删除,记录删除版本号,并新建一条新记录,并记录创建版本号。
可见,mvcc的实现是在每行添加两列隐藏数据,创建版本号(xmin)、删除版本号(xmax)。
(1)当你插入一行记录时,MySql会把当前事务的XID存储在这一行中并称之为 xmin。
(2)对于那些已提交的而且xmin比当前事务的XID小的记录 才对当前事务可见。
(3)开始一个新事务然后插入一行记录,直到提交之前,你插入的这行记录对其他事务永远都是不可见的。
(4)提交以后,其他后创建的新事务就可以看到这行新记录了,因为他们满足了 xmin < XID 条件。
在read commit的事务隔离策略下,使用mvcc 是很容易实现的:
select -->只获取已提交&& xmin<XID的数据,这样就确保了每次获取的都是读已提交。
insert/delete/update同repeatable read
在repeatable read下,使用mvcc的实现:
select-->只获取xmin<XID && XID< xmax,这样就满足了每次读取的数据是一样的。
schema 数据库
表空间
数据据库真正存放数据的是数据文件,而表空间实际上是一个逻辑的概念,他在物理上是并不存在的,那么把一组data files逻辑形成一个表空间。
一个数据库可以包含多个表空间,一个表空间只能属于一个数据库;一个表空间包含多个数据文件,一个数据文件只能属于一个表空间
表这空间可以划分成更细的逻辑存储单元
从逻辑的角度来看,一个数据库(database)下面可以分多个表空间(tablespace);一个表空间下面又可以分多个段(segment);一个数据表要占一个段(segment),一个索引也要占一个段(segment )。 一个段(segment)由多个 区间(extent)组成,那么一个区间又由一组连续的数据块(data block)组成。这连续的数据块是在逻辑上是连续的,有可能在物理磁盘上是分散。
那么从物理的角度上看,一个表空间由多个数据文件组成,数据文件是实实在在存在的磁盘上的文件。这些文件是由oracle数据库操作系统的block 组成的。
常用数据类型
tinyInt 8
smallInt 16
mediumInt 24
Int 32
bigInt 64
unsigned 非负
float
double
不推荐使用decimal,第一是cpu不支持decimal的计算,而数据库通过逻辑装换调用cpu计算,第二是小数点占位1个字节,增加开销。
varchar 可变长 优点节省空间 缺点执行update 比定长慢,如将长度为2的update为长度50.
char 定长 优点不容易产生磁盘碎片,更新操作更快,不适合存储长字段。
text 类似与oracle中的clob
tinytext
smalltext
mediumtext
longtext
分区表
http://www.jb51.net/article/62290.htm
一个表最多有1024个分区,
range分区
create table t_range(
id int(11),
money int(11) unsigned not null,
date datetime
)partition by range(year(date))(
partition p2007 values less than (2008),
partition p2008 values less than (2009),
partition p2009 values less than (2010)
partition p2010 values less than maxvalue
);
分区合并
mysql> ALTER TABLE sale_data
-> REORGANIZE PARTITION p201001,p201002,p201003,
-> p201004,p201005,p201006,
-> p201007,p201008,p201009 INTO
-> (
-> PARTITION p2010Q1 VALUES LESS THAN (201004),
-> PARTITION p2010Q2 VALUES LESS THAN (201007),
-> PARTITION p2010Q3 VALUES LESS THAN (201010)
-> );
分区提供以下优点:
(1)由于将数据分散到各个分区中,减少了数据损坏的可能性;
(2)可以对单独的分区进行备份和恢复;
(3)可以将分区映射到不同的物理磁盘上,来分散IO;
(4)提高可管理性、可用性和性能。
Oracle10g/mysql提供了以下几种分区类型:
(1)范围分区(range);
(2)哈希分区(hash);
(3)列表分区(list);
(4)范围-哈希复合分区(range-hash);
(5)范围-列表复合分区(range-list)。
Range分区是应用范围比较广的表分区方式,它是以列的值的范围来做为分区的划分条件,将记录存放到列值所在的range分区中。
分区表的插入,不需要关心插入到那个分区表里,存储引擎已帮你完成,但是在创建分区条件的时候,不要使用逻辑运算,可能会造成插入的字段不能作为分区条件而不能插入。
视图
创建视图
create view test_view as select * from li_entry where bank_code = 'citiUK' ;
select * form test_view where va_card ='7888991';
临时表
create temporanry table tmp_test as select *from li_entry where bank_code ='citiUK';
select * from tmp_test where va_card ='1112233';
临时表和视图有什么区别呢?
视图是基于合并算法..
临时表基于临时表算法...
但视图底层还是一个临时表。
游标
游标的缺点:
1、关闭游标是而额外的开销
2、游标所在的临时表不支持text或blob字段,数据库将为其创建临时磁盘表,增加IO复杂性。