Mysql 区别预其他数据库最重要的特点就是
插件式的表存储引擎
支持事务, 主要面向在线事务处理(OLTP online transaction processing)方面的应用
innoDb存储引擎将数据放在一个逻辑的表空间中, 将每个innodb存储引擎的表单独放到一个独立的ibd文件中.
官方提供的引擎, 对于一些OLAP( online analytical processing在线分析处理)操作速度快.
特点: 不支持事务,支持表锁,支持全文索引
构成: MYD和MYI, MYD用来存放数据文件, MYI用来存放索引文件. (可以通过myisampack 来压缩数据文件, 压缩后只读)
数据量支持
集群存储引擎
非常适合存储归档数据,如:日志信息
新开发的引擎, 目标时取代原有的MyISM存储引擎
组成 共7个线程
IO thread的数量由配置文件中的inoodb_file_io_thread参数控制, 默认为4 (linux平台下不可用)
InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理
组成
缓冲池(buffer pool) --- innodb_buffer_pool_size (从InnoDB1.0.x版本开始,允许设置多个缓冲池实例,即参数innodb_buffer_pool_instances)
缓冲池是占最大块内存的部分, 工作方式: 将数据库文件按页(每页16k)读到缓冲池,然后按照最少使用(LRU)的算法来保留其中的数据
如果要修改数据, 总是先修改缓冲池中的页(修改后即为脏页),即缓冲池中的数据和磁盘上的数据不一致,这时数据库会通过checkpoint机制将脏页刷新回磁盘,而Flush列表中的数据即为脏页列表(脏页既存在与LRU列表,也存在与Flush列表,LRU列表用来管理缓冲池中页的可用性,Flush列表用来管理将页刷新回磁盘,二者不影响)
包含的数据页类型
LRU List/ Free List / Flush List
缓冲池占很大的一片内存区域,那么如何管理呢? 通常来说,数据库中的缓冲池是通过LRU算法来管理的,即频繁使用的页在LRU列表的前端,最少使用的页在LRU列表的尾部。当缓冲池不能存放新读取到的页时,将首先释放LRU列表中尾端的页。
在InnoDB引擎中,缓冲池中页的大小为16kb,同样使用LRU算法对缓冲池进行管理。稍有不同的是对LRU算法进行了优化。即在LRU列表中加入了midpoint位置,即新读取到的页并不是直接放入到LRU列表的首部,而是放入到midpoint位置(在默认配置下,midpoint在LRU列表的5/8处。该大小由参数innodb_old_blocks_pct控制,该值默认为37,即尾部的3/8处)。
在InnoDB引擎中,把midpoint之后的列表称为old列表,之前的成new列表(可以简单的理解new列表中的数据为热点数据)
InnoDB引擎从1.0.x版本开始支持压缩页功能,即将原本16kb的页压缩成1kb、2kb、4kb、8kb。由于页的大小发生了变化,LRU列表页发生了变化,对于非16kb的页,通过unzip_LRU列表来进行管理,通过show engine innodb status来观察(LRU的数量包含unzip_LRU的数量)。
unzip_LRU是如何分配内存的呢?(录入申请4kb的内存)
-- 通过information_schema架构下的INNODB_BUFFER_LRU观察unzip_LRU的情况
select * from information_schema.innodb_buffer_lru where compressed_size <> 0;
重做日志缓冲池(redo log buffer) --- innodb_log_buffer_size
InnoDB引擎首先将重做日志信息放入这个缓冲区,然后以一定的频率将其刷新到重做日志文件。重做日志缓冲一般不需要多大,因为一般情况下每秒都会讲重做日志缓冲刷新到日志文件。(默认为8MB)
以下三种情况会刷新到文件:
额外的内存池(additional memory pool)--- innodb_additional_men_pool_size
innodb存储引擎的主要工作都是在一个单独的线程master thread 中完成的。
master thread 优先级最高
组成
主循环 (loop)
大多数的操作都是在loop中, 其操作分为两大部分:每秒钟的操作和每十秒钟的操作
void master_thread() {
loop;
for(int i = 0; i < 10; i++){
// do thing once per second
// sleep 1 second if necessary
}
// do things once per ten seconds
goto loop;
}
loop循环主要通过sleep来实现(每秒和每10秒并不是精确的)
后台循环(background loop)
刷新循环(flush loop)
暂停循环(suspend loop)
包括:插入缓冲、两次写(double write)、自适应哈希索引(adaptive hash index)、异步io(Async IO)、刷新邻接页(Flush neighbor page)
insert buffer和数据页一样,也是物理页的一个组成部分
我们知道, 主键是行唯一的标识符,在应用程序中行记录的插入顺序是按照主键递增的顺序进行插入的。因此,插入聚集索引一般是顺序的,不需要磁盘的随机读取。比如:
>mysql create table t (id int auto_increment, name varchar(20), primary key(id));
id是自增长的,这意味着当执行插入操作时,id列会自动增长,页中的行记录按id执行顺序存放。
一般情况下不需要随机读取另一页执行记录的存放。这种情况下插入操作一般很快能完成。
但是,如果表中存在一个非聚集的辅助索引(secondary index)。比如:按照name这个字段查找,并且name不是唯一的,建表语句如下:
>mysql create table t(id int auto_increment, name varchar(20), primary key(id), key(name))
这样就产生了一个非聚集的并且不是唯一的索引。在插入时,数据页的存放还是按主键id的执行顺序存放,但是对于非聚集索引,叶子节点的插入不是顺序的了。这时就需要离散的访问非聚集索引页,插入性能在这里就变低了。
插入缓存
对于非聚集索引的插入Insert和更新update操作,不是一次直接插入到索引页种,而是先判断插入的非聚集索引页是否在缓冲池中,如果存在,则先入InesrtBuffer 对象中,然后再以一定的频率执行插入缓冲和非聚集索引页子节点的合并操作,这样就大大提高了性能。
插入缓冲
的使用要满足两个条件:
存在的问题: 在写密集的情况下,会占用大量的缓冲池内存(innodb_buffer_poll),默认最大可以占用1/2的内存
InnoDB从1.0.x 版本开始引入了Change Buffer,可将其视为Insert Buffer 的升级版,从这个版本开始,InnoDB引擎可以对DML操作--INSERT/DELETE/UPDATE都进行缓冲,即:Insert Buffer、Delete Buffer、Purge Buffer
和Insert Buffer 一样,ChangeBUffer 适用于非唯一的辅助索引。
对一条 UPDATE 操作可以分为两个过程:
Insert Buffer 使用场景:非唯一索引的插入操作
Insert Buffer 的数据结构是一棵B+树(在 Mysql4.1版本之前,每个表都有一个对应的B+树,现在版本中,全局只有1个B+树,负责对所有的辅助索引的缓存,这个B+树存放在共享表空间中(ibdata1))
Insert Buffer 是一棵B+树,因此是由叶子节点和非叶子节点构成。非叶子节点存放的是查询的 search key(键值):
search key
一共占用9个字节。
space
表示带插入记录所在表的表空间 id(在 Innodb 引擎中,每个表都有一个唯一的 spaceid),占4个字节
marker
是用来兼容老版本的 Insert Buffer,占1个字节
offset
表示页所在的偏移量,占4个字节
插入过程:
? 当一个辅助索引要插入到页(space,offset)时,如果该页不在缓冲池中,那么 InnoDB 引擎首先更具上述规则构造一个 search key
,接下来将这条记录插入的 Insert Buffert 中(插入并不是直接插入的,需要根据以下规则进行构造):
space、marker、page_no 字段和之前一样,占用9个字节。matadata 占用4个字节。因此同样的记录,InsertBuffer 中的记录比原记录多额外的13字节的开销。
启用 Insert Buffer 索引后,辅助索引页(space,page_no)中的记录可能被插入到 Insert Buffer 的B+树中,所以为了保证每次 Merge Insert Buffer成功,需要有一个特殊的页用来标记每个辅助索引页的可用空间(也就是 Insert Buffer Bitmap)。
每个 Insert Buffer Bitmap 页用来跟踪16384个辅助索引页,也就是256个区(extent),每个 Insert Buffer Bitmap 页都在16384个页的第二个页中。
Merge Insert Buffer 的操作发生的几种情况:
插入缓存带来的是性能, 两次写带来的是可靠性
写失效(partial page wirte):数据库正在写页时,数据库宕机, 此时页(16k)只写了一部分
double write: 在执行重做日志之前,我们需要一个副本,当写失效发生时,先通过副本来还原页,然后再进行重做。
由两部分组成:一部分是内存中的doublewrite buffer, 大小为2MB;另一部分时物理磁盘上共享表空间(ib_datafile)中连续的128个页(128*16k=2MB),即两个区(extent)。
当缓冲池中的脏页刷新时,并不直接写磁盘,而是会通过memcpy函数将脏页先拷贝到内存中的doublewrite buffer,之后通过doublewrite buffer再分两次,每次写入1MB到共享表空间的物理磁盘上,然后马上调用fsync函数,同步磁盘,避免缓冲写带来的问题。再完成doublewrite页的写入后,再将doublewrite buffer中的页写入各个表空间文件中,此时写入是离散的。
通过命令show global status like ‘innodb_dblwr_%‘
可以看到 double write 的运行情况:
可以看到 double write 一共写了6325194个页,但实际写入次数为100399,基本符合64:1.如果系统高峰时 Innodb_dblwr_pages_writtens:innodb_dblwr_writes 远小于64:1时,说明系统写入压力不高。
hash 是一种查询非常块的方法,时间复杂度 O(1),B+树的查询复杂度基于树的高度,一般生产环境中,B+树的高度一般为34层,顾需要34次查询
innodb存储引擎会监控对上索引的查找,如果观察到建立hash索引可以带来速度的提升,则建立哈希索引
自适应hash索引通过缓冲池的B+树构造而来的,因此建立的速度很块,而且不需要对整个表都建立,InnoDb会自动根据访问的频率和模式为某些页建立hash索引
为了提高磁盘操作性能,当前数据库系统都采用异步 IO 的方式来处理磁盘操作.
在 Innodb 存储引擎中,read ahead、脏页的刷新(即磁盘写入操作)都是有 AIO 完成。
-- 查看是否开启native io
show variables like ‘innodb_use_native_io‘;
原理:当刷新一个页时,Innodb 引擎会检测该页所在的区(extent,64个页)的所有页,如果是脏页,那么一起刷新。
好处:通过 AIO 可以将多个 IO 写入操作合并为一个 IO 操作
参数:innodb_flush_neighbors
注意:对于传统机械硬盘建议开启该特性,对于固态硬盘,建议关闭(0)
参数
动态参数
可以在mysql运行期间修改
修改使用set
set [global|session] system_var_name;
select @@session.read_buffer_size \G;
静态参数
在运行期间不可修改
错误日志文件对Mysql的启动、运行、关闭过程进行了记录
show variables like ‘log_error‘; -- 查询错误日志文件的路径
-- 慢查询时间阈值 大于时间阈值的会记录慢日志
show variables like ‘long_query_time‘;
-- 启动慢查询日志(默认不启动)
show variables like ‘slow_query_log‘;
-- 运行的sql没有使用索引,开启改参数后 也会记录慢日志
show variables like ‘log_queries_not_using_indexes‘;
分析慢查询日志 mysqldumpslow
命令
mysql5.1 开始可以将慢查询日志记录到一张表中 mysql.slow_log
(该表默认使用的引擎时CSV,可以修改为MyISM)
-- 参数log_output指定了慢查询的输出格式, 默认为FILE, 可以将它设置为TABLE,然后慢查询日志进入slow_log表
show variables like ‘log_output‘;
set global log_output = ‘TABLE‘;
-- 修改引擎
alter table slow_log engine=myisam;
记录了所有对Mysql数据库的请求信息,不论这些请求是否正确执行
默认文件名: 主机名.log
日志也可以进表:general_log
记录了对数据库执行更改的所有操作(不包括select和show这类操作)
默认不启动
作用
设置
通过配置参数log-bin[=name]可以启动二进制, 如不指定name,则默认二进制文件名为主机名,后缀名为二进制日志的序列号,所在路径为数据库所在目录
-- 数据库所在目录
show variables like ‘datadir‘;
相关参数
max_binlog_size
单个二进制文件的最大值,超过该值,则产生新的二进制日志文件,后缀名+1 默认大小为1 073 741 824
(1GB)
binlog_cache_size
当使用事务存储引擎(如innoDB)时,所有未提交(uncommitted)的二进制日志会被记录到一个缓存中,等该事务提交时直接将缓冲中的二进制日志写入到二进制日志文件,该缓冲的大小有binlog_cache_size控制 (基于session,每个线程都会分配一个二进制日志缓冲),默认为32kb
可以通过show global status like ‘binlog_cache%‘;查看使用临时文件写二进制的次数
sync_binlog 等于1时,控制同步写入二进制日志
binglog_do_db 哪些表写二进制日志文件
binglog_ignore_db 哪些表不写二进制日志文件
log_slave_update 从库是否写二进制文件 (主-> 从 -> 从 第一个从需要开启log_slave_update)
binlog_format
查看
binlog_format为statement时: 直接使用 mysqlbinlog --start-position=*** test.000004
如果为row时,需要加上参数-vv
Unix系统下连接mysql可以使用Unix域套接字方式,这种方式需要套接字文件(socket)
show variables like ‘socket‘\G;
mysql实例启动时,会将自己的进程ID写入一个文件中---即pid文件,该文件可有参数pid_file控制
默认路径位于数据库目录下,文件名为主机名.pid
show variables like ‘pid_file‘;
因为mysql插件式存储引擎的体系, mysql对于数据的存储是按照表的,所以每个表都有有与之对应的文件。
无论采用何种引擎,都会有一个frm为后缀的文件,该文件记录了表结构定义(如果有视图,也会有对应的frm文件)
frm文件可以直接cat查看
每个存储引擎都有自己独有的文件
表空间文件
默认配置下,会有一个初始大小为10M,名为ibdata1的文件。该文件就是默认的表空间文件(tablespace file),可以通过参数innodb_data_file_path进行设置 innodb_data_file_path=datafile_spec1[;datafile_spec2]
也可以使用多个文件组成一个表空间,同时指定文件的属性
-- 以下有两个表空间文件,如果两个文件位于不同的磁盘上,则可以提升一定的性能 autoextend(自动增长)
innode_data_file_path=ibdata1:20M;ibdata2:20M:autoextend
设置innodb_data_file_path后,对于所有基于Innodb存储引擎的表数据都会记录到改文件内。
如果设置innodb_file_per_table, 可以将每个基于Innodb引擎的表单独产生一个表空间, 文件名为表名.ibd (这些单独的表空间仅存储了该表的数据、索引、插入缓冲等信息,其余信息还放在默认表空间中)
重做日志文件
默认情况下会有两个文件,ib_logfile0和ib_logfile1。称为Innodb存储引擎的日志文件(更准确应该校重做日志文件)。记录了对于innodb存储引擎的事务日志。
每个innodb存储引擎至少有一个重做日志文件组(group), 每个文件组下至少有两个重做日志文件,如默认的ib_logfile0和ib_logfile1.
为了提高可靠性可以设置多个镜像日志组(mirrored log groups),将不同的文件组放在不同的磁盘上
分析Innodb存储引擎的物理存储特征---数据是如何组织和存放的。 (简单来说:表就是关于特定实体的数据集合,这也是关系型数据库的核心)
在InnoDB存储引擎表中,如果在创建表时没有显式的定义主键(primary key), 则InnoDB存储引擎会按照以下方式选择或创建主键:
1. 首先表中是否有非空的唯一索引(Unique not null), 如果有,则该列为主键
2. 不符合时,InnoDB存储引擎会自动创建一个大小为6字节的指针
InnoDB存储引擎的表,所有数据都被逻辑的存放在一个空间中,也就是表空间(tablespace),表空间又由段(segment)、区(extend)、页(page)组成。页在有的文档里边也称块(block)。
表空间可以看做时InnoDB存储引擎逻辑结构的最高层,所有数据都存储在表空间中。默认情况下InnoDB由一个共享表空间ibdata1,即所有数据都放在这个表空间内。如果启用了参数innodb_file_per_table,则每张表内的数据可以单独放在一个表空间内(ibd文件, 该文件内只是存放数据、索引和插入缓冲)
创建的段:数据段、索引段、回滚段等(前边说过InnoDB存储引擎时索引组织的,因此数据即索引,索引即数据, 那么数据段即为B+树页节点, 索引段即为B+树的非索引节点)
不是每个对象都有段,表空间是由分散的页和段组成。
区是由64个连续的页组成,每个页大小为16kb,即每个区大小为1MB。对于大的数据段,InnoDB存储引擎最多每次可以申请4个区,以此来保证顺序性能。
问题:在启用参数innodb_file_per_table后,创建的表默认大小为96kb。 区是64个连续的页,那创建的表大小至少应该时1MB才对?
是因为在每个段开始时,现有32个页大小的碎片页来存放数据,当这些页使用完之后,才是64个连续页的申请。
页是InnoDB磁盘管理的最小单位。默认每个页大小为16kb。从 Innodb1.2.x 版本开始,可以通过参数 innodb_page_size 设置页的大小
InnoDB存储引擎是面向行的,也就是说数据的存放按行进行存放。每个页存放的行记录也是由硬性规定的,最多允许存放16kb / 2 - 200行记录,即7992行。(16*1024/2 - 200)
-- 7992怎么算的
每个记录最少2个字节,每个页预留200字节(预留为规定) 因此:16*1024/2 - 200
-- 每个页至少两行记录 最小记录和最大记录,用来区分边界
Innodb 引擎提供两种行记录格式:compact(默认)、redundant
可以通过show table status like ‘mytest%‘
查看和记录格式
从物理意义上来看,InnoDB表是共享表空间、日志文件组(redo文件组)、表结构定义文件组成。
若将innodb_file_per_table设置为on,则每个独立的产生一个表空间文件,以ibd结尾,数据、索引、表的内部数据字典信息保存在这个独立的表空间文件中。
表结构定义文件以frm结尾,这个是和存储引擎无关的,任何存储引擎的表结构定义文件都一样。
InnoDB存储引擎数据记录是以行的形式存储的(意味着页中保存着表中一行行的数据)
show table status like ‘table_name‘ -- 查看表记录的存储格式
Compact行记录是在mysql5.0版本之后引入的,目标是高效的存储数据(简单来说一个页中存放的行数据越多,性能也就越高)
从上图可以看出compact行记录方式:
变长字段长度列表
Compact行记录格式的首部是一个非NULL变长字段长度列表,并且是按照列的顺序逆序放置的,长度为:
变长字段的长度不能超过2字节, 这是因为mysql数据库中varchar类型的最大长度限制为65535.
NULL标志位
指示了该行数据中是否有NULL值,有则用1表示
该部分所占字节为1字节
记录头信息(record header)
固定占用5字节(40位(bit))
列表*数据
NULL列数据不占该部分任何空间。
除了用户定义的数据列之外还有两个隐藏列,事务id列和回滚指针列,分别占6字节和7字节大小。若InnoDB没有定义主键,还会有一个6字节的rowid列
InnoDB存储引擎可以将一条记录中的某些数据存储在真正的数据页面之外。一般认为BLOB、LOB这类的大对象类型的存储会把数据存放在数据页面之外。但是BLOB可以不将数据放在溢出页面,而且即便是VARCHAR列数据类型,依然有可能被存放为行溢出数据。
Mysql数据库的VARCHAR类型可以存放65535字节,但是实际上只能存放65532字节(还有别的开销)。(如果在建表时没有将SQL_MODE设置为严格模式的话,当创建65535字节的列时,仍然是可以创建成功的, 因为mysql会将varchar(65535)转变为text类型)
需要注意的是:varchar(65532) 默认是IatinL是可以的, 但是当字符类型是GBK或UTF-8时,是不能创建的
上边这个是因为,VARCHAR(N) 中的N指的是字符的长度, 而文档中说VARCHAR类型最大支持的65535,单位是字节。-
注意mysql手册中定义的65535字节长度,说的是所有varchar列的长度总和,如果列的总和超过,也不能创建
[ ] 即便能够存储65532字节, InnoDB引擎的页为16kb(也就是16384字节),怎样存放65535字节呢?
一般情况下,InnoDB引擎的数据都是放在页类型为B-tree node中,但是,当发生行溢出时,数据存放在页类型为Uncompress BLOB页中。(数据页中只存放了前缀(768字节的前缀),之后就是偏移量,指向行溢出页,也就是Uncompress BLOB page)
InnoDB 1.0.x版本开始引入了新的文件格式(file format, 可以理解为新的页格式)。 以前支持的Compact和Redundant格式称为Antelope格式, 新的文件格式称为Barracuda文件格式。
新的文件格式对于存放在BLOB中的数据都采用了完全的行溢出的方式,即在数据页中值存放20字节的指针,实际的数据都存放在Off page中, 而旧版本会在数据页中存放768个前缀字节
Compressed行记录格式的另一个功能:存放在其中的行数据会以zlib的算法进行压缩
通常理解VARCHAR存储变长长度的字符类型, CHAR存储固定长度的字符类型。
Mysql4.1 版本之后CHAR(N)中的N指定的是字符长度,而不是之前版本的字节长度,也就是说,在不同的字符集下,CHAR类型列内部存储的可能不是定长的数据
例如:
create table a (
c CHAR(2)
) engine=innodb charset=gbk;
insert into a select ‘我们‘;
insert into a select ‘ab‘;
-- 字符集是GBK,分别插入了‘我们’和‘ab’, 实际存储的‘我们’占4个字节, ‘ab‘占2个字节
对于多字节编码的CHAR数据类型的存储,InnoDB引擎在内部会视为变长字符类型,也就是说在变长长度列表中会记录CHAR数据类型的长度。
页是InnoDB存储引擎管理数据库的最小磁盘单位。 页类型为B-tree Node的页存放的即是表中行的实际数据。
InnoDB数据页由7部分组成:
其中Filer Header、Page Header、File Trailer大小是固定的,分别为38/56/8字节,这些用来标记该页的一些信息,如Checksum,数据页所在的B+数索引的层数。
User Records、Free Space、PageDIrectory这些部分为实际的行记录粗出空间,大小是动态的
用来记录一些数据页的一些头信息, 38字节(38B)
记录数据页的状态信息,14部分组成, 占56字节
在InnoDB引擎中,每个数据页中有两个虚拟的行记录,用来限定记录的边界。
Infimum记录是比该页中任何记录都小的值
Supremum指比任何可能大的值还要大的值
这两个值在页创建时被建立,并且任何情况下不会被删除。
User Record:实际存储记录的内容
Free Space: 空闲空间,同样也是链表数据结构(在一条数据被删除后,该空间会被加入到空闲空间中)
页目录中存放了记录的相对位置,有时候这些记录指针称为Slots(槽)或者目录槽(Directory Slots)。
与其他数据库系统不同,在InnoDB中并不是每个记录都拥有一个槽,InnoDB存储引擎的槽是一个稀疏目录,即一个槽中可能包含多个记录。当记录被插入或删除时需要对槽进行分裂或平衡的维护操作
作用: 检验页是否已经完整的写入磁盘
关系型数据库系统和文件系统的一个不同点就是,关系型数据库本身能保证存储数据的完整性。
数据完整性有以下三证形式:
实体完整性
保证表中有一个主键
域完整性
保证每列的值满足特定的条件,域完整性可以通过以下几种途径类保证:
- 选择合适的数据类型
- 外键约束
- 编写触发器
- DEFAULT约束
参照完整性
保证两个表之间的关系
对于InnoDB本身来说,提供了以下几种约束:
约束的创建:
1. 表建立时进行定义
2. alter table进行创建
对于Unique key(唯一约束),可以通过命令CREATE UNIQUE INDEX来建立。
当用户创建了一个唯一索引就是创建了一个唯一约束。但是约束和索引概念是有所不同的,约束更是一个逻辑概念,用来保证数据的完整性,而索引是一个数据结构,既有逻辑概念,在数据库中还代表着物理存储的方式。
默认情况下,mysql数据库允许非法的或不正确的数据插入或更新,又或者可以在数据库内部将其转换为一个合法的值, 如:向NOT NULL的字段插入一个NULL,mysql数据库会将其转换成0再进行插入。
如果想要报错,而不是警告的话, 需要设置sql_mode,用来严格审核参数
通过设置sql_mode为STRICT_TRANS_TABLES
触发器作用:在执行INSERT/DELETE/UPDATE命令之前或之后自动调用sql命令或存储过程。
触发器的创建命令是:CREATE TRIGGER,只有具备Super权限的Mysql数据库用户才可以执行:
CREATE
[DEFINER = [user | CURRENT_USER]]
TRIGGER trigger_name BEFORE|ALTER INSERT|UPDATE|DELETE
ON tbl_name FOR EACH ROW trigger_stmt
最多可以为一个表创建6个触发器,即分别是insert、update、delete的before和after各定义一个。
外键用来保证参照完整性。mysql的myisam本身不支持外键,对于外键的定义只是起到了一个注释的作用。
视图(VIew)是一个命名的虚表,它是由一个sql查询来定义,可以当做表使用。
mysql支持的几种分区:
注意: 如果表中存在主键或唯一索引时,分区列必须是主键或唯一索引的一部分。(否则不能创建分区)
分区函数:year() / to_days()/ to_seconds() / unix_timestamp()
create table t(
id int primary key
) engine=innodb
partition by range(id)(
partition p0 values less than(10),
partition p1 values less than(20),
partition p2 values less maxvalue
);
-- maxvalue 理解为正无穷
-- 删除分区
alter table t drop partition p0; -- 会将所有小于10的数据全部删除
create table t(
id int primary key,
b int
) engine=innodb
partition by list(id) (
partition p0 values in (1,3,5,7,8),
partition p1 values in (2,4,6,8,10)
);
create table t (
id int,
b datetime
) engine=innodb
partition by hash(year(b))
partitions 4;
create table t(
a int,
b datetime
) engine=innodb
partition by key(b)
partitions 4;
range、list、hash、key 分区条件:数据必须是整型,如果不是则需要转化为整型。
mysql5.5版本开始支持 COLUMNS 分区,可以直接使用非整型的数据进行分区
支持的数据类型:
-- 对于日期类型 不需要使用 year()或者 to_days()函数了
create table t(
a int,
b datetime
) engine=innodb
partition by range columns(b) (
partition p0 values less than (‘2020-01-01‘),
partition p1 values less than (‘2021-01-01‘)
)
mysql ---- innodb-1- 体系结构、文件、表
原文:https://www.cnblogs.com/nxzblogs/p/14288708.html