用法:truncate 表名;delete from 表名 where...;drop table 表名;
区别:
truncate、drop是不可以rollback的,但是delete是可以rollback的;原因是:delete删除是一行一行的删除,会触发触发器,删除可以返回行数,每删除一行会进行一次日志记录,所以可回滚;而truncate删除是删除表的所有数据,通过释放存储表数据所用的数据页来删除数据,并且只在事务日志中记录页的释放,所以不能回滚,可以重置自增字段的计数器;Drop语句将删除表的结构、被依赖的约束(constrain)、触发器 (trigger)、索引(index);依赖于该表的存储过程/函数将保留,但是变为invalid状态。
注意:drop、truncate不能删除有外键约束的表。
首先需要解释一下几个跟隔离性相关的概念定义:
(1)脏读:指事务读到脏数据,所谓脏数据,指的是不正确的数据,例如事务执行过程中修改了某记录,然后回滚,如果其他事务读到了该记录的中间修改值,则为脏读。
(2)不可重复读:事务在执行过程中,多次对同一个已经存在的记录进行读取,各次读取的值不同。读提交隔离级别存在不可重复读的问题,事务1、2并发执行,事务2首先读取记录1,然后事务1修改记录1并提交,事务2继续读取记录1,则事务2两次读取到的值不同。
(3)幻读:幻读是指使用某个条件读取一批记录时,可能读到的记录数不同。幻读与脏读、不可重复读的区别在于,脏读、不可重复读都是针对某个确定的已经存在的记录出现的值不要求(读到脏数据或多次读的值不同),而幻读则是多次使用同一个条件查询一批记录,多次读到的记录数不同,也就是说,脏读、不可重复读是由于多个事务并行执行update引起的,而幻读则是由于多个事务并行执行insert引起的(并发delete引起的问题看起来算哪个都行……)。
(1)Read Uncommited:读未提交,其含义为多个并发事务,任何一个事务可以读到其他事务尚未提交的修改:
存在脏读、不可重复读、幻读可能性。
(2)Read Commited:读已提交,含义为多个并发事务,任何一个事务只可以读到其他事务已经提交的修改:
解决脏读,存在不可重复读、幻读可能性。
(3)Repeatable Read:可重复读,含义为多个事务并发执行时,任何一个事务反复读取已存在的记录,每次读到的值都是相同的
解决脏读、不可重复读,存在幻读可能性。
(4)Serializable:串行化,含义为所有事务串行执行,因此不存在事务并发执行的情况。
解决脏读、不可重复读、幻读。
上述四个隔离级别中,读未提交隔离性最差,且相对于读已提交,性能并没有多少提升,几乎不会使用;串行化隔离性最好,可是性能太差,也几乎不会使用。一般数据库的默认隔离级别要么是读已提交,要么是可重复读(例如MySQL的InnoDB引擎),要么是读已提交(例如Oracle )。
如果使用行级读锁、写锁来实现读已提交或可重复读,应当是以下的步骤:
1、事务1会修改行1,则会在行1加上写锁,开始事务;
2、事务2为纯读取操作,需要读取行1,试图在行1上加上读锁,由于事务1已加写锁,因此事务2等待直到事务1完成。
3、如果事务2先开始,则事务1也需要等到事务2完成并释放读锁后才可以开始执行。
也即使说,对某行的写操作会阻塞所有对该行的读取操作,对某行的读操作会阻塞所有对该行的写操作,在系统存在读、写并发时,不论系统IO能力有多高,会受限于锁而导致性能低下。
MVCC用于解决这个问题来提高系统性能,MVCC并没有统一的标准,各个数据库实现均采用不同方式来实现MVCC,InnoDB的实现方式如下:
准备工作:
(1)对每行记录增加行标志和删除标志两个字段;
(2)维护一个全局的系统版本号,每开始一个事务(注意select也是事务,读事务),将该系统版本号加1并作为事务的版本号
插入记录的行标志设置为本事务版本号,删除标志为空;
删除记录的删除标志设置为本事务版本号;
修改的处理过程:将原记录的删除版本号修改为本事务版本号;新插入一条记录,包含原记录数据及本次修改,行记录标志设置为本事务版本号,删除标志为空;
读取的处理过程:
仅读取同时满足以下条件的记录行:
(1)行标志小于或等于本事务版本号(等于用于保证能够读取到本事务内提交的增加);
(2)删除标志为空或者大于本事务版本号(不包括等于以保证不会读取到本事务删除的记录);
相当于在读事务开始的时刻点,建立了一个系统的快照,该事务读取的所有数据,均是从快照中读取的,因此满足可重复读的条件,并且可解决幻读的问题,并且也不会读到产生“同样查询条件,事务中第一次读到的记录数大于第二次读到的记录数的问题“(由并发删除引起)
从上可知,使用MVCC后,大部分读都不再需要加读锁,因此读不再阻塞写,写也不再阻塞读。读操作只再受限于系统IO能力。
InnoDB提供提交、回滚、崩溃恢复能力的事务安全(ASID)能力,实现并发控制。
MyISAM提供较高的插入和查询记录的效率,主要用于插入和查询。
memory用于临时存放数据,数据量不大并且不需要较高数据安全性。
archive:如果只有插入和查询可以用,支持高并发的插入操作,但本身不是事务安全。
MyISAM更快,因为MyISAM内部维护了一个计数器,可以直接调取。
innodb、myisam、memory、archive
查询语句:select* from 表名;
插入数据:insert into 表名 (clus...) values(values...);
更新语句:update 表名 set clu=value where 条件;
删除语句:delete from 表名 where..;truncate 表名;drop table 表名;
存储过程:存储过程体中可以使用自定义函数(UDF)中使用的复合结构/流程控制/SQL语句/自定义变量等等内容
CREATE procedure sp_add(a int, b int,out c int)
begin
DELETE FROM son WHERE id = a;
end
函数定义:
CREATE FUNCTION 函数名称(参数列表)
RETURNS 返回值类型
BEGIN
DELETE FROM son WHERE id = uid;
RETURN (SELECT COUNT(id) FROM son);
END
存储过程说白了就是把经常使用的SQL语句或业务逻辑封装起来,预编译保存在数据库中,当需要的时候从数据库中直接调用,省去了编译的过程. 提高了运行速度;同时降低网络数据传输量(你觉得传一堆SQL代码快,还是传一个存储过程名字和几个参数快???),在程序端可以直接调用存储过程,而函数不能独立运行。
内连接是根据某个条件连接两个表共有的数据所有字段;
左连接是根据某个条件以及左边的表连接数据,右边的表没数据的话则填null;
右连接是根据某个条件以及右边的表连接数据,左边的表没数据的话则填null;
例如,有两个表学生表student和成绩表grade,如图
内连接也就是等值连接:SELECT * FROM student , grade WHERE student.`id`=grade.`studentId`;
左连接:SELECT * FROM student LEFT JOIN grade ON student.`id`=grade.`studentId`;
右连接:SELECT * FROM student RIGHT JOIN grade ON student.`id`=grade.`studentId`;