MVCC 概念

举报
幼儿园老大* 发表于 2025/01/31 22:07:35 2025/01/31
1.8k+ 0 0
【摘要】 MVCCMVCC 概念MVCC 即多版本并发控制,维持一个数据的多个版本,使得读写操作没有冲突。从而提高数据库并发性能,做到即使有读写冲突时,也能不加锁非阻塞并发读。是乐观锁的一整实现方式,就是每行都有版本号,保存时根据版本号决定是否成功。读类型当前读读取的是记录最新版本,同时会对读取的记录进行加锁保证其他并发事务不能修改 select lock in share mode(共享锁), se...

MVCC

MVCC 概念

MVCC 即多版本并发控制,维持一个数据的多个版本,使得读写操作没有冲突。从而提高数据库并发性能,做到即使有读写冲突时,也能不加锁非阻塞并发读。

是乐观锁的一整实现方式,就是每行都有版本号,保存时根据版本号决定是否成功。

读类型

  • 当前读

    读取的是记录最新版本,同时会对读取的记录进行加锁保证其他并发事务不能修改 select lock in share mode(共享锁), select for update ; update, insert ,delete

  • 快照读

可能读到的是数据之前的历史版本.在很多情况下,避免了加锁操作,降低了开销;

像不加锁的select操作就是快照。但如果隔离级别是最高级串行化,快照读会退化成当前读。

MVCC 实现

在 InnoDB 存储引擎中,每行记录除了我们自定义的字段外,还会隐式记录:

  1. 最近修改:记录创建这条记录/最后一次修改该记录的事务ID
  2. 回滚指针:指向这条记录的上一个版本,存储于 rollback segment 里。
  3. 隐藏主键:如果数据表没有主键,InnoDB 会自动产生一个自增的聚簇索引。
  4. 删除标记:标记该记录是否已被删除。

事务进行快照读操作的时候生产的读视图(Read View),在该事务执行的快照读的那一刻,会生成数据库系统当前的一个快照,记录并维护系统当前活跃事务的ID(当每个事务开启时,都会被分配一个ID, 这个ID是递增的,所以最新的事务,ID值越大)。

InnoDB 会根据读取事务 ID 判断应该都什么时间段的数据。

在RC隔离级别下,是每个快照读都会生成并获取最新的Read View;而在RR隔离级别下,则是同一个事务中的第一个快照读才会创建Read View, 之后的快照读获取的都是同一个Read View。


数据类型

字符串类型

常用的字符串类型有定长字符串 CHAR 和变长字符串 VARCHAR 两种,必须用数字注明可容纳的字符数。

  • CHAR(n) 表示固定容纳 n 个字符,当少于 n 个字符时,会使用空格填充。
  • VARCHAR(n) 表示最多容纳 n 个字符,当少于 n 个字符时不会补空。起始位和结束位需要额外 3 字节。

英文字母单个字符占 1 字节。汉字单个字符 UTF-8 编码占 3 字节,GBK 编码占 2 字节。

对于长字符串数据可以用 TEXT 或 BLOB 类型存储,固定占用 65535 字节。其中 TEXT 保存文本格式,BLOB 保存二进制格式。如果需要存储更短或更长的字符串类型数据,可以使用 TEXT/BLOB 的扩充类型:如 TINYTEXT、MEDIUMTEXT 和 LONGTEXT。

类型名称 大小(字节) 数据库类型 JAVA 类型
CHAR(n) N(0-255) CHAR String
VARCHAR(n) N+3(0-65535) VARCHAR String
TEXT 65535 VARCHAR String
BLOB 65535 BLOB byte[]

CHAR 类型最大只能容纳 255 字节数据,已不推荐使用。目前 VARCHAR 支持容纳最大 65535 字节数据,且长度不固定能有效节省数据库空间,推荐尽量使用 VARCHAR 数据类型取代 TEXT。

TEXT/BLOB 等大数据类型不支持 MySQL 内存临时表,进行排序等操作必须在磁盘中进行。尽量不要使用,一定要用建议单独建表。

整型 & 浮点型

布尔型

布尔型数据用 BIT 表示。

类型名称 大小(字节) 取值 JAVA 类型
BIT 1 0 or 1 Boolean

整型

整形数据一般用 INT/INTEGER 表示,固定占用 4 字节。如果需要存储更短或更长的整型数据,可以使用 INT 的扩充类型:如 TINYINT、SMALLTEXT 和 MEDIUMTEXT 和 BIGINT。

在声明整型数据时也可以注明显示位宽,如 int(n)。在整形数据不足 n 位时会自动补零,几乎没有任何用处。

类型名称 大小(字节) 表示范围 JAVA 类型
TINYINT 1 (-128,127) (0,255) Integer
SMALLINT 2 (-32 768,32 767)(0,65 535) Integer
MEDIUMINT 3 (-8 388 608,8 388 607)(0,16 777 215) Integer
INT/INTEGER 4 (-2 147 483 648,2 147 483 647) (0,4 294 967 295) Integer
BIGINT 8 非常大 BigInteger

浮点型

常用的浮点型数据类型有 FLOAT/DOUBLE ,FLOAT 类型固定占用 4 字节,DOUBLE 类型固定占用 8 字节。但 FLOAT/DOUBLE 只是近似存储,在数据库中我们常用 DECIMAL 类型记录金额,在数据库中实际以字符串形式存储,以确保不会产生任何误差。

  • DECIMAL(M,D) M 表示最大位数,D 表示小数点右侧的位数。如 DECIMAL(5,2) ,小数点前 3 位,小数点后 2 位。
类型名称 大小(字节) 表示范围 JAVA 类型
FLOAT 4 Float
DOUBLE 8 Double
DECIMAL(M,D) M + 2 BigDecimal

日期类型

java.sql 包内有专用 Java 类型匹配,注意数据类型必须是 java.sql.Date,而不是 java.util.Date 

类型 大小(字节) 格式 表示范围 JAVA 类型
YEAR 1 YYYY 1901/2155 Date
DATE 3 YYYY-MM-DD 1000-01-01/9999-12-31 Date
TIME 3 HH:MM:SS -838:59:59'/'838:59:59 Time
TIMESTAMP 4 YYYY-MM-DD HH:MM:SS 1970-01-01 00:00:00/2038-1-19 11:14:07 Timestamp
DATETIME 8 YYYY-MM-DD HH:MM:SS 1000-01-01 00:00:00/9999-12-31 23:59:59 Timestamp

枚举 & 集合

create table tab(  
   gender enum('male','remale','secret')            -- gender 属性为枚举类型
);  

insert into tab values ('remale');  

 select * from tab where gender=2;                  -- 两者等价
  select * from tab where gender= 'remale';Copy to clipboardErrorCopied

记录字符串,但底层数据实际以2个字节的整型(smallint)保存。

在已知的值中进行单选。最大数量为65535.按保存的位置顺序,从1开始逐一递增。

NULL值的索引是NULL。空字符串错误值的索引值是0。

create table tab(  
   gender set('male','remale','secret')            -- gender 属性为集合类型
);  

insert into tab values ('male', 'remale');  Copy to clipboardErrorCopied

记录字符串,但底层数据实际以8个字节的整型(bigint)保存。

在已知的值中进行多选。最多有 64 个成员。

-- 查询 flag 字段包含 a,b 的字段
mysql -> select * from table_name where FIND_IN_SET('a,d', flag);
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。