数据库学习

数据无价!

最近发生了一起真实的 删库事件。一名运维人员将数据全部删除。

数据无价啊,数据被删除后,市值大降。

(⊙o⊙)…这里是对数据库学习的笔记,其他先不说了。

数据,现在主要存储在关系型数据库管理软件中。常用的数据管理软件有oracle、mysql、DB2、sql server等。

一般,数据库管理软件 需要服务器有高性能的内存,以便提高读写性能。数据库管理软件安装在Linux服务器之后,那么这台服务器就是 数据库服务器了。

对数据库的操作性能,受到很多因素影响:

1. 网络

2. 服务器性能

3. 数据库管理软件类型

4.读取的数据中 存储的数据量大小,对于数据增长太快的表,可以将数据定期归档存储

// SQL

数据库管理软件,安装在Linux操作系统后,我们有了一台数据库服务器。软件一般都是C/S 或者B/S 模式的。操作软件总有一个页面或者入口。现在的Windows操作系统仍然保留的DOS窗口,也是对操作系统执行操作的一个入口,只不过不是UI,需要输入DOS命令才行。操作数据库管理软件也有一些命令,通过这些命令就可以对数据库软件进行管理了。SQL 结构化查询语言,就是我们与数据库管理软件进行交互的一种语言。

在Java中提供了操作数据库的API,不同的数据库软件厂家需要提供Java语言连接数据库并操作数据库的实现,以便在Java语言开发中操作数据库。

当然,也有专门的软件,可以直接执行SQL,方便数据的操作。

根据功能不同,SQL 分为 DDL、DML、DQL、DCL

DDL:Definition 定义,创建数据库、表、视图、索引等

DML:Manipulation ,对数据库表中的数据 insert、update、delete操作

DQL:Query ,对数据库表中的数据 select

DCL:control,权限设置操作

//数据库时一种共享资源

既然数据库软件给我们提供了操作数据库中数据的 操作命令,那我们就可以对数据进行操作了了。

在Java中,有一个关键字叫 synchronize,用来对共享资源访问时的一种加锁机制。

对共享资源并发访问,在计算机的世界中 无处不在。

数据库管理系统中存储的数据,在现在的系统当中,通常都会发生并发访问。

数据库存储的数据资源作为一种共享资源,需要一种类似Java中的加锁机制来控制对数据的访问以防止不必要的问题发生。

因为数据库的特性,出现了一种特殊的功能,叫做事务。

// 事务

数据库的事务 :是指一组包含DML、DQL语句的逻辑单元。可能只有一条SQL语句,也可能包含多条SQL语句。这些语句执行的结果只有两种:1、全部执行成功;2、全部执行失败,即使只有1条执行失败,其他执行过的也需要回滚。

事务与程序的关系:

SQL语言中,每一条sql都是完成了数据库的一次操作,对于某一个功能来说,会对数据库执行多次不同的数据库操作。在Java语言中 每操作一次数据库,都需要 一段Java代码来完成。那就是 一个事务可能包含一条语句、多条语句或者一个程序片段;而程序中有可能包含多个事务。

事务的开始和结束,在数据库软件中也有响应的命令来设置:

1. 有的是自动提交

2. 也可以设置为手动提交 commit/或者回滚rollback

数据库之所以有事务功能,是为了保证数据的一致性,保证数据的完整性。

事务具有4种特性:原子性、一致性、持久性、隔离性;

事务的隔离有 串行、重复读、读已提交、读未提交

// 脏读、不可重复读、幻读

这几个概念,不可重复读还好,就是想读的数据被更改了;脏读、幻读是什么鬼?我只听过脏数据,就是这个数据无用或者损坏了。

脏读

有一种隔离机制会出现脏读,就是 读未提交;意思 T1读取了T2未提交的数据;那么,事务没有提交之前,因为事务的原子性,事务如果没有提交,那么就说明事务中的sql没有执行完,那就有可能发生数据的不完整性,不一致性,这时 的数据 可以看成是脏数据,而这时如果读取了这个数据,就是一种脏读

原来,脏读是 读取的 事务没有提交的SQL操作;只要事务没有提交,但是已经更新的数据可以被读取到,而这时的数据时一种脏数据,脏读由此产生。也可能读取的未提交的数据被rollback了。

// 不可重复读。读取最新数据

