MySQL-adv-02



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));





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章