MySQL--表

  • 索引组织表
    • 定义:在innodb存储引擎中,表都是根据主键顺序组织存放的,这种存储方式的表称为索引组织表。
    • 在innodb存储引擎表中,每张表都有一个主键
    • 如果在创建表的过程中,没有显示的定义主键,则innodb存储引擎会按照如下方式选择或创建主键:
      • 首先判断表中是否有非空的唯一索引(unique not null),如果有,则该列即为主键;
      • 如果不符合上述条件,innodb存储引擎会自动创建一个6字节大小的指针。
    • 当表中有多个非空唯一索引时,innodb存储引擎将选择建表时定义的第一个定义的非空唯一索引为主键,注意:主键的选择根据的是定义索引的顺序,而不是建表时列的顺序;
  • innodb逻辑存储结构
    • innodb存储引擎的逻辑存储结构可以看出,所有数据都被逻辑地存放在一个空间中,称之为表空间;
    • 表空间由段(segment)、区(extend)、页(page)组成
    • 表空间
      • 当事物发生时,如果数据未提交,共享表空间的大小会增大,但是当事务回滚时,共享表空间并不会缩小,innodb不会在rollback时区收缩表空间,innodb会判断这些undo信息是否还需要,如果不需要,则会将这些空间标记为可用空间,供下次undo使用;
    • 段:
      • 常见的段有数据段、索引段、回滚段等
      • 数据段即为B+Tree的叶子节点,索引段即为B+Tree的非索引节点
      • 段的管理是有引擎自动完成的
    • 区:
      • 区是由连续的页组成的空间,在任何情况下每个区的大小都为1MB,为了保证区中页的连续性,innodb一次从磁盘中申请4~5区,在默认情况下,innodb存储引擎页的大小为16k,即一个区中一共有64个连续的页;
    • 页:
      • 页是innodb磁盘管理的最小单位
      • 常见页的类型有:
        • 数据页(B-Tree node)
        • undo页(undo log page)
        • 系统页(system page)
        • 事物数据页(transaction system page)
        • 插入缓冲位图页(insert buffer page)
        • 插入缓冲空闲列表页(insert buffer free list)
        • 未压缩的二进制大对象页(uncompressed blob page)
        • 压缩的二进制大对象页(compressed blob page)
    • 行:
      • innodb存储引擎是面向列的,也就是说数据是按照行进行存放的
      • 每个页存放的行记录也是有硬性定义的,最多允许存放16k-200行记录,即7992行记录
  • innodb行记录格式
    • compact
      • 存储方式:
        • 变长字段长度列表:null标志位:记录头信息:列1数据:列2数据:.......
        • compact行记录格式的首部是一个非null变长字段长度列表,按照列的顺序逆序放置其长度为
          • 若列的长度小于255字节,用1字节表示;
          • 若大于255字节,用2字节表示,最大不能超过2字节
        • null标志为:
          • 该标志为指明了该行数据是否有null值,有则用1表示,该部分所占用的字节是1字节;
        • 记录头信息:固定占用5字节(40位)。每列含义如下:
          • ()                1            未知
          • ()                1            未知
          • deleted_flag   1            该行是否已经删除
          • min_rec_flag   1            为1,如果该记录是预先定义为最小的记录
          • n_owned        4            该记录拥有的记录数
          • heap_no         13          索引岁中该条记录的排序记录
          • record_type    3            记录类型,000表示普通,001表示B+Tree树节点指针,010表示infimum,011表示                                       supermum,1xx标出保留 
          • next_record     16          页中下一条记录的相对位置
          • total                 40
        • 不管是char类型,还是varchar类型,在compact格式下null值都不占用任何存储空间 
      • 一个页中存放的数据越多,其性能就越高
    • redundant
      • 存储方式:
        • 字段长度偏移列表:记录头信息:列1数据:列2数据:列3数据:.........
        • 行记录首部是一个字段长度偏移列表,同样是按照列的顺序逆序存放的
        • 记录头信息
    • 行溢出数据
      • innodb存储引擎可以将一条记录中的某些数据存储在真正的数据页面之外。
      • 即使是varchar列数据类型,依然有可能被存放为行溢出数据。
    • compressed和dynamic行记录格式
      • 以上的文件格式(compact和redundant)称为antelope文件格式,新的文件格式称为barracuda文件格式,barracuda文件格式拥有两种新的行记录格式,compressed和dynamic;
      • 新的行记录格式对于存放在blob中的数据采用了完全的行溢出的方式,在数据页中只存放20个字节的指针,实际的数据都存放在off page 中。
      • compressed的另一个功能就是,存储在其中的行数据会以zlib算法进行压缩。
    • char的行结构存储
      • 在多字节字符集的情况下,char和varchar的实际行存储基本是没有区别的。
  • innodb数据页结构
    • innodb数据页由以下7部分组成:
      • file header(文件头)-------------38字节
      • page header(页头)-------------56字节
      • infinimum和supermum records
        • 在innodb存储引擎中,每个数据页中有两个虚拟的行记录,用来限定记录的边界;
        • infimum记录是比该页中任何主键值都要小的值,supermum指比任何可能大的值还要大的值;
        • 这两个值在页创建的时候被建立,并且在任何情况下都不会被删除;
        • 在compact和redundant行格式下,两者占用的字节数各不相同
      • user records(用户记录,即行记录)
      • free space
      • page directory(页目录)
        • page directory中存放了记录的相对位置(注意,这里存放的是相对位置,不是偏移量),有些时候这些记录的指针称为slots(槽)或目录槽(dirctory slots);
        • innodb存储引擎的槽是一个稀疏目录,即一个槽中可能包含多个记录;
        • B+Tree索引本身并不能找到具体的一条记录,能够找到的只是该记录所在的页,数据库把页载入到内存中,然后通过page directory在进行二叉查找,只不过二叉查找的时间复杂度很低,同时在内存中的查找很快,因此通常忽略这部分查找所用的时间。
      • file trailer(文件结尾信息)--------8字节
        • 为了检测页是否已经完整的写入磁盘,innodb存储引擎页中设置了file trailer部分;
        • file trailer 只有一个fil_page_space_end_lsn部分,占用8字节,前4字节代表该页的checksum值,最后4字节和fiile header中的fil_page_lsn相同。将这两个值与file header中的fil_page_space_or_chksum和fil_page_lsn值进行比较,看是否一致,以此来保证页的完整性。
  • 约束
    • 数据完整性
      • 一般来说,数据完整性有以下三种形式:
        • 实体完整性保证表中有一个主键。在innodb存储引擎表中,用户可以通过定义primary key或unique key约束来保证实体的完整性。用户还可以编写触发器来保证数据完整性;
        • 域完整性保证数据每列的值满足特定的条件,在innodb存储引擎中,域完整性可以通过以下几种途径保证;
          • 选择合适的数据类型确保一个数据值满足特定条件;
          • 外键(foreign key)约束;
          • 编写触发器;
          • 还可以考虑使用default约束作为强制域完整性的一个方面
        • 参照完整性保证两个表之间的关系,innodb存储引擎支持外键,因此允许用户定义外键以强制参照完整性,也可以通过触发器强制执行
    • 约束类型
      • primary key
      • foreign key
      • unique key
      • default key
      • not null
    • 约束的创建和查找
      • 方式:
        • 表建立时就立即约束定义;
        • 利用alter table命令来进行创建约束
    • 约束和索引的区别
      • 用户创建了一个唯一索引就创建了一个唯一的约束,但是约束和索引的概念还是有所不同的,约束更是一个逻辑概念,用来保证数据的完整性,而索引是一个数据结构,基友逻辑上的约束,在数据库中还代表着物理存储的方式
    • enum和set约束
    • 触发器与约束
    • 外键约束
      • 外键用来保证参照完整性;
      • 一般来说,称被引用的表为父表,引用的表称为子表;
      • 外键定义时的on delete和on update表示在对父表进行delete和update操作时,对子表所做的操作,可定义的子表操作有:
        • cascade
        • set null
        • no action
        • restrict
  • 视图
    • 在mysql中,视图(view)是一个命名的虚表,它由yigesql查询来定义,可以当作表使用。
    • 与持久表相比视图中的数据没有实际的物理存储
    • 视图的作用
    • 物化视图
  • 分区表
    • 分区概述:
      • mysql支持的分区类型为水平分区,并不支持垂直分区
      • mysql数据库的分区是局部分区索引,一个分区中既存放了数据又存放了索引;
      • 全局分区是指:数据存放在各个分区中,但是所有数据的索引放在一个对象中,mysql5.6不支持全局分区
      • 分区类型:
        • range分区:行数据基于属于一个给定连续区间的列值被放入分区
        • list分区:和range分区类似,list分区面向的离散的值
        • hash分区:根据用户自定义的表达式的返回值来进行分区
        • key分区:根据mysql数据库提供的hash函数来进行分区
        • columns分区
      • 注意:不论创建何种类型的分区,如果表中存在主键或唯一索引,分区列必须是唯一索引的一个组成部分;
      • 唯一索引可以是允许null值的,并且分区列只要是唯一索引的一个组成部分,不需要整个唯一索引都是分区列;
      • 如果建表时没有指定主键,唯一索引,可以指定任何一个列为分区列
    • 子分区
      • 子分区是在分区的基础上再进行分区,有时也称这种分区为复合分区
      • mysql允许在range分区和list分区的基础上再进行hash或key分区
      • 注意:
        • 每个子分区的数量必须相同
        • 要在一个分区表的任何分区上使用subpartitioin来明确定义任何子分区,就必须定义所有的子分区
        • 每个subpartition子句必须包括子分区的一个名字
        • 子分区的名字必须是唯一的
      • 子分区可以用于特别大的表,在多个磁盘间分别分配数据和索引。由于innodb使用表空间自动地进行数据和索引的管理,因此会忽略data directory和index directory 语法。
    • 分区中的null值
      • mysql数据库允许对null值做分区,mysql数据库的分区总是视null值小于任何一个非null值,因此对于不同的分区类型,mysql数据库对于null值 的处理方式也是不一样的
      • range分区:mysql会将null值放入最左边的分区,删除分区时也会一并将null值记录删除;
      • list分区:在list分区下使用null值,必须显式地指出哪一个分区中放入null值,否则报错;
      • hash分区和key分区:任何分区函数都会将含有null值的记录返回为0;
    • 在表和分区间交换数据
      • alter table ... exchange partition语法
      • 允许分区或子分区中的数据与另一个非分区的表中的数据进行交换;
      • 如果非分区表中的数据为空,相当于将分区的数据移动到非分区表中
      • 若分区表的数据为空,相当于将外部表的数据导入到分区表中
      • 使用上述语句必须满足如下条件:
        • 要交换的表和分区表有着相同的表结构,但是表不能含有分区
        • 在非分区表中的数据必须在交换的分区定义内
        • 被交换的表中不能含有外键,或者其他的表含有对该表的外键引用
        • 用户除了需要alter、insert、create权限外,还需要drop权限
      • 注意;
        • 使用该语句时,不会触发交换表和被交换表上的触发器
        • auto_increment列将被重置
    • 分区并不总是适用于OLTP应用

猜你喜欢

转载自www.cnblogs.com/ykyk1229/p/9158425.html