MySQL-adv-02

来源:互联网 发布:ios小说阅读器 源码 编辑:程序博客网 时间:2024/05/16 14:18


1.事务
•在MySQL中只有使用了Innodb数据库引擎的数据库或表才支持事务
•事务处理可以用来维护数据库的完整性,保证成批的MySQL操作要么完全执行,要么完全不执行
•事务用来管理insert、update、delete语句//事务和select没有了关系


2.事务处理的关键在于将SQL语句组分解为逻辑块,并明确规定数据何时应归回滚,何时提交
•事务(transaction):指一组SQL语句
•回滚(rollback):指撤销指定SQL语句的过程
•提交(commit):指将未存储的SQL语句结果写入到数据库中
•保留点(savepoint):指事务处理中设置的临时占位符,可以对它进行回滚
•事务处理的关键在于将SQL语句组分解为逻辑块,并明确规定数据何时应归回滚,何时提交


3.事务的开始和结束
开始:start transaction;
结束:rollback或者commit;
START TRANSACTION;/*开始事务*/
DELETE FROM t_tableA WHERE id = 1;
ROLLBACK;/*事务回滚*/

START TRANSACTION;
DELETE FROM t_tableA WHERE id = 1;
COMMIT; /*事务提交*/
4.保留点
START TRANSACTION;
 DELETE FROM t_tableA WHERE id = 4;
SAVEPOINT s1;             /*声明一个保留点*/
 DELETE FROM t_tableA WHERE id = 5;
ROLLBACK TO s1;         /*回滚到s1保留点*/


5.transaction 的ACID
1.原子性
2.一致性
3.隔离性
4.持续性
•原子性(Atomic):组成事务的处理语句组成了一个逻辑单元,这是最小的执行单位
•一致性(Consistent):在事务处理执行之前和之后,数据是一致的
•隔离性(Isolated):一个事务的处理对另一个事务没有影响
•持续性(Durable):当事务处理成功后,其结果在数据库中被永久记录下来


6.jdbc实现事务回滚和保留点


public static void main(String[] args){
//1. 编程式事务,这个是1.
//2. 声明式事务
Connection conn = null;
PreparedStatement stat = null;
Savepoint sp = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql:///mydb", "root", "root");
conn.setAutoCommit(false); //关闭自动提交,不加这句话的时候,当stat.executeUpdate();
                         //系统会自动提交
String sql = "INSERT INTO t_post(title,user_id) VALUES('x1','1')";
stat = conn.prepareStatement(sql);
stat.executeUpdate();
sp = conn.setSavepoint();
String sql2 = "INSERT INTO t_post(title,user_id) VALUES('x2','1')";
stat = conn.prepareStatement(sql2);
stat.executeUpdate();
//conn.commit(); //提交
conn.rollback(sp); //回滚到某个保留点
conn.commit();////这个时候若是没有这句话,没有这个提交,他不仅仅是回滚到保留点,
            //会是整个都回滚,加上这句话,就把保留点之前的提交了
} catch (Exception e) {
e.printStackTrace();
try {

//conn.rollback(); //回滚
} catch (SQLException e1) {
e1.printStackTrace();

} finally {
try {
stat.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}


7.public static void main(String[] args){

//1. 编程式事务
//2. 声明式事务
Connection conn = null;
PreparedStatement stat = null;
Savepoint sp = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql:///mydb", "root", "root");
conn.setAutoCommit(false); //关闭自动提交,不加这句话的时候,当stat.executeUpdate();
//系统会自动提交
String sql = "INSERT INTO t_post(title,user_id) VALUES('x1','1')";
stat = conn.prepareStatement(sql);
stat.executeUpdate();
sp = conn.setSavepoint();
String sql2 = "INSERT INTO t_post(title,user_id) VALUES('x2','1')";
stat = conn.prepareStatement(sql2);
stat.executeUpdate();
//conn.commit(); //提交
conn.rollback(sp); //回滚到某个保留点
conn.commit();
} catch (Exception e) {
e.printStackTrace();
try {
conn.rollback(sp); //回滚到某个保留点
conn.commit();
//conn.rollback(); //回滚
} catch (SQLException e1) {
e1.printStackTrace();

} finally {
try {
stat.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}


8.索引,***
索引是优化数据库查询速度的重要途径
•普通索引:最基本的索引类型,没有唯一性之类的限制
01.CREATE INDEX valindex ON t_tableA(username(20))///若是字符串,需要指定它的长度
02.CREATE INDEX products_index ON t_tableA(username(20),password(20))  ////多列索引
//索引不仅可以在单列上加,也可以在多列上加,
//区别当where username=?会用第一个
//当where username=?and password=?时候会用多列索引那个
//如果是多列索引,查询时候会非常依赖第一列。当没有01的时候,只有02
//这时若是查询只有第一列where username=?它会用02这个索引;where username=?and password=?也是会用02
//但是where password=?这个就不会用02,这个就是对第一列比较依赖
create index user_id_index on t_post(user_id)////表示在user_id这个列创建一个索引
用的时候:select * from t_post where user_id=1;
•唯一索引:和普通所以基本相同,但所有的索引列只能出现一次,保持唯一性//
除了主键列外的其他列,你不希望它重复,就可以加一个唯一索引
CREATE UNIQUE INDEX valindex2 ON t_tableB(val(20))///若是字符串,需要指定它的长度,这个是mysql中特有的
////其他的并不用加

•主键索引:主键索引是一种特殊的唯一索引,在建立主键时自动创建,这个会查询比较快
•全文索引:全文索引可以在varchar或text类型上创建。
//mysql中把在varchar或text类型上创建的索引叫全文索引

9.索引的缺点,所以索引不是建的越多越好
01.虽然索引大大提高了查询速度,但会降低更新表的速度,比如对表的insert、update、delete操作,
   因为更新表时,MySQL不仅仅要保存数据,还要保存索引文件。
   eg:一个表查询比较少,就不适合建太多索引。只要对表进行了更新操作,都要去更新索引。
   不适合用索引的情况:如果一个表的更新的操作的大于查询,那么就不要加索引。但是一般都是查询大于更新。

02.建立索引会占用磁盘空间。如果在一个大表上创建了多种索引组合,索引文件会膨胀的很快。
eg:有个软件桌面搜索,在磁盘上进行搜索。这个软件会给你每个文件都加一个索引。但是它很占空间。
iphone就有一个bug就是索引只增不减
10. 不适合用索引的情况:
01.更新很频繁的时候。
如果一个表的更新的操作的大于查询,那么就不要加索引。但是一般都是查询大于更新。
02.每次查询的记录数量占总记录量很大的时候。
在查询的时候,如果一个表总共有100万条记录,每次要查询90万条记录
03.记录比较少,表很小的时候。假如用户就几百个的时候。


11.自动如何拿到主键值
在stat.executeUpdate();之前加上一句。stat = 
conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);里传入的是一个sql语句,
和一个Statement.RETURN_GENERATED_KEYS常量值。然后再stat.executeUpdate();之后,

ResultSet rs = stat.getGeneratedKeys();//返回的肯定是一个结果集,因为可以有多条语句,
                                         //返回的肯定是对应的sql,的自动增长的主键的值。可以用for来取值
rs.next();
System.out.println(rs.getInt(1));



Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql:///mydb", "root", "root");
String sql = "INSERT INTO t_post(title,user_id) VALUES('x1','1')";
stat = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
stat.executeUpdate();
ResultSet rs = stat.getGeneratedKeys();
rs.next();
System.out.println(rs.getInt(1));





0 0
原创粉丝点击