它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。事务是数据库维护数据一致性的单位,在每个事务结束时,都能保持数据一致性
事物是由一系列操作完成的,具有四个基本性质(ACID)
脏读:是指在一个事务处理过程里读取了另一个未提交的事务中的数据(一个事物A读取了另一个事物B未提交的信息,而事物B由于问题进行了回滚操作,导致了事物A读取了不存在的事物。)
不可重复读:不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了(事物A读取了某条记录,事物B此时对这条记录进行了修改并提交,事物A再次读取信息时导致两次读取的信息不一致。)
幻读:幻读针对的是一批数据整体,如事物A统计了某些信息的数量,而事物B添加了一条相关的记录,事物A再次查询时统计信息是不一致的。
读事物不加锁;写事物加行级共享锁;
不能解决脏读、不可重复读及幻读
读事物加行级共享锁,读取完成后立即释放锁;写事物加行级排它锁,直到事物结束才释放锁;
能解决脏读,不能解决不可重复读及幻读。
读事物加行级共享锁,直到事物完成才释放锁;写事物加行级排它锁,直到事物结束才释放锁;
能解决脏读,可重复度;不能解决幻读
读事物加表级共享锁,直到事物完成才释放锁;写事物加表级排它锁,直到事物结束才释放;
假设不会发生并发冲突,不加锁,只在提交操作时检查是否违反数据完整性。 乐观锁不能解决脏读的问题。
乐观锁就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。
比如 给 表加一个 时间戳的列,保存更新的时间
更新操作之前 先查询出 时间戳 timestamp,
更新是 update … set … time= 当前时间where … AND time = timestamp;
Delete … where … AND time = timestamp;
修改的时候把时间戳改为当前时间。
如果事务A查询了时间戳之后,进行修改,而事务B这时候已经修改了改行,则事务A进行修改的时候会发现时间不一致,而导致不能修改。避免发生错误。
事务A可以不断重试,直到修改成功。这样可以不加锁而保证并发安全。但是对于并发量特别大的话,可能会导致不断地重试,而一直不能完成操作。通过添加版本号也是同样的道理。
与乐观锁相反, 每次去拿东西时都认为别人会修改,所以会加锁。锁有行级锁和表级锁。
InnoDB行锁是通过索引上的索引项来实现的,这一点MySQL与Oracle不同,后者是通过在数据中对相应数据行加锁来实现的。InnoDB这种行锁实现特点意味者:只有通过索引条件检索数据,InnoDB才会使用行级锁,否则,InnoDB将使用表锁!
包含记录的文件按照某个搜索码指定的顺序排序,那么该搜索码对应的索引称为聚集索引,聚集索引的搜索码常常是主码。(文件是排序存储的,一般按照主码进行排序)
搜索码指定的顺序与文件中记录的物理顺序不同的索引称为非聚集索引。
(聚簇索引与非聚簇的优缺点)
https://blog.csdn.net/xlgen157387/article/details/53976153
随数据不断增加,需要选择合适的方案去应对数据规模的增长,以应对逐渐增长的访问压力和数据量。
关于数据库的扩展主要包括:业务拆分、主从复制,数据库分库与分表。
业务起步初始,为了加快应用上线和快速迭代,很多应用都采用集中式的架构。随着业务系统的扩大,系统变得越来越复杂,越来越难以维护,开发效率变得越来越低,并且对资源的消耗也变得越来越大,通过硬件提高系统性能的方式带来的成本也越来越高。
随着业务规模的增大,访问量的增大,我们不得不对业务进行拆分。每一个模块都使用单独的数据库来进行存储,不同的业务访问不同的数据库,将原本对一个数据库的依赖拆分为对4个数据库的依赖,这样的话就变成了4个数据库同时承担压力,系统的吞吐量自然就提高了。
(将原本在一个数据库的内容分到多个数据库中)
MySQL主从复制的原理:数据复制的实际就是Slave从Master获取Binary log文件,然后再本地镜像的执行日志中记录的操作。由于主从复制的过程是异步的,因此Slave和Master之间的数据有可能存在延迟的现象,此时只能保证数据最终的一致性。
https://blog.csdn.net/KingCat666/article/details/78324678
http://www.infoq.com/cn/articles/key-steps-and-likely-problems-of-split-table分库分表讲的比较详细,包括优缺点的分析等