目錄
一.數據庫索引基礎
索引的概念
- 索引是一種特殊的文件,包含着數據表中所有記錄的引用指針。即數據庫索引相當於一本書的目錄,能夠加快數據庫的查詢速度。數據庫索引就是爲了提高表的搜索效率而對某些字段的值建立起來的目錄
索引的作用
- 建立索引的目的是爲了加快對錶中記錄的查找或排序。爲表設置索引要付出代價:一是增加了數據庫的存儲空間,二是在插入和修改數據時要花費比較多的時間(索引也要隨之變動)。
- 設置了合適的索引之後,數據利用各種快速的定位技術,可以大大加快數據的查詢速度,這是創建索引的最主要的原因
- 當表很大時,或者查詢多個表時,使用索引的可以加快查詢速度
- 索引也可以降低數據庫的I/O成本,並且索引還可以降低數據庫的排序成本
- 通過創建唯一性索引,可以保證數據庫表中每一行數據的唯一性
- 索引可以加快表與表之間的連接
- 在使用分組和排序子句進行數據查詢時,可以顯著減少查詢中分組和排序的時間
索引的分類(MySQL)
- 普通索引,這是最基本的索引類型,而且它沒有唯一性之類的限制
- 唯一性索引,這種索引和前面“普通索引”基本相同,但有一個區別:索引列的所有值只能出現一次,即必須唯一
- 主鍵索引,主鍵是一種唯一性索引,但是它必須指定爲“primary key”。在數據庫中表定義主鍵將自動創建主鍵索引,主鍵索引是唯一索引的特定類型
- 全文索引,索引類型爲 fulltext,全文索引可以在char、varchar 或者 text 類型的列上創建
- 單索引與多列索引,索引可以是單列上創建的索引,可以是在多列上創建的索引。而且多列索引可以區分其中一列可能相同值的行
創建索引的原則依據
- 表的主鍵、外鍵必須有外鍵。主鍵具有唯一性,索引值也是唯一的,查詢時可以快速定位到數據行。外鍵一般關聯的是另一個表的主鍵,所以在多表查詢的時候也可以快速定位
- 數據量超過300行的表應該有索引。數據量較大時,如果沒有索引,需要把表遍歷一遍,嚴重影響數據庫的性能
- 經常與其他數據表進行表連接的數據表,在連接字段上應該建立索引
- 唯一性太差的字段不合適建立索引
- 更新太頻繁的字段不適合創建索引。在表中進行增、刪、改時,索引也應該有相應的操作。字段更新的過於頻繁,對於系統的資源佔用也會更多
- 經常出現在Where語句的字段,應該建立索引
- 索引應該建在選擇性高的字段上。如果很少的字段擁有相同值,即有很多獨特值,則選擇性很高
- 索引應該建立在小字段上,對於大的文本字段甚至超長字段,不要建立索引
二.創建索引與查看索引
安裝MySQL5.6版本,創建
##解壓數據包
tar xzvf mysql-5.6.26.tar.gz -C /opt
##下載必要安裝包
yum install -y ncurses-devel \
autoconf cmake \
zlib-devel make \
gcc \
gcc-c++ \
make
##配置功能模塊
cd /opt/mysql-5.6.26/
cmake \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DEXTRA_CHARSETS=all \
-DSYSCONFIDIR=/etc \
-DMYSQL_DATADIR=/home/mysql/ \
-DMYSQL_UNIX_ADDR=/home/mysql/mysql.sock
##編譯與安裝
make && make install
##覆蓋本機的數據庫,和前面的配置文件的目錄一致
cp support-files/my-default.cnf /etc/my.cnf
##啓動腳本
cp support-files/mysql.server /etc/init.d/mysqld
##給予權限
chmod 755 /etc/init.d/mysqld
chkconfig --add /etc/init.d/mysqld
chkconfig mysqld --level 35 on
##設置環境變量,將啓動腳本放到系統中
echo "PATH=$PATH:/usr/local/mysql/bin" >> /etc/profile
source /etc/profile
echo $PATH
##添加用戶
useradd -s /sbin/nologin mysql
chown -R mysql:mysql /usr/local/mysql/
##初始化數據庫,之前必須創建用戶
/usr/local/mysql/scripts/mysql_install_db \
--user=mysql \
--ldata=/var/lib/mysql \
--basedir=/usr/local/mysql \
--datadir=/home/mysql
##創建socket文件的軟鏈接
ln -s /var/lib/mysql/mysql.sock /home/mysql/mysql.sock
##修改啓動腳本
vim /etc/init.d/mysqld
#指明工作路徑
basedir=/usr/local/mysql
#數據存放位置
datadir=/home/mysql
service mysqld start
##mysql服務3306端口
netstat -anpt | grep 3306
##mysql用戶創建密碼
mysqladmin -u root -p password "abc123"
##進入數據庫
mysql -u root -p
##創建數據庫和數據表,添加數據記錄
mysql> create database company;
Query OK, 1 row affected (0.02 sec)
mysql> use company
Database changed
mysql> create table company.info (崗位名稱 char(10) not null,姓名 char(10) not null,年齡 int(3) not null,員工ID int(4) not null primary key, 學歷 char(10) not null, 工作年限 int(2) not null, 薪資 int(6) not null);
Query OK, 0 rows affected (0.01 sec)
mysql> describe info;
+--------------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+----------+------+-----+---------+-------+
| 崗位名稱 | char(10) | NO | | NULL | |
| 姓名 | char(10) | NO | | NULL | |
| 年齡 | int(3) | NO | | NULL | |
| 員工ID | int(4) | NO | PRI | NULL | |
| 學歷 | char(10) | NO | | NULL | |
| 工作年限 | int(2) | NO | | NULL | |
| 薪資 | int(6) | NO | | NULL | |
+--------------+----------+------+-----+---------+-------+
7 rows in set (0.00 sec)
mysql> insert into info values("網絡工程師","張三",24,1001,"本科",2,4800);
Query OK, 1 row affected (0.01 sec)
mysql> insert into info values("Linux工程師","李四",22,1002,"專科",1,3800);
Query OK, 1 row affected (0.00 sec)
mysql> insert into info values("Java工程師","王五",27,1003,"本科",5,15000);
Query OK, 1 row affected (0.00 sec)
mysql> insert into info values("雲計算工程師","姜文",30,1004,"本科",8,25000);
Query OK, 1 row affected (0.01 sec)
mysql> insert into info values("大數據工程師","藍凌",35,1005,"專科",10,23000);
Query OK, 1 row affected (0.00 sec)
mysql> select * from info;
+--------------------+--------+--------+----------+--------+--------------+--------+
| 崗位名稱 | 姓名 | 年齡 | 員工ID | 學歷 | 工作年限 | 薪資 |
+--------------------+--------+--------+----------+--------+--------------+--------+
| 網絡工程師 | 張三 | 24 | 1001 | 本科 | 2 | 4800 |
| Linux工程師 | 李四 | 22 | 1002 | 專科 | 1 | 3800 |
| Java工程師 | 王五 | 27 | 1003 | 本科 | 5 | 15000 |
| 雲計算工程師 | 姜文 | 30 | 1004 | 本科 | 8 | 25000 |
| 大數據工程師 | 藍凌 | 35 | 1005 | 專科 | 10 | 23000 |
+--------------------+--------+--------+----------+--------+--------------+--------+
5 rows in set (0.00 sec)
mysql>
創建索引、查看索引
- 創建普通索引
- 創建唯一性索引
- 創建主鍵索引,有兩種方式
一種是創建表的同時指定主鍵,主鍵索引會自動創建(primary key)
另一種是,創建表沒有指定主鍵,然後修改表加入主鍵,主鍵索引會自動創建()
- 創建全文索引,在MySQL中使用全文索引,目前只有使用MyISAM類型表的時候有效(MyISAM爲默認表類型)。全文索引可以建立在TEXT、CHAR、VARCHAR類型的字段或者字段組合上
- 創建多列索引
刪除索引
mysql> show index from info;
+-------+------------+------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| info | 0 | PRIMARY | 1 | 員工ID | A | 5 | NULL | NULL | | BTREE | | |
| info | 0 | name_info | 1 | 姓名 | A | 5 | NULL | NULL | | BTREE | | |
| info | 1 | age_info | 1 | 年齡 | A | 5 | NULL | NULL | | BTREE | | |
| info | 1 | name_age_ID_info | 1 | 姓名 | A | 5 | NULL | NULL | | BTREE | | |
| info | 1 | name_age_ID_info | 2 | 年齡 | A | 5 | NULL | NULL | | BTREE | | |
| info | 1 | name_age_ID_info | 3 | 員工ID | A | 5 | NULL | NULL | | BTREE | | |
| info | 1 | work_info | 1 | 崗位名稱 | NULL | 5 | NULL | NULL | | FULLTEXT | | |
+-------+------------+------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
7 rows in set (0.00 sec)
mysql> drop index name_age_ID_info on info; #######刪除特定索引
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show index from info;
+-------+------------+-----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+-----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| info | 0 | PRIMARY | 1 | 員工ID | A | 5 | NULL | NULL | | BTREE | | |
| info | 0 | name_info | 1 | 姓名 | A | 5 | NULL | NULL | | BTREE | | |
| info | 1 | age_info | 1 | 年齡 | A | 5 | NULL | NULL | | BTREE | | |
| info | 1 | work_info | 1 | 崗位名稱 | NULL | 5 | NULL | NULL | | FULLTEXT | | |
+-------+------------+-----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
4 rows in set (0.00 sec)
mysql>
-
豎向顯示索引
mysql> show index from info\G;
*************************** 1. row ***************************
Table: info
Non_unique: 0
Key_name: PRIMARY
Seq_in_index: 1
Column_name: 員工ID
Collation: A
Cardinality: 5
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
三.MySQL事務的概念以及特點
事務的概念
- 事務是一種機制、一個操作序列,包含了一組數據庫操作命令,並且把所有的命令作爲一個整體一起向系統提交或撤銷操作請求,即一組數據庫命令要麼都執行,要麼都不執行
- 事務一個不可分割的工作邏輯單元,在數據庫系統上執行併發操作時,事務是最小的控制單元。
- 事務適用於用戶同時操作數據庫系統,通過事務的整體性以保證數據的一致性。
- 事務是保證了一組操作的平穩性和可預測的技術
事務的ACID特性
- 原子性:事務是一個完整的操作,各個元素是不可分的,即原子的。事務中的所有元素必須作爲一個整體提交或者回滾。如果事務中的任何元素失敗,則整個事務失敗
- 一致性:當事務完成時,數據必須處於一致性;在事務開始之前,數據庫中存儲的數據處於一致性;在事務進行中時,數據可能處於不一致的狀態;當事務成功完成時,數據必須再次回到已知的一致狀態。
- 隔離性:在數據進行修改的所有併發事務是彼此隔離的,這表明事務必須是獨立的,它不應以任何方式依賴或影響其他事務。
- 持久性:指的是不管系統是否發生故障,事務處理的結果都是永久的。一旦事務被提交,事務的效果會被永久地保留在數據庫中
四.MySQL操作事務
MySQL事務
- 默認情況下,MySQL的事務是自動提交的。之前我們用SQL語句操作數據庫時,一條語句執行後,系統會自動執行事務提交。當需要一組語句作爲一個事務提交時,需要手動對事務進行控制。手動控制事務兩種方法,一種使用事務命令控制,另一種是使用set設置事務的處理方式
使用事務命令控制事務
- MySQL中使用命令控制事務的3個命令
- begin:表示事務的開始,後面會有多條數據庫操作語句執行
- commit:表示提交一個事務,對應前面的begin操作,他們之間的數據庫操作語句一起完成
- rollback:表示回滾一個事務,在begin和commit之間,如果某一個數據庫操作語句出現錯誤,執行rollback回滾,數據庫回到begin之前的狀態,也就是操作語句都沒執行
- 具體操作
- 使用begin開始事務,插入兩條語句
- 直接回滾,在查看logs表內數據
- 使用commit提交數據,然後回滾
- 使用savepoint定點回滾
使用set設置控制事務
- MySQL默認是自動提交事務,也可以修改爲不自動提交事務
set autocommit=0 ##禁止自動提交
set autocommit=1 ##開啓自動提交
- 當我們把autocommit的值改爲0時,則需要手動提交,即用commit提交,回滾使用rollback