1. 程式人生 > 其它 >MySQL索引、事務與儲存引擎

MySQL索引、事務與儲存引擎

技術標籤:mysql資料庫索引

MySQL索引、事務與儲存引擎

索引的概念

資料庫索引

1、是一個排序的列表,儲存著索引值和這個值所對應的實體地址
2、無須對整個表進行掃描,通過實體地址就可以找到所需資料
3、是表中一列或者若干列值排序的方法
4、需要額外的磁碟空間

索引的作用

1、資料庫利用各種快速定位技術,大大加快查詢速率
2、當表很大或者查多個表時,可極大的提高查詢速度
3、降低資料庫的IO成本,降低資料庫的排序成本
4、通過唯一性索引保證資料表資料的唯一性
5、可以加快表與表之間的連線
6、使用分組和排序時,可大大減少分組和排序時間

索引的優缺點

優點:可以快速的找到所需要的的資源
缺點:佔用空間

建立索引的原則依據

1、表的主鍵、外來鍵必須有索引      ##外來鍵:主表中的外來鍵是另一張表的主鍵
2、記錄數超過300行的表應該有索引
3、經常與其他表進行連線的表,在連線欄位上應該建立索引
4、唯一性太差的欄位不適合建立索引
5、更新太頻繁的欄位不適合建立索引
6、經常出現在where字句中的欄位,特別是大表的欄位,應該建立索引
7、索引應該建在選擇性高的欄位上
8、索引應該建在小欄位上,對於大的文字欄位甚至超長欄位,不要建索引

索引的分類

普通索引、唯一索引、主鍵索引、組合索引、全文索引。

普通索引:最基本的索引型別,沒有唯一性之類的限制

唯一性索引:這種索引和前面的“普通索引”基本相同,但有一個區別:索引列的所有值都只能出現一次,即必須唯一

主鍵索引:主鍵是一種唯一性索引,但它必須指定為“ PRIMARY KEY”(建立表的時候預設指定了)

組合索引:索引可以是單列上建立的索引,也可以是在多列上建立的索引

全文索引:MySQL從32323版開始支援全文索引和全文檢索。在 MySQL中全文索引的索引型別為 FULLTEXT,全文索引可以在ARCHAR或者TEXT型別的列上建立

索引的使用方法

索引的建立

1、直接建立索引

2、修改表結構方式新增索引
3、建立表結構時建立索引

索引的檢視

方法一:show index from 表名
方法二:show keys from 表名

索引的刪除

方法一:drop index 索引名 on 表名
方法二:alter table 表名 drop index 索引名

示例

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| aaa                |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

mysql> use aaa;
Database changed
mysql> show tables;
+---------------+
| Tables_in_aaa |
+---------------+
| stu           |
| test          |
| test2         |
+---------------+
3 rows in set (0.00 sec)

mysql> select * from test;
+----+-----+----------+-------+------+
| id | age | name     | score | addr |
+----+-----+----------+-------+------+
|  1 |  17 | zhangsan |    85 |  101 |
|  2 |  18 | lisi     |    90 |  102 |
|  3 |  17 | wangwu   |    78 |  101 |
+----+-----+----------+-------+------+
3 rows in set (0.00 sec)

