mysql 用户列表数据结构_MySQL数据结构-行结构
数据的具体存储是交由具体的存储引擎实现的,所以同样的数据,在不同的存储引擎中的存储方式也是不同的,现在只讨论InnoDB引擎的数据结构。
CPU发出读取数据的指令后,Mysql进程需要把存储在硬盘中的数据读取到内存中,CPU真正处理数据的地方是在内存。如果每次读取或写入都要去操作内存和磁盘的话,那样太慢了。
Mysql的策略是:将真实数据划分为若干个页,内存与磁盘交互的最小单位是页,页的大小一般为16KB,也就是说,一次最少从磁盘中读取16KB的内容到内存中,一次最少把内存中的16KB内容刷新到磁盘中。
1.行结构
平时操作Mysql是以一行一行的数据为单位,表中的行也有他自己的行格式,每张表中所有行共享一种行格式,目前共有四种行格式供我们选择,他们大同小异,我们先介绍Compact:
Dynamic (5.7.0默认)
Compact
Compressed
Redundant (5.5.0废弃)
/**创建时指定行格式**/
CREATE TABLE 表名 (列的信息) ROW_FORMAT=行格式名称
/**修改行格式**/
ALTER TABLE 表名 ROW_FORMAT=行格式名称
/**查看表的行格式**/
show table status like '表名'
Compact行格式包括:
一条记录的额外信息
变长字段长度
NULL值列表
头信息
一条记录的真实数据
列的真实值
隐藏列
变长字段长度列表(不必须)
如果行中有变长类型的字段(比如VARCHAR(M、各种TEXT类型,各种BLOB类型),并且这些字段的数据值不为null;或者这个表的字符集是变长字符集(比如utf8每个字符占用1-3个字节,而ascii固定每个字符固定占用1个字节),存储这些变长字段的时候,要把他们的真实数据的字节长度一并存入变长字段长度列表。变长字段长度列表最多占用2个字节。
每个变长字段的长度都占据一个或两个字节,他们逆序排列,组成了变长字段长度列表。
值得注意的有两点,
当变长数据类型的列数据为null时,不会存入变长字段长度列表
变长字段长度列表不是必须存在的,如果所有字段都是固定长度的,并且字符集也是定长字符集,则不存在变长字段长度列表
这里说一下定长和变长字段的区别,比如char(10)和varchar(10)都存"zz",表编码为ascii,varchar列占用2个字节;而char列占用10个字节,没有使用的8个字节全部用0补齐。
括号内的10代表最多占用的字符数,尝试插入11个字符会报错。
NULL值列表(不必须)
如果字段中有允许为NULL的字段,则将这些字段是否为null的信息存储在NULL值列表中。NULL值列表占用1个字节。
值得注意的是,NULL值列表页不是必须的,如果表中没有允许存储 NULL 的列,则不存在NULL值列表。
记录头信息(必须)
记录头信息固定占用5个字节也就是40位,不同位代表不同信息,主要有:
delete_mask 标记该记录是否被删除
record_type表示当前记录的类型
0表示普通记录,1表示B+树非叶子节点记录,2表示最小记录,3表示最大记录
next_record 表示下一条记录的相对位置
隐藏列(必须)
隐藏列中的信息因为与事务和主键有关,所以很重要,总共占用19个字节,有三列:
row_id (不必须) 替补主键id
trx_id 事务id
roll_pointer 回滚指针
这里需要提一下InnoDB表对主键的生成策略:
优先使用用户自定义主键作为主键,如果用户没有定义主键,则选取一个Unique键作为主键,如果表中连Unique键都没有定义的话,则InnoDB会为表默认添加一个名为row_id的隐藏列作为主键。
真实数据
Mysql存储数据的规定限制:
每行最多65535个字节
每页最少存储两行数据
//TODO 待整理
varchar(M)的最大M
mysql表中的一条记录占用的最大存储空间是有限的,除了BLOB和text类型的字段意外,其他所有的列占用的字节长度加起来不能超过65536个字节,这65535个字节除了这条记录本身的真实数据之外,还包括一些其他数据。
比如我们存储一个VARCHAR(M)类型的字段,总共可能需要占用3部分存储空间:
真实数据占用的字节长度(1-2个字节)
Null值标识(1个字节)
真实数据
所以正常来说每行真实数据最多占用65532个字节。
假设一张表中只有一个字段varchar,这张表的行格式是ascii字符集(ascii字符集每个字符占用一个字节),而一行真实数据最多最多占用65532个字节,所以M最大可以是65532;
如果VARCHAR(M)类型的列使用的不是ascii字符集,那M的最大取值取决于该字符集表示一个字符最多需要的字节数。在列的值允许为NULL的情况下,gbk字符集表示一个字符最多需要2个字节,那在该字符集下,M的最大取值就是32766(也就是:65532/2);utf8字符集表示一个字符最多需要3个字节,那在该字符集下,M的最大取值就是21844,就是说最多能存储21844(65532/3)个字符。
值得注意的是:上述所言都是在表中只有一个字段的情况下说的,要记住一个行中的所有列(不包括隐藏列和记录头信息)占用的字节长度加起来不能超过65535个字节!
行数据溢出
上一节我们知道,一行数据最多可以有65535个字节,而一个页只有16kb,也就是16384个字节,很有可能出现一页装不下一行数据的尴尬情况,这就是行数据溢出。
在Compact和Reduntant行格式中,对于占用存储空间非常大的列,在记录的真实数据处只会存储该列的一部分数据,把剩余的数据分散存储在几个其他的页中,然后记录的真实数据处用20个字节存储指向这些页的地址(当然这20个字节中还包括这些分散在其他页面中的数据的占用的字节数),从而可以找到剩余数据所在的页,如图所示:
从图中可以看出来,对于Compact和Reduntant行格式来说,如果某一列中的数据非常多的话,在本记录的真实数据处只会存储该列的前768个字节的数据和一个指向其他页的地址,然后把剩下的数据存放到其他页中。如下图:
最后需要注意的是,不只是 VARCHAR(M) 类型的列,其他的 TEXT、BLOB 类型的列在存储数据非常多的时候也会发生行溢出。
溢出临界点
每行存储多少数据的时候会发生行溢出呢?
mysql规定每个数据页至少要存储两行数据,每个页除了记录数据以外,还会有132个字节存储页的信息,每行记录额外需要的存储空间是27字节:
2个字节用于存储真实数据的长度
1个字节用于存储列是否是NULL值
5个字节大小的头信息
6个字节的row_id列
6个字节的transaction_id列
7个字节的roll_pointer列
所以计算公式是:
132 + 2×(27 + n) < 16×1024
算出x<8099,也就是说当一行总数据量>=8099字节时,会发生行溢出。
Dynamic行格式
默认行格式Dynamic与Compact很像,只不过在处理行溢出数据时有点儿分歧,它不会在记录的真实数据处存储字段真实数据的前768个字节,而是把所有的字节都存储到其他页面中,只在记录的真实数据处存储其他页面的地址,就像这样:
参考:《MySQL 是怎样运行的:从根儿上理解 MySQL》
mysql 用户列表数据结构_MySQL数据结构-行结构相关推荐
- mysql用户数据导入_MySQL添加用户、删除用户与授权和数据的导入导出
MySql中添加用户,新建数据库,用户授权,删除用户,修改密码(注意每行后边都跟个;表示一个命令语句结束): 1.新建用户 1.1 登录MYSQL: @>mysql -u root -p @&g ...
- mysql 用户管理表_Mysql—用户表详解(mysql.user)
MySQL 数据库 Mysql-用户表详解(mysql.user) MySQL是一个多用户管理的数据库,可以为不同用户分配不同的权限,分为root用户和普通用户,root用户为超级管理员,拥有所有权限 ...
- mysql 用户划表_mysql用户表
mysql5.6中mysql.user表 一些特殊符号: 在myql中% *是通配符, ::1 是IPv6格式的 127.0.0.1 Host列指定了允许用户登录所使用的IP,比如user=root ...
- mysql用户表示例_MySQL添加用户、删除用户与授权与关联实例
1.新建用户 1.1 登录MYSQL: @>mysql -u root -p @>密码 1.2 创建用户: mysql> insert into mysql.user(Host,Us ...
- 给mysql用户授权命令_mysql添加用户并授权的命令(示例)
本节内容: mysql用户授权命令与mysql常用命令. 1,新建(添加)用户. 复制代码 代码示例: //登录MYSQL >mysql -u root -p >密码 //创建用户 mys ...
- mysql用户控制登录_MySql用户权限控制_MySQL
bitsCN.com MySql用户权限控制 本文将介绍MySql创建帐号,删除帐号,设置和介绍各种帐号的权限 创建用户帐号: www.bitsCN.com [sql] CREATE USER use ...
- mysql用户replace权限_mysql查看用户的权限脚本
1.安装mysql支持python包 yum -y install mysql-connector-python 2.查看MySQL 用户权限的Python脚本 vi py_priv.py #!/us ...
- mysql 创建端口号_MySQL命令行 不同端口登录 执行SQL文件 创建用户 赋予权限 修改root密码...
0.安装MySQL服务 1.[不同端口登录] 通过开始菜单-> 程序-> MySQL-> MySQL Command Line Client 通过输入密码Enter password ...
- mysql数据库管理系统模式_MYSQL命令行模式管理MySql的一点心得
MYSQL命令行模式管理MySql的一点心得 MYSQL命令行模式管理MySql的一点心得 MySql数据库是中小型网站后台数据库的首选,因为它对非商业应用是免费的.网站开发者可以搭建一个" ...
- mysql 用户与数据_MySQL经验9-用户和数据安全
mysql心得9--用户和数据安全 1. 添加用户 可以使用CREATE USER语法添加一个或多个用户,并设置相应的密码. 语法格式: CREATE USER user [identified B ...
最新文章
- 学计算机打字一段话,初学电脑基础知识打字
- SuperMap webGIS 简易提示框示例
- python inspect模块
- JetPack——网络库封装
- ajax如何处理服务器返回的三种数据类型
- 运行Deeplab遇到‘Unexpected label’
- [html] 使用canvas制作一个印章
- activity启动流程_以AMS视角看Activity启动过程
- 【Linux】创建逻辑卷管理(LVM)
- 真正的云主机到底是什么样的?转发
- 2016年5月27日更新后MSYS2的shell用法
- 微信昵称特殊符号入库报错解决方案
- idea xml高亮问题
- 长期不使用计算机会损坏吗,电脑长时间存放不用会不会影响硬件寿命
- 如何封装svg矢量图
- 【记录】关于编码格式导致的中文乱码问题
- 为什么你在互联网上搞不到钱?
- C语言学习1——C语言概述
- 苹果手机Java在那_iPhone8描述文件在哪?iPhone描述文件不见了如何解决?
- JAVAWEB之JSTL标签
热门文章
- opencv图像分析与处理(5)- 取样和取样函数的傅立叶变换
- 深度学习笔记(二)——VGG
- Windows10 如何删掉内置的 skype ?
- ssh 端口转发实现外网 80 端口映射到内网 80 端口
- 基于Matlab的标记分水岭分割算法
- VS2010利用MFC的MSCcom控件的方法(WIN8系统)
- C++读取和写入文件(fstream等)
- PSP模块Tensorflow/Pytorch实现小结
- 文献笔记5 review on RS Hydrology
- 解决WebGL加载倾斜摄影模型出现An eror occurred while rendering.Rendering has stopped.问题