已某种组织方式存储的数据集合(通常是一个文件或者是一组文件)
误导:误用导致混淆人们通常用数据库这个术语来代表他们使用的数据库软件这是不正确的,它是引起混淆的根源。确切地说,数据库软件应称为DBMS(数据库管理系统)。数据库是通过DBMS创建和操纵的容器。数据库可以是保存在硬设备上的文件,但也可以不是。在很大程度上说,数据库究竟是文件还是别的什么东西并不重要,因为你并不直接访问数据库:你使用的是DBMS,它替你访问数据库。
第一层:连接处理,身份验证,安全性等
第二层:解析,分析,优化 ,内置函数(日期,时间,数学);存储过程,触发器,视图
第三层:存储引擎负责MySQL中数据的存储和提取。
查询缓存在8.0版本完全弃除
多个查询需要同时修改数据,就会产生并发控制问题。
首先读取操作不会影响数据。但是有人正在读取A数据,同一时间下另一个人试图删除A数据,此时会发生什么呢?
这要分情况,可能会报错,可能数据出现问题。
并发控制经典解决方案利用了共享锁和排他锁 也称读锁和写锁
共享锁(读锁):资源共享,互不阻塞,多个客户端可以同时读取同一个资源。
排他锁(写锁):一个排他锁既会阻塞读锁也会阻塞其他的写锁。只有这样才能保证在特定的时间里,只有一个客户端可以写入,并防止其他客户端进行读取操作。
只要客户端修改某一个部分数据,MySQL会通过锁定防止其他客户端读取同一数据,锁的管理速度够快,不会影响。
实际上每个SQL语句都会被视为一个单独的事务进行处理,即自动提交模式。
读取未提交(RU):在事务中可以查看其他事务没有提交修改的数据。性能也没有好太多,还容易造成脏读。
读取已提交(RC):在事务中可以查看其他事务提交修改后的数据 。这意味着同一事务中多次读取操作的数据会不一致(可重复读)大多数引擎都是采用这种方式(Orcale) 基于修改
不可重复读(RR):保证了同一事务中多次读取相同行数据保持一致 。指的是当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行 基于添加
事务A开始执行,并在某个隔离级别下(比如可重复读)执行了一个SELECT查询,假设查询的是所有年龄大于20岁的人数。
Sql
SELECT COUNT(*) FROM Users WHERE Age > 20;
在事务A还未结束时,事务B提交了一个新的INSERT操作,新增了一个年龄大于20岁的用户记录。
Sql
INSERT INTO Users (Name, Age) VALUES ('NewUser', 25);
事务A接着再次执行同样的SELECT查询。
在没有防止幻读措施的情况下,事务A第二次执行的查询结果可能会多出一条记录(即事务B新插入的记录),即使事务A的隔离级别应该是保证在事务开始后看到的数据集合不发生变化。
序列化读:在读取每一行的数据上加锁很安全
指的两个或两个事务相互持有和请求相同资源,产生循环依赖导致死锁。
出现死锁的情况:可能是数据影响 或者 存储引擎。
一旦发生死锁,不回滚事务(部分或全部) 就无法打破思索。InnoDB存储引擎方式:将持有最少行级排他锁的事务回滚。
假设在事务中混合使用事务表和非事务表(例如,InnoDB和MyISAM表)事务成功不会有任何影响,事务失败可能会导致非事务表回滚失败
隐式锁定:指DBMS执行特定操作时自动加锁。例:InnoDB引擎中,事务更新或删除行时,自动对涉及的行进行排他锁,读取时隔离及不不是读未提交,则可能获取共享锁。
显式锁定:由用户手动执行锁或释放锁操作。
-- 锁表
-- 对 `my_table` 进行写锁定(Exclusive Lock)
LOCK TABLES my_table WRITE;
-- 在这里执行对 `my_table` 的更新或删除等操作
-- 释放所有由当前客户端持有的锁定
UNLOCK TABLES;
-- 锁行(innoDB存储引擎)
START TRANSACTION; -- 事务控制语句
SELECT * FROM my_table WHERE id = 1 FOR UPDATE;
-- 执行基于锁定行的更新或其他操作
UPDATE my_table SET column = value WHERE id = 1;
COMMIT; -- 提交事务后,行锁自动释放
UPDATE;
– 执行基于锁定行的更新或其他操作
UPDATE my_table SET column = value WHERE id = 1;
COMMIT; – 提交事务后,行锁自动释放