既然读未提交的隔离会出现脏读,那我读已提交就能解决脏读问题了吧。的确如此,读已提交的隔离可以避免脏读,包装读取的都是事务已提交的数据。但是这个时候会出现,我读取的数据在时刻变化,现在读的是一种值,过一会我读的又是另一种值了,当然,读已提交可以保证我读取的数据是最新的,如果对数据的实效性要求比较高的话,那么这种隔离级别可以满足。但是有场景就不使用了,比如读取某个时间点的数据。这就出现了一种不可重复读的情况。有时候需要可重复读。

// 可重复读

既然有的场景需要可重复读,有一种隔离级别是 可重复的,这种情况会读取事务开启时 数据的值,不会被其他事务提交影响。

//幻读

(⊙o⊙)…,之前那个脏读是因为事务没有提交,现在的幻读又是什么鬼?

脏读是读已提交的结果;为了保证不脏读 可以用读已提交,但是又会出现不可重复读;为了解决可重复读可以用可重复的隔离级别,这种隔离级别读取的数据,有可能是过时的,因此这种隔离级别读取的数据 可以称为幻读吧。

MySQL高效存储

现代,电子设备很普及,笔记本、ipad、手机等等。这些硬件设备普及,伴随而来的是 软件也流行起来。硬件与软件相辅相成。不论是社交软件,还是购物类软件,都需要一种能力,就是存储数据,比如:用户信息,软件使用之前 都需要注册,后续 需要使用 用户名密码等完成登录,

那么 问题来了,如何 保存这些 信息?

一般 持久存储 数据 都是 使用 磁盘。

那么简单了,像Java语言 也可以 向磁盘中读写数据。我们是否可以 自己写一个 存储数据的服务呢?自己写的服务 能保证 数据 完整不丢失又高效吗?

MySQL数据库 软件系统,给我们提供了 这种 能力。MySQL 就是 基于磁盘存储的

那么 MYSQL 是如何做到的呢?

众所周知,对磁盘进行读写,就是磁盘IO,提到IO操作,第一反应就是 慢。可以使用 内存 来解决慢的问题,但是 内存 中的数据,在断电之后 就丢失了,最终数据还是需要存储到磁盘中。

mysql 把内存分了几个部分:

关于磁盘的几个概念:

1. 扇区: 磁盘的 最小存储单位,512字节

2. 页:16k = 32个扇区

1. 页缓冲,所有的数据操作,读、写、更新 都在 内存中进行,这样就提高了速度

2. 重做日志缓冲、重做日志文件

在对内存中的页缓冲的数据 进行操作之前,先生成重做日志,等事务提交时,确保重做日志缓冲写入重做日志文件成功,事务才算提交成功。利用这种方式,来保证的 数据完整性、保证即使 内存中的数据 还没来得及写入磁盘,也可以从重做日志文件中 恢复数据。

重做日志缓冲、重做日志文件 以 512字节 为单位 进行存储,符合磁盘扇区的最小单位。      

/sys/block/sda/queue 可以查看磁盘的块大小

/proc/sys/vm

重做日志的设计都是循环使用

格式:

重做日志类型:插入、删除、更新

表空间:哪张表

页偏移量:哪个页

offset: 记录的位移

记录的具体内容


3. 两次写

页大小16K,刷新到磁盘 不是原子性的,可能只写入 部分数据,此时 当前页 是损坏的,重做日志无法进行恢复,因为重做日志必须是完整的页数据 才能进行重做。这就是 部分写问题。为此 实现了 dubble write。

doublewrite buffer 2MB

128连续页 共享表空间,2MB

1次顺序写入1MB

为什么是2M,每次写1M?

1024KB/16KB=64个页=1个簇大小

所以一共可以存储 128个脏页

4.插入缓冲

辅助索引

非唯一索引

B+树 共享表空间

ibdata1

5. checkpoint 

刷新脏页到磁盘?

什么时间刷?从哪个脏页开始刷?刷多少脏页?

这些问题,都是 checkpoint 来解决的。

缓冲池、重做日志的限制

LSN(Log Sequence Number)8字节数字

页、重做日志、checkpoint 都有LSN

SHOW ENGINE INNODB STATUS

Log sequence number 3031219119  重做日志缓冲中最新的 LSN
Log flushed up to   3031219119  重做日志文件中最新的LSN
Pages flushed up to 3031219119 脏页刷盘成功的最小 LSN
Last checkpoint at  3031219110 checkpoint 的LSN

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值