索引與事務
文章目錄
- 索引與事務
- 一、索引
- 1.1 何為索引
- 1.2 索引的特點
- 二、索引的資料結構
- 2.1 B樹
- 2.3 B+樹
- 2.4非聚簇索引
- 2.5聚簇索引
- 三、事務
- 3.1 何為事務
- 3.2 事務的概念
- 3.3 事務的特性
- 四、JDBC
- 4.1 何為JDBC
- 4.2 JDBC作業原理
- 4.3 JDBC的實作
🎈🎆🎇 前言:
本條帖子只介紹原理及概念,不包含具體的底層實作
一、索引
1.1 何為索引
在資料庫中數量及其龐大的時候,怎么快速找到目標尼?此時就會用到索引,一本書想快速找到自己想找的知識點,首先就會先去看目錄,而索引就是相當于書的目錄,方便查詢,
1.2 索引的特點
- 類似于書籍目錄,快速定位,方便查詢
- 索引提高資料庫的性能幫助極大
- 資料庫中的表,資料,索引之間的關系,類似于書架上的圖書、書籍內容和書籍目錄的關系 ,
二、索引的資料結構
說到速度,增刪查改,肯定就能想到資料結構,資料庫本質上也是用資料結構來實作的,那么怎樣的資料結構是合適索引的尼?
- 首先
二叉搜索數,他的底層實作固能提高查找效率,但是當他是單枝樹的時候時間復雜度就是O(N)了 - 其次是
AVL樹,AVL樹是二叉樹搜索數的升級版,它解決了單枝樹的情況,但是也引入了新問題,在進行插入或洗掉操作的是后就會破壞AVL樹的結構規則,規則是abs(左子樹高度-右子樹高度)<=1,破壞了規則就要調整,這樣每次調整就會很頻繁,那么插入或洗掉就變得低效了, - 然后就是
哈希表,哈希表的時間復雜度是O(1),這個速度就快了,但是哈希表存在很大的局限性,哈希查詢是key == value,但在資料庫中有很多的查詢方式(< > != …),哈希表還有個致命缺陷就是哈希沖突, - 再然后就是
紅黑樹,紅黑樹畢竟是二叉樹的基礎,所以查詢效率是由樹的高度決定的,高度也就相當于比較次數,當資料結構龐大的時候,高度也會高比較次數,就會更多,查找效率就會減慢了
那么這上面的資料結構可以說是資料結構中的頂流了,他們都不行,那么MySQL中的索引使用的什么資料結構尼???
其實MySQL中的索參考的是一個N叉搜索樹!!!
啥是N叉搜索樹???
上面說了紅黑樹查詢效率是由樹的高度決定的,N叉搜索樹目的就是來減少高度,高度低了查詢比較次數就減少了,效率就高了,
N叉搜索樹,相當于B+樹,想要了解B+樹,就要先看看B樹,
2.1 B樹

二叉樹和B樹區別
二叉樹:
- 每個節點含一個值
- 只有兩個分支
- 每個節點所能包含的資訊少
B樹:
- 每個節點含多個值
- 有多條分支
- 每個節點里面包含了很多列,每個節點占用的空間大,保證了B數每個節點都要存在硬碟上,像MySQL這種有龐大的資料這一點明顯更適合
可以從它兩區別看出,B樹優化了二叉樹高度問題,減少查詢次數,增加了效率,并且能把資料存在硬碟上不會消失
但是B樹還可以進一步改進,然后就有了B+樹:
2.3 B+樹

B+樹和B樹變化有兩方面
- B+樹非葉子節點的值存在重復,保證葉子節點這一層是完整的資料結構集合(重復帶來的意義)
- 最后葉子節點用過鏈表方式,把所有的葉子節點按照順序連接起來
B+樹的優勢:
1、善于范圍查找,如那兩個邊界值,分別找兩個邊界值的位置,(id<50 and id >30)
2、查詢最侄訓落在葉子節點這一層,查詢速度穩定,快
3、因為葉子是資料的全集,所以把葉子節點存在了硬碟上,非葉子節點存在記憶體中,又進一步降低了讀取硬碟的次數!!!(B+樹的大殺器)
注意事項:
1、索引是查找比較多的情況下才適合用
2、索引占據的空間不小,磁盤小不建議用
3、建立索引需要區分度比較大得時候才適合制作索引
4、在MySQL中使用create index命令,MySQL底層自動幫我們創建B+樹
2.4非聚簇索引
描述MySQL底層是怎樣組織資料的,
非聚簇索引是通過“表”的結構,把所有的資料裝進去

最后通過表的形式,把資料都裝入一個表中
2.5聚簇索引
資料本身就是通過B+樹方式組織的,每個葉子節點存一條完整記錄,