### 普通索引
mysql> create index name on test(name); #建立表“test”裡“name”列的普通索引
Query OK, 0 rows affected (0.08 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> show index from test\G; #展示test表的索引
*************************** 1. row ***************************
        Table: test
   Non_unique: 0
     Key_name: PRIMARY
 Seq_in_index: 1
  Column_name: id
....省略內容

mysql> desc test;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(3)       | NO   | PRI | NULL    | auto_increment |
| age   | int(3)       | NO   |     | NULL    |                |
| name  | varchar(100) | NO   | MUL | NULL    |                |  #“MUL”表示有索引
| score | decimal(5,0) | YES  |     | NULL    |                |
| addr  | int(3)       | YES  |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

### 唯一索引
mysql> create unique index addr on test(addr); #建立表“test”裡“addr”的唯一性索引
ERROR 1062 (23000): Duplicate entry '101' for key 'addr' #“101”重複出現,無法建立!
mysql> create unique index score on test(score); #建立表“test”裡“score”的唯一性索引
Query OK, 0 rows affected (0.07 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc test;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(3)       | NO   | PRI | NULL    | auto_increment |
| age   | int(3)       | NO   |     | NULL    |                |
| name  | varchar(100) | NO   | MUL | NULL    |                |
| score | decimal(5,0) | YES  | UNI | NULL    |                | #“UNI”表示有唯一索引
| addr  | int(3)       | YES  |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

mysql> alter table test add index addr(addr); #建立表“test”裡“addr”列的普通索引
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc test; 
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(3)       | NO   | PRI | NULL    | auto_increment |
| age   | int(3)       | NO   |     | NULL    |                |
| name  | varchar(100) | NO   | MUL | NULL    |                |
| score | decimal(5,0) | YES  | UNI | NULL    |                |
| addr  | int(3)       | YES  | MUL | NULL    |                |  #新增的索引
+-------+--------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

### 刪除索引
mysql> drop index name on test; #方法一:刪除“name”的索引
Query OK, 0 rows affected (0.07 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> alter table test drop index addr; #方法二:刪除“addr”的索引
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc test;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(3)       | NO   | PRI | NULL    | auto_increment |
| age   | int(3)       | NO   |     | NULL    |                |
| name  | varchar(100) | NO   |     | NULL    |                |  #“name”索引沒了
| score | decimal(5,0) | YES  | UNI | NULL    |                |
| addr  | int(3)       | YES  |     | NULL    |                |  #“addr”索引沒了
+-------+--------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

### 組合索引
mysql> create table team(id int(3) auto_increment, name char(32) not null, age int(3) not null,index team(id,name,age)); #建立表“team”裡“id,name,age”的組合索引
Query OK, 0 rows affected (0.07 sec)

mysql> show index from team; #查看錶“team”裡的索引們
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| team  |          1 | team     |            1 | id          | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| team  |          1 | team     |            2 | name        | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| team  |          1 | team     |            3 | age         | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
3 rows in set (0.00 sec)

### 全文索引
mysql> create fulltext index name on team(name); #建立表“team”的“name”為全文索引
Query OK, 0 rows affected, 1 warning (0.12 sec)
Records: 0  Duplicates: 0  Warnings: 1

事務的概念

1、通過事務的整體性,保證資料的一致性
2、是一種機制、一個操作序列,包含了一組資料庫操作命令,並且把所有的命令作為一個整體一起向系統提交或撤銷操作請求,即這一組資料庫命令要麼都執行,要麼都不執行。
3、是一個不可分割的邏輯單元,在資料庫系統上執行併發操作時,事務是最小的控制單元。
4、使用於多使用者同時操作的資料庫系統的場景,如銀行、保險公司及證券交易系統等等

事務的ACID特點

原子性(Atomicity)

1、事務是一個完整的操作,事務的各元素是不可分的
2、事務中的所有元素必須作為一個整體提交或回滾
3、如果事務中的任何元素失敗,則整個事務將失敗

一致性(Consistency)

1、當事務完成時,資料必須處於一致狀態
2、在事務開始前,資料庫中儲存的資料處於一致狀態
3、在正在進行的事務中,資料可能處於不一致的狀態
4、當事務成功完成時,資料必須再次回到已知的一致狀態

隔離性(Isolation)

1、對資料進行修改的所有併發事務是彼此隔離的,表明事務必須是獨立的,它不應以任何方式依賴於或影響其他事務
2、修改資料的事務可在另一個使用相同資料的事務開始之前訪問這些資料,或者在另一個使用相同資料的事務結束之後訪問這些資料

永續性(Durability)

1、指不管系統是否發生故障,事務處理的結果都是永久的
2、一旦事務被提交,事務的效果會被永久的保留在資料庫中

事務控制語句

MySQL事務預設是自動提交的,當SQL語句提交時事務便自動提交

事務控制方法

手動對事務進行控制的方法
1、事務處理命令控制事務
begin:開始一個事務
rollback:回滾一個事務
commit:提交一個事務

2、使用set命令進行控制
set autocommit=0:禁止自動提交
set autocommit=1:開啟自動提交(預設開啟)

控制語句

begin或start transaction 
commit
rollback
savepoint indetifier 建立儲存點
release savepoint identifier 刪除一個儲存點
rollback to identifier 回滾到儲存點
set transaction 設定事務的隔離級別

儲存引擎

1、定義:MySQL中的資料用各種不同的技術儲存在檔案中,每一種技術都使用不同的儲存機制、索引技巧、鎖定水平並最終提供不同的功能和能力,這些不同的技術以及配套的功能在MySQL中稱為儲存引擎

2、儲存引擎就是 MySQL將資料儲存在檔案系統中的儲存方式或者儲存格式

3、目前 MySQL常用的兩種儲存引擎
MyISAM
InnoDB

4、MySQL儲存引擎是 MySQL資料庫伺服器中的元件,負責為資料庫執行實際的資料I/O操作

5、使用特殊儲存引擎的主要優點之一在於:
(1)僅需提供特殊應用所需的特性
(2)資料庫中的系統開銷較小
(3)具有更有效和更高的資料庫效能

6、MySQL系統中,儲存引擎處於檔案系統之上,在資料儲存到資料檔案之前會傳輸到儲存引擎,之後按照各個儲存引擎的儲存格式進行儲存

MyISAM

概述:MyISAM是預設儲存引擎(Mysql5.1前)。它基於更老的ISAM程式碼,但有很多有用的擴充套件。(注意MySQL 5.1不支援ISAM)。 每個MyISAM在磁碟上儲存成三個檔案,每一個檔案的名字均以表的名字開始,副檔名指出檔案型別。

特點

1、MylSAM不支援事務,也不支援外來鍵

2、訪問速度快

3、對事務完整性沒有要求

4、MyISAM在磁碟上儲存成三個檔案
(1)儲存檔案:副檔名為.frm
(2)資料檔案:副檔名為.MYD (MYData)
(3)索引檔案:副檔名是.MYI (MYIndex)

5、表級鎖定形式,資料在更新時鎖定整個表

6、資料庫在讀寫過程中相互阻塞(讀寫不能同時進行)

7、資料單獨寫入或讀取,速度過程較快且佔用資源相對少

8、MyISAM支援的儲存格式
靜態表
動態表
壓縮表

MyISAM適用的生產場景舉例

公司業務不需要事務的支援
單方面讀取或寫入資料比較多的業務
MyISAM儲存引擎資料讀寫都比較頻繁場景不適合
使用讀寫併發訪問相對較低的業務
資料修改相對較少的業務
對資料業務一致性要求不是非常高的業務
伺服器硬體資源相對比較差

lnnoDB

概述:InnoDB,是MySQL的資料庫引擎之一,現為MySQL的預設儲存引擎,為MySQL AB釋出binary的標準之一。InnoDB由Innobase Oy公司所開發,2006年五月時由甲骨文公司併購。與傳統的ISAM與MyISAM相比,InnoDB的最大特色就是支援了ACID相容的事務(Transaction)功能,類似於PostgreSQL。

lnnoDB特點

支援4個事務隔離級別
行級鎖定,但是全表掃描仍然會是表級鎖定
讀寫阻塞與事務隔離級別相關
能非常高效的快取索引和資料
表與主鍵以簇的方式儲存
支援分割槽、表空間,類似oracle資料庫
支援外來鍵約束,5.5前不支援全文索引,5.5後支援全文索引
對硬體資源要求還是比較高的場合

InnoDB適用生產場景分析

1、業務需要事務的支援
2、行級鎖定對高併發有很好的適應能力,但需確保查詢是通過索引來完成
3、業務資料更新較為頻繁的場景
·如:論壇,微博等
4、業務資料一致性要求較高
·如:銀行業務
5、硬體裝置記憶體較大,利用Innodb較好的快取能力來提高記憶體利用率,減少磁碟IO的壓力

企業選擇儲存引擎依據

1、需要考慮每個儲存引擎提供的核心功能及應用場景
2、支援的欄位和資料型別
(1)所有引擎都支援通用的資料型別
(2)但不是所有的引擎都支援其它的欄位型別,如二進位制物件
3、鎖定型別:不同的儲存引擎支援不同級別的鎖定
(1)表鎖定
(2)行鎖定
4、索引的支援
(1)建立索引在搜尋和恢復資料庫中的資料時能顯著提高效能
(2)不同的儲存引擎提供不同的製作索引的技術
(3)有些儲存引擎根本不支援索引
5、事務處理的支援
(1)提高在向表中國更新和插入資訊期間的可靠性
(2)可根據企業業務是否要支援事務選擇儲存引擎

儲存引擎的相關操作

查看錶的儲存引擎

mysql> show engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine             | Support | Comment                                                        | Transactions | XA   | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| InnoDB             | DEFAULT | Supports transactions, row-level locking, and foreign keys     | YES          | YES  | YES        |
| MRG_MYISAM         | YES     | Collection of identical MyISAM tables                          | NO           | NO   | NO         |
| MEMORY             | YES     | Hash based, stored in memory, useful for temporary tables      | NO           | NO   | NO         |
| BLACKHOLE          | YES     | /dev/null storage engine (anything you write to it disappears) | NO           | NO   | NO         |
| MyISAM             | YES     | MyISAM storage engine                                          | NO           | NO   | NO         |
| CSV                | YES     | CSV storage engine                                             | NO           | NO   | NO         |
| ARCHIVE            | YES     | Archive storage engine                                         | NO           | NO   | NO         |
| PERFORMANCE_SCHEMA | YES     | Performance Schema                                             | NO           | NO   | NO         |
| FEDERATED          | NO      | Federated MySQL storage engine                                 | NULL         | NULL | NULL       |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
9 rows in set (0.00 sec)

修改儲存引擎

方法一(直接修改)
alter table 表名 engine=引擎;
mysql> alter table team engine=MyISAM;
Query OK, 0 rows affected (0.08 sec)
Records: 0  Duplicates: 0  Warnings: 0

方法二(修改配置檔案)
vim /etc/my.cnf
[mysqld]
……省略部分……
default-storage-engine=InnoDB

方法三(建立表時指定引擎)
create table 表名(欄位)engine=引擎
mysql> create table test7(num int(3)) engine=MEMORY;
Query OK, 0 rows affected (0.06 sec)