重慶分公司,新征程啟航
為企業(yè)提供網(wǎng)站建設(shè)、域名注冊、服務(wù)器等服務(wù)
為企業(yè)提供網(wǎng)站建設(shè)、域名注冊、服務(wù)器等服務(wù)
本文將要詳細介紹MySQL索引與事務(wù)的概念及原理,并初步了解MySQL數(shù)據(jù)庫視圖概念,簡述數(shù)據(jù)庫的存儲過程。
創(chuàng)新互聯(lián)主營湯原網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營網(wǎng)站建設(shè)方案,重慶App定制開發(fā),湯原h(huán)5小程序制作搭建,湯原網(wǎng)站營銷推廣歡迎湯原等地區(qū)企業(yè)咨詢
一般來說,一篇論文,或者說一本書,都有其目錄,而目錄一般是所有章節(jié)的概述,或者說是要點核心,而索引的概念其實也與之類似。
索引,顧名思義,就是一個方便用戶搜索所需資源的引導(dǎo),只不過在數(shù)據(jù)庫中,索引一般被認為是一種特殊的文件,尤其在Linux系統(tǒng)中("一切皆文件")。從專業(yè)術(shù)語上解釋其含義就是“代表記錄的引用指針”。
就是一般的索引,只是為了區(qū)別于其他特殊索引的一個統(tǒng)稱
與普通索引基本類同,區(qū)別在于,唯一性索引的列中的所有值都不相同,即“唯一”。
簡單舉例來說,學(xué)生數(shù)據(jù)表,年齡可以是普通索引,但不可以是唯一性索引,但是詳細住址可以是。
本質(zhì)上也是一種唯一性索引,但必須指定為“primary key”,該索引要求主鍵中的每個值都唯一。上篇文章中,我們提及到了主鍵的概念,其特點也是“非空唯一”。
索引類型為FULLTEXT,全文索引可以在char、vachar或者text類型的列上創(chuàng)建。
可以在單列或多列上創(chuàng)建索引。多列索引一般用于區(qū)分其中一列可能有相同值的行。
索引可以提升數(shù)據(jù)庫的查詢速度,但并非所有的數(shù)據(jù)表都需要創(chuàng)建索引。因為索引本身也是需要占用系統(tǒng)資源的,或許一般情況下這個問題不會很突出,因為服務(wù)器的資源在一定程度上還是能夠正常支持的,但是如果索引文件過大,其大小可能達到操作系統(tǒng)允許的最大文件限制。
并且,如果說索引使用不當(dāng)也會造成數(shù)據(jù)庫的負擔(dān)。因此,數(shù)據(jù)庫創(chuàng)建索引也是有其原則的。
優(yōu)點:快速查詢所需資源
缺點:占用空間以及資源
首先我們需要保證數(shù)據(jù)庫中有表,且表內(nèi)有數(shù)據(jù);
mysql> select * from fruit_info;
+----+-------+---------+
| id | price | newtype |
+----+-------+---------+
| 1 | 2.50 | banana |
| 2 | 5.50 | apple |
| 3 | 6.00 | peach |
+----+-------+---------+
3 rows in set (0.00 sec)
命令格式:create index <索引名> on 數(shù)據(jù)表 (列名);
實例:
mysql> create index id_index on fruit_info(id);
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show index from fruit_info; #查看索引語句也可以將index換成“keys”
+------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| fruit_info | 1 | id_index | 1 | id | A | 3 | NULL | NULL | | BTREE | | |
+------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)
其中Non_unique為1,表示不是唯一性索引;Key_name 對應(yīng)的是索引名稱,這里就是id_index;
命令格式:create unique index <索引名稱> on 數(shù)據(jù)表 (列名);
實例:
mysql> create unique index type_index on fruit_info(newtype);
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show index from fruit_info;
+------------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+------------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| fruit_info | 0 | type_index | 1 | newtype | A | 3 | NULL | NULL | YES | BTREE | | |
| fruit_info | 1 | id_index | 1 | id | A | 3 | NULL | NULL | | BTREE | | |
+------------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
2 rows in set (0.00 sec)
這里的索引名稱為type_index,與之對應(yīng)的Non_unique的值為0,表示其為唯一性索引。并且唯一性索引的值都不一樣。
那么我們考慮一個問題:數(shù)據(jù)庫中的表的字段是否既可以是普通索引,又可以是唯一性索引?
我們來實操驗證一下:
mysql> create unique index id_index_new on fruit_info(id);
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show index from fruit_info;
+------------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+------------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| fruit_info | 0 | id_index_new | 1 | id | A | 3 | NULL | NULL | | BTREE | | |
| fruit_info | 0 | type_index | 1 | newtype | A | 3 | NULL | NULL | YES | BTREE | | |
| fruit_info | 1 | id_index | 1 | id | A | 3 | NULL | NULL | | BTREE | | |
+------------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
3 rows in set (0.00 sec)
事實證明是可以的,但是我們需要知道唯一性索引與普通索引的區(qū)別就在于“唯一性”上。如果創(chuàng)建了唯一性索引,那么在插入數(shù)據(jù)記錄的時候就需要注意字段匹配時的唯一性。
命令格式:(1)創(chuàng)建表的時候創(chuàng)建主鍵:create table 表名 ([ ... ],primary key(列的列表));
(2)修改表結(jié)構(gòu)加入主鍵:alter table 表名 add primary key;
實例:
mysql> create table student (id int not null,sex char(2),age int not null,hobby varchar(20),primary key(id,hobby));
Query OK, 0 rows affected (0.01 sec)
mysql> show index from student;
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| student | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE | | |
| student | 0 | PRIMARY | 2 | hobby | A | 0 | NULL | NULL | | BTREE | | |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
2 rows in set (0.01 sec)
一個表里面只能有一個主鍵,但一個主鍵可以由多個字段組成。
mysql> alter table fruit_info add primary key(id);
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show index from fruit_info;
+------------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+------------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| fruit_info | 0 | PRIMARY | 1 | id | A | 4 | NULL | NULL | | BTREE | | |
| fruit_info | 0 | id_index_new | 1 | id | A | 4 | NULL | NULL | | BTREE | | |
| fruit_info | 0 | type_index | 1 | newtype | A | 4 | NULL | NULL | YES | BTREE | | |
| fruit_info | 1 | id_index | 1 | id | A | 4 | NULL | NULL | | BTREE | | |
+------------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
4 rows in set (0.00 sec)
主鍵索引是設(shè)置主鍵后自動創(chuàng)建的,無需指定名稱,系統(tǒng)自動生成名字“primary”。主鍵索引與唯一性索引區(qū)別就在于唯一性索引可以為null,而主鍵索引為not null,所以可以簡單用公式理解:primary index = not null + unique index;
全文索引可以建立的字段類型在前面已經(jīng)提及了,命令格式如下:
1、create table 表名 (列名 text,F(xiàn)ULLTEXT(列名))engine=MyISAM;
2、alter table 表名 add FULLTEXT(列名);
實例:
查看數(shù)據(jù)庫的存儲引擎類型:(存儲引擎我們下一篇文章會講解)
mysql> show table status from fruit where name='student'\G
*************************** 1. row ***************************
Name: student
Engine: InnoDB
Version: 10
Row_format: Dynamic
Rows: 0
Avg_row_length: 0
Data_length: 16384
Max_data_length: 0
Index_length: 16384
Data_free: 0
Auto_increment: NULL
Create_time: 2020-01-06 19:12:24
Update_time: NULL
Check_time: NULL
Collation: utf8_general_ci
Checksum: NULL
Create_options:
Comment:
1 row in set (0.00 sec)
mysql> alter table student add fulltext(hobby);
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> mysql> show keys from student;
+---------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| student | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE | | |
| student | 0 | PRIMARY | 2 | hobby | A | 0 | NULL | NULL | | BTREE | | |
| student | 1 | hobby | 1 | hobby | NULL | 0 | NULL | NULL | | FULLTEXT | | |
+---------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
3 rows in set (0.00 sec)
在創(chuàng)建索引時指定多列即可
命令格式:create index 索引名 on 表名(字段1,字段2);
實例:
mysql> create index mo_index on student(id,hobby)
-> ;
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show index from student;
+---------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| student | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE | | |
| student | 0 | PRIMARY | 2 | hobby | A | 0 | NULL | NULL | | BTREE | | |
| student | 1 | mo_index | 1 | id | A | 0 | NULL | NULL | | BTREE | | |
| student | 1 | mo_index | 2 | hobby | A | 0 | NULL | NULL | | BTREE | | |
| student | 1 | hobby | 1 | hobby | NULL | 0 | NULL | NULL | | FULLTEXT | | |
+---------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
6 rows in set (0.00 sec)
命令格式:
格式:drop index 索引名 on 表名;
實例:
mysql> drop index mo_index on student;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show index from student;
+---------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| student | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE | | |
| student | 0 | PRIMARY | 2 | hobby | A | 0 | NULL | NULL | | BTREE | | |
| student | 1 | hobby | 1 | hobby | NULL | 0 | NULL | NULL | | FULLTEXT | | |
+---------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
4 rows in set (0.00 sec)
格式:alter table 表名 drop index 索引名;
實例:
mysql> alter table student drop index hobby;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show index from student;
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| student | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE | | |
| student | 0 | PRIMARY | 2 | hobby | A | 0 | NULL | NULL | | BTREE | | |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
2 rows in set (0.00 sec)
格式:alter table 表名 drop primary key;
實例:
mysql> alter table student drop primary key;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show index from student;
Empty set (0.00 sec)
當(dāng)然如果在修改表結(jié)構(gòu)的時候,刪除了包含索引的列,那么對應(yīng)的索引也會被刪除。
將多個命令作為整體執(zhí)行,要么都成功要么都不執(zhí)行,如銀行轉(zhuǎn)賬;
如果執(zhí)行事務(wù)的時候,前面的一部分成功了,而最后的一部分失敗了,那么就會實行“回滾“機制,將執(zhí)行操作回到事務(wù)的起點位置,數(shù)據(jù)沒有發(fā)生結(jié)果性變化。
事務(wù)是不可分割的工作邏輯單元,事務(wù)可以包含多個sql語句,但整個事務(wù)是一個完整的操作,不可分割;(比如轉(zhuǎn)賬,轉(zhuǎn)賬過程中一但出現(xiàn)error,那么就會回滾到起初狀態(tài),二者資產(chǎn)不會有任何變化)
事務(wù)執(zhí)行前和執(zhí)行后數(shù)據(jù)必須處于一致狀態(tài),但是執(zhí)行過程中是動態(tài)變化的;(比如轉(zhuǎn)賬,轉(zhuǎn)賬前和轉(zhuǎn)賬后雙方資產(chǎn)的總和是不變的(不考慮手續(xù)費等其他費用的情況))
并發(fā)事務(wù)是彼此隔離的,事務(wù)之間必須是獨立(比如打電話,甲和乙打電話不會影響丙和丁打電話)
事務(wù)結(jié)果都是永久的并且是不可逆的(比如轉(zhuǎn)賬的結(jié)果,如果發(fā)生糾紛再次處理就是另一個事務(wù)了。)
默認的情況下是自動提交的,就是輸入了sql語句就自動提交執(zhí)行該命令,但一般來說這是不安全的;
在生產(chǎn)環(huán)境中,該模式使用比較多,這是因為手動提交可以通過緩存,內(nèi)存中的數(shù)據(jù)顯示的結(jié)果查看是否出錯,錯了即實行回滾操作(rollback)(一般會設(shè)置回滾點)。
begin:表示開始一個事務(wù),后面接多個sql語句;0
commit:表示提交一個事務(wù),對應(yīng)前面的begin
rollback:表示回滾一個事務(wù),在begin和rollback之間,錯誤的時候可以回滾。
savepoint:表示設(shè)置回滾點配合rollback命令使用。
實例:
首先我們有一個如下的數(shù)據(jù)表:
mysql> desc fruit_info; #表結(jié)構(gòu)
+---------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| id | int(4) | NO | PRI | NULL | |
| price | decimal(3,2) | NO | | NULL | |
| newtype | varchar(6) | YES | UNI | NULL | |
+---------+--------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> select * from fruit_info; #表數(shù)據(jù)
+----+-------+---------+
| id | price | newtype |
+----+-------+---------+
| 1 | 2.50 | banana |
| 2 | 5.50 | apple |
| 3 | 6.00 | peach |
| 4 | 6.00 | orange |
+----+-------+---------+
4 rows in set (0.00 sec)
mysql> begin; #開始一個事務(wù)的標志
Query OK, 0 rows affected (0.00 sec)
mysql> insert into fruit_info values(5,4,'pear'); #插入一個記錄
Query OK, 1 row affected (0.00 sec)
mysql> select * from fruit_info; #此時只是放入緩存中使用rollback可以回到最初狀態(tài);
+----+-------+---------+
| id | price | newtype |
+----+-------+---------+
| 1 | 2.50 | banana |
| 2 | 5.50 | apple |
| 3 | 6.00 | peach |
| 4 | 6.00 | orange |
| 5 | 4.00 | pear |
+----+-------+---------+
5 rows in set (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from fruit_info;
+----+-------+---------+
| id | price | newtype |
+----+-------+---------+
| 1 | 2.50 | banana |
| 2 | 5.50 | apple |
| 3 | 6.00 | peach |
| 4 | 6.00 | orange |
+----+-------+---------+
4 rows in set (0.00 sec)
mysql> insert into fruit_info values(5,4,'pear');
Query OK, 1 row affected (0.00 sec)
mysql> commit; #提交之后無法使用rollback回到最初狀態(tài);
Query OK, 0 rows affected (0.00 sec)
mysql> select * from fruit_info;
+----+-------+---------+
| id | price | newtype |
+----+-------+---------+
| 1 | 2.50 | banana |
| 2 | 5.50 | apple |
| 3 | 6.00 | peach |
| 4 | 6.00 | orange |
| 5 | 4.00 | pear |
+----+-------+---------+
5 rows in set (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from fruit_info;
+----+-------+---------+
| id | price | newtype |
+----+-------+---------+
| 1 | 2.50 | banana |
| 2 | 5.50 | apple |
| 3 | 6.00 | peach |
| 4 | 6.00 | orange |
| 5 | 4.00 | pear |
+----+-------+---------+
5 rows in set (0.01 sec)
設(shè)置斷點——“回滾點”
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into fruit_info values(5,4,'pear');
ERROR 1062 (23000): Duplicate entry '5' for key 'PRIMARY'
mysql> insert into fruit_info values(6,4,'grape');
Query OK, 1 row affected (0.00 sec)
mysql> savepoint s1;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into fruit_info values(7,4,'cherry');
Query OK, 1 row affected (0.00 sec)
mysql> savepoint s2;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from fruit_info;
+----+-------+---------+
| id | price | newtype |
+----+-------+---------+
| 1 | 2.50 | banana |
| 2 | 5.50 | apple |
| 3 | 6.00 | peach |
| 4 | 6.00 | orange |
| 5 | 4.00 | pear |
| 6 | 4.00 | grape |
| 7 | 4.00 | cherry |
+----+-------+---------+
7 rows in set (0.00 sec)
mysql> rollback to savepoint s2;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from fruit_info;
+----+-------+---------+
| id | price | newtype |
+----+-------+---------+
| 1 | 2.50 | banana |
| 2 | 5.50 | apple |
| 3 | 6.00 | peach |
| 4 | 6.00 | orange |
| 5 | 4.00 | pear |
| 6 | 4.00 | grape |
| 7 | 4.00 | cherry |
+----+-------+---------+
7 rows in set (0.00 sec)
mysql> rollback to savepoint s1;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from fruit_info;
+----+-------+---------+
| id | price | newtype |
+----+-------+---------+
| 1 | 2.50 | banana |
| 2 | 5.50 | apple |
| 3 | 6.00 | peach |
| 4 | 6.00 | orange |
| 5 | 4.00 | pear |
| 6 | 4.00 | grape |
+----+-------+---------+
6 rows in set (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from fruit_info;
+----+-------+---------+
| id | price | newtype |
+----+-------+---------+
| 1 | 2.50 | banana |
| 2 | 5.50 | apple |
| 3 | 6.00 | peach |
| 4 | 6.00 | orange |
| 5 | 4.00 | pear |
+----+-------+---------+
5 rows in set (0.00 sec)
mysql> rollback to savepoint s1;
ERROR 1305 (42000): SAVEPOINT s1 does not exist
根據(jù)以上的結(jié)果我們可以得到如下結(jié)論:
使用事務(wù)命令控制事務(wù)是可以實現(xiàn)回滾機制的;
在使用savepoint結(jié)合rollback命令時,回滾的位置是根據(jù)你執(zhí)行的命令的最終位置;
如果直接使用rollback命令是直接回到最初狀態(tài),且無法回到其他回滾節(jié)點。
set autocommit=0:禁止自動提交 ——就相當(dāng)于begin;
set autocommit-=1:開啟自動提交
本文主要是對MySQL數(shù)據(jù)庫中的索引和事務(wù)的概念進行詳細的介紹,這里的概念和原理以及對應(yīng)的使用場景需要我們結(jié)合實例進行詳細理解。索引的分類以及主鍵索引與唯一性索引的區(qū)別,事務(wù)的4大特點和事務(wù)的回滾機制。