聚簇和非聚簇,最終是聚簇的索引更高效,因為非聚簇還要建一個表再把資料放入表中這個動作拖慢了速度,但是非聚簇有一個優點就是它是通過每一行存盤資料那么它的磁盤碎片就比較少,更省空間,
三、事務
3.1 何為事務
一般在錢的事情上人們都比較敏感,如果別人給你轉了200,那么別人的賬戶就-200,這時候如果服務器斷了,你就沒有收到別人的200塊錢,這種現象會造成一種社會的恐慌是一種嚴重的現象,為了解決這種現象SQL就使用事務來控制,保證要么全部執行成功,要么全部執行失敗,
3.2 事務的概念
事務指邏輯上的一組操作,組成這組操作的各個單元,要么全部成功,要么全部失敗,在不同的環境中,都可以有事務,對應在資料庫中,就是資料庫事務,
3.3 事務的特性
原子性:將一系列操作打包到一起,構成一個整體,這個整體要么全做完,要么全失敗, such as:A賬戶-200,B賬戶+200,中途資料庫崩潰,那么原子性,會把做了中間狀態的操作還回去(術名:回滾),原子性會把中間的操作記錄下來,當資料庫崩潰是,在把上一條操作還回去,從而實作要么全成功,要么全失敗,一致性:執行事務之前,和執行完事務之后,當前表里面的資料都是合理的狀態持久性:事務操作的資料都是在硬碟上操作的,而硬碟是一個持久化儲存的,隔離性:多個事務,并發執行時產生的問題!!!
四、JDBC
4.1 何為JDBC
JDBC是java當中的資料庫的API,也就是說JDBC是通過java代碼操作資料庫的,由于資料庫支持多種編程,也就是說不同資料庫支持不同語言的API,資料庫也分多種資料庫,也分多種API,如果通過代碼操作不同資料庫完成同樣的功能,也就要寫多種語言的代碼,開發成本高,學習成本也高,時間成本也高,所以為了解決上訴問題,就是把各類資料庫的各類API抽象出來封裝到一層,封裝出一套統一的API, 那么JDBC就是java語言標準庫提供的API,
4.2 JDBC作業原理

JDBC優勢:
1、Java語言訪問資料庫操作完全面向抽象介面編程
2、開發資料庫應用不用限定在特定資料庫廠商的API
3、程式的可移植性大大增強
4.3 JDBC的實作
1、增加操作:
public static void testInsert() throws SQLException {
//DataSource標準庫的介面, MYsqlDataSource()是MySQL JDBC的驅動
DataSource dataSource=new MysqlDataSource();
//1.設定IP和埠,通過URL來表示,
//1).setURL屬于MySQLDataSource的方法,用到向下轉型
((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/java101?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("0123456789");
//3.連接資料庫
Connection connection=dataSource.getConnection();
//4.讓用戶輸入id和姓名
Scanner scanner=new Scanner(System.in);
System.out.println("請輸入學號:");
int id=scanner.nextInt();
System.out.println("請輸入姓名");
String name=scanner.next();
//5.構造一個SQL陳述句,給插入做準備
String sql="insert into student values(?,?)";
PreparedStatement statement=connection.prepareStatement(sql);//與資料庫服務器進行連接互動
statement.setInt(1,id);//提供setXXX方法,下標從1開始
statement.setString(2,name);
System.out.println("sql:"+ statement);
//executeUpdate()來變更資料庫增,改,刪操作
int ret=statement.executeUpdate();
System.out.println("ret:"+ ret);
//釋放資源
statement.close();
connection.close();
}


2、洗掉操作,跟增加操作差不懂不在贅述:
public static void testDelete() throws SQLException {
DataSource dataSource=new MysqlDataSource();
((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/java101?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("0123456789");
Connection connection=dataSource.getConnection();
Scanner scanner=new Scanner(System.in);
System.out.println("請輸入洗掉的id");
int id=scanner.nextInt();
//構造sql
String sql="delete from student where id=?";
PreparedStatement statement=connection.prepareStatement(sql);
statement.setInt(1,id);
System.out.println("sql:" + statement);
//執行sql
int ret = statement.executeUpdate();
System.out.println("ret:" + ret);
//釋放資源
statement.close();
connection.close();
}
3、修改操作,和前面增,刪操作一樣
public static void testUpdate() throws SQLException {
DataSource dataSource=new MysqlDataSource();
((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/java101?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("0123456789");
Connection connection=dataSource.getConnection();
Scanner scanner=new Scanner(System.in);
System.out.println("請輸入你要修改的id");
int id=scanner.nextInt();
System.out.println("請輸入你要修改的名字");
String name=scanner.next();
//構造sql
String sql="Update student set id=? where name=?";
PreparedStatement statement=connection.prepareStatement(sql);
statement.setInt(1,id);
statement.setString(2,name);
System.out.println("sql:"+statement);
//執行sql
int ret= statement.executeUpdate();
System.out.println("ret:" + ret);
//釋放資源
statement.close();
connection.close();
}
4.查詢操作,跟前面不太一樣:
public static void testSelect() throws SQLException {
DataSource dataSource=new MysqlDataSource();
((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/java101?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("0123456789");
Connection connection=dataSource.getConnection();
String sql="select * from student";
PreparedStatement statement= connection.prepareStatement(sql);
// 因為select最終呈現的表是一張臨時表,要寫額外的代碼,報這張臨時表獲取到
ResultSet resultSet=statement.executeQuery();
//resultSet是一張表,
while (resultSet.next()) {
//next()表示獲取當前行同時切換下一行類似于i++,有回傳true,沒有回傳false
//resultSet表示當前行,下面get表示每一行中的具體列
int id=resultSet.getInt("id");
String name=resultSet.getString("name");
System.out.println("id:"+id+" name:"+name);
}
//釋放資源
resultSet.close();
statement.close();
connection.close();
}


以上JDBC的實作是固定套路,需要多敲代碼熟悉,自然就記住了,上面的索引和事務大家也要掌握原理和概念,面試官在考察MySQL的時候很有可能問到底層原理,但不必掌握底層代碼的實作,除非你以后是專門開發資料庫的,那么你就要看底層代碼B+樹怎么實作了,
鐵汁們,覺得筆者寫的不錯的可以點個贊喲?🧡💛💚💙💜🤎🖤🤍💟,收藏關注唄,你們支持就是我寫博客最大的動力!!!!

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/374752.html
標籤:java
