mysql 2006测试_狂神说MySQL06:事务和索引
狂神說MySQL系列連載課程,通俗易懂,基于MySQL5.7.19版本,歡迎各位狂粉轉(zhuǎn)發(fā)關(guān)注學(xué)習(xí)。禁止隨意轉(zhuǎn)載,轉(zhuǎn)載記住貼出B站視頻鏈接及公眾號(hào)鏈接!
上課視頻同步文檔
事務(wù)和索引
事務(wù)
什么是事務(wù)
事務(wù)就是將一組SQL語句放在同一批次內(nèi)去執(zhí)行
如果一個(gè)SQL語句出錯(cuò),則該批次內(nèi)的所有SQL都將被取消執(zhí)行
MySQL事務(wù)處理只支持InnoDB和BDB數(shù)據(jù)表類型
事務(wù)的ACID原則 ?百度 ACID
原子性(Atomic)
整個(gè)事務(wù)中的所有操作,要么全部完成,要么全部不完成,不可能停滯在中間某個(gè)環(huán)節(jié)。事務(wù)在執(zhí)行過程中發(fā)生錯(cuò)誤,會(huì)被回滾(ROLLBACK)到事務(wù)開始前的狀態(tài),就像這個(gè)事務(wù)從來沒有執(zhí)行過一樣。
一致性(Consist)
一個(gè)事務(wù)可以封裝狀態(tài)改變(除非它是一個(gè)只讀的)。事務(wù)必須始終保持系統(tǒng)處于一致的狀態(tài),不管在任何給定的時(shí)間并發(fā)事務(wù)有多少。也就是說:如果事務(wù)是并發(fā)多個(gè),系統(tǒng)也必須如同串行事務(wù)一樣操作。其主要特征是保護(hù)性和不變性(Preserving an Invariant),以轉(zhuǎn)賬案例為例,假設(shè)有五個(gè)賬戶,每個(gè)賬戶余額是100元,那么五個(gè)賬戶總額是500元,如果在這個(gè)5個(gè)賬戶之間同時(shí)發(fā)生多個(gè)轉(zhuǎn)賬,無論并發(fā)多少個(gè),比如在A與B賬戶之間轉(zhuǎn)賬5元,在C與D賬戶之間轉(zhuǎn)賬10元,在B與E之間轉(zhuǎn)賬15元,五個(gè)賬戶總額也應(yīng)該還是500元,這就是保護(hù)性和不變性。
隔離性(Isolated)
隔離狀態(tài)執(zhí)行事務(wù),使它們好像是系統(tǒng)在給定時(shí)間內(nèi)執(zhí)行的唯一操作。如果有兩個(gè)事務(wù),運(yùn)行在相同的時(shí)間內(nèi),執(zhí)行相同的功能,事務(wù)的隔離性將確保每一事務(wù)在系統(tǒng)中認(rèn)為只有該事務(wù)在使用系統(tǒng)。這種屬性有時(shí)稱為串行化,為了防止事務(wù)操作間的混淆,必須串行化或序列化請(qǐng)求,使得在同一時(shí)間僅有一個(gè)請(qǐng)求用于同一數(shù)據(jù)。
持久性(Durable)
在事務(wù)完成以后,該事務(wù)對(duì)數(shù)據(jù)庫所作的更改便持久的保存在數(shù)據(jù)庫之中,并不會(huì)被回滾。
基本語法
-- 使用set語句來改變自動(dòng)提交模式
SET autocommit = 0; ? /*關(guān)閉*/
SET autocommit = 1; ? /*開啟*/
-- 注意:
--- 1.MySQL中默認(rèn)是自動(dòng)提交
--- 2.使用事務(wù)時(shí)應(yīng)先關(guān)閉自動(dòng)提交
-- 開始一個(gè)事務(wù),標(biāo)記事務(wù)的起始點(diǎn)
START TRANSACTION
-- 提交一個(gè)事務(wù)給數(shù)據(jù)庫
COMMIT
-- 將事務(wù)回滾,數(shù)據(jù)回到本次事務(wù)的初始狀態(tài)
ROLLBACK
-- 還原MySQL數(shù)據(jù)庫的自動(dòng)提交
SET autocommit =1;
-- 保存點(diǎn)
SAVEPOINT 保存點(diǎn)名稱 -- 設(shè)置一個(gè)事務(wù)保存點(diǎn)
ROLLBACK TO SAVEPOINT 保存點(diǎn)名稱 -- 回滾到保存點(diǎn)
RELEASE SAVEPOINT 保存點(diǎn)名稱 -- 刪除保存點(diǎn)
測(cè)試
/*
課堂測(cè)試題目
A在線買一款價(jià)格為500元商品,網(wǎng)上銀行轉(zhuǎn)賬.
A的銀行卡余額為2000,然后給商家B支付500.
商家B一開始的銀行卡余額為10000
創(chuàng)建數(shù)據(jù)庫shop和創(chuàng)建表account并插入2條數(shù)據(jù)
*/
CREATE DATABASE `shop`CHARACTER SET utf8 COLLATE utf8_general_ci;
USE `shop`;
CREATE TABLE `account` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(32) NOT NULL,
`cash` DECIMAL(9,2) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8
INSERT INTO account (`name`,`cash`)
VALUES('A',2000.00),('B',10000.00)
-- 轉(zhuǎn)賬實(shí)現(xiàn)
SET autocommit = 0; -- 關(guān)閉自動(dòng)提交
START TRANSACTION; ?-- 開始一個(gè)事務(wù),標(biāo)記事務(wù)的起始點(diǎn)
UPDATE account SET cash=cash-500 WHERE `name`='A';
UPDATE account SET cash=cash+500 WHERE `name`='B';
COMMIT; -- 提交事務(wù)
# rollback;
SET autocommit = 1; -- 恢復(fù)自動(dòng)提交
索引
索引的作用
提高查詢速度
確保數(shù)據(jù)的唯一性
可以加速表和表之間的連接 , 實(shí)現(xiàn)表與表之間的參照完整性
使用分組和排序子句進(jìn)行數(shù)據(jù)檢索時(shí) , 可以顯著減少分組和排序的時(shí)間
全文檢索字段進(jìn)行搜索優(yōu)化.
分類
主鍵索引 (Primary Key)
唯一索引 (Unique)
常規(guī)索引 (Index)
全文索引 (FullText)
主鍵索引
主鍵 : 某一個(gè)屬性組能唯一標(biāo)識(shí)一條記錄
特點(diǎn) :
最常見的索引類型
確保數(shù)據(jù)記錄的唯一性
確定特定數(shù)據(jù)記錄在數(shù)據(jù)庫中的位置
唯一索引
作用 : 避免同一個(gè)表中某數(shù)據(jù)列中的值重復(fù)
與主鍵索引的區(qū)別
主鍵索引只能有一個(gè)
唯一索引可能有多個(gè)
CREATE TABLE `Grade`(
`GradeID` INT(11) AUTO_INCREMENT PRIMARYKEY,
`GradeName` VARCHAR(32) NOT NULL UNIQUE
-- 或 UNIQUE KEY `GradeID` (`GradeID`)
)
常規(guī)索引
作用 : 快速定位特定數(shù)據(jù)
注意 :
index 和 key 關(guān)鍵字都可以設(shè)置常規(guī)索引
應(yīng)加在查詢找條件的字段
不宜添加太多常規(guī)索引,影響數(shù)據(jù)的插入,刪除和修改操作
CREATE TABLE `result`(
-- 省略一些代碼
INDEX/KEY `ind` (`studentNo`,`subjectNo`) -- 創(chuàng)建表時(shí)添加
)
-- 創(chuàng)建后添加
ALTER TABLE `result` ADD INDEX `ind`(`studentNo`,`subjectNo`);
全文索引
百度搜索:全文索引
作用 : 快速定位特定數(shù)據(jù)
注意 :
只能用于MyISAM類型的數(shù)據(jù)表
只能用于CHAR , VARCHAR , TEXT數(shù)據(jù)列類型
適合大型數(shù)據(jù)集
/*
#方法一:創(chuàng)建表時(shí)
CREATE TABLE 表名 (
字段名1 數(shù)據(jù)類型 [完整性約束條件…],
字段名2 數(shù)據(jù)類型 [完整性約束條件…],
[UNIQUE | FULLTEXT | SPATIAL ] ? INDEX | KEY
[索引名] (字段名[(長(zhǎng)度)] [ASC |DESC])
);
#方法二:CREATE在已存在的表上創(chuàng)建索引
CREATE [UNIQUE | FULLTEXT | SPATIAL ] INDEX 索引名
ON 表名 (字段名[(長(zhǎng)度)] [ASC |DESC]) ;
#方法三:ALTER TABLE在已存在的表上創(chuàng)建索引
ALTER TABLE 表名 ADD [UNIQUE | FULLTEXT | SPATIAL ] INDEX
索引名 (字段名[(長(zhǎng)度)] [ASC |DESC]) ;
#刪除索引:DROP INDEX 索引名 ON 表名字;
#刪除主鍵索引: ALTER TABLE 表名 DROP PRIMARY KEY;
#顯示索引信息: SHOW INDEX FROM student;
*/
/*增加全文索引*/
ALTER TABLE `school`.`student` ADD FULLTEXT INDEX `studentname` (`StudentName`);
/*EXPLAIN : 分析SQL語句執(zhí)行性能*/
EXPLAIN SELECT * FROM student WHERE studentno='1000';
/*使用全文索引*/
-- 全文搜索通過 MATCH() 函數(shù)完成。
-- 搜索字符串作為 against() 的參數(shù)被給定。搜索以忽略字母大小寫的方式執(zhí)行。對(duì)于表中的每個(gè)記錄行,MATCH() 返回一個(gè)相關(guān)性值。即,在搜索字符串與記錄行在 MATCH() 列表中指定的列的文本之間的相似性尺度。
EXPLAIN SELECT *FROM student WHERE MATCH(studentname) AGAINST('love');
/*
開始之前,先說一下全文索引的版本、存儲(chǔ)引擎、數(shù)據(jù)類型的支持情況
MySQL 5.6 以前的版本,只有 MyISAM 存儲(chǔ)引擎支持全文索引;
MySQL 5.6 及以后的版本,MyISAM 和 InnoDB 存儲(chǔ)引擎均支持全文索引;
只有字段的數(shù)據(jù)類型為 char、varchar、text 及其系列才可以建全文索引。
測(cè)試或使用全文索引時(shí),要先看一下自己的 MySQL 版本、存儲(chǔ)引擎和數(shù)據(jù)類型是否支持全文索引。
*/
拓展:測(cè)試索引
建表app_user:
CREATE TABLE `app_user` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT '' COMMENT '用戶昵稱',
`email` varchar(50) NOT NULL COMMENT '用戶郵箱',
`phone` varchar(20) DEFAULT '' COMMENT '手機(jī)號(hào)',
`gender` tinyint(4) unsigned DEFAULT '0' COMMENT '性別(0:男;1:女)',
`password` varchar(100) NOT NULL COMMENT '密碼',
`age` tinyint(4) DEFAULT '0' COMMENT '年齡',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
`update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='app用戶表'
批量插入數(shù)據(jù):100w
DROP FUNCTION IF EXISTS mock_data;
DELIMITER $$
CREATE FUNCTION mock_data()
RETURNS INT
BEGIN
DECLARE num INT DEFAULT 1000000;
DECLARE i INT DEFAULT 0;
WHILE i < num DO
INSERT INTO app_user(`name`, `email`, `phone`, `gender`, `password`, `age`)
VALUES(CONCAT('用戶', i), '24736743@qq.com', CONCAT('18', FLOOR(RAND()*(999999999-100000000)+100000000)),FLOOR(RAND()*2),UUID(), FLOOR(RAND()*100));
SET i = i + 1;
END WHILE;
RETURN i;
END;
SELECT mock_data();
索引效率測(cè)試
無索引
SELECT * FROM app_user WHERE name = '用戶9999'; -- 查看耗時(shí)
SELECT * FROM app_user WHERE name = '用戶9999';
SELECT * FROM app_user WHERE name = '用戶9999';
mysql> EXPLAIN SELECT * FROM app_user WHERE name = '用戶9999'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: app_user
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 992759
filtered: 10.00
Extra: Using where
1 row in set, 1 warning (0.00 sec)
創(chuàng)建索引
CREATE INDEX idx_app_user_name ON app_user(name);
測(cè)試普通索引
mysql> EXPLAIN SELECT * FROM app_user WHERE name = '用戶9999'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: app_user
partitions: NULL
type: ref
possible_keys: idx_app_user_name
key: idx_app_user_name
key_len: 203
ref: const
rows: 1
filtered: 100.00
Extra: NULL
1 row in set, 1 warning (0.00 sec)
mysql> SELECT * FROM app_user WHERE name = '用戶9999';
1 row in set (0.00 sec)
mysql> SELECT * FROM app_user WHERE name = '用戶9999';
1 row in set (0.00 sec)
mysql> SELECT * FROM app_user WHERE name = '用戶9999';
1 row in set (0.00 sec)
索引準(zhǔn)則
索引不是越多越好
不要對(duì)經(jīng)常變動(dòng)的數(shù)據(jù)加索引
小數(shù)據(jù)量的表建議不要加索引
索引一般應(yīng)加在查找條件的字段
索引的數(shù)據(jù)結(jié)構(gòu)
-- 我們可以在創(chuàng)建上述索引的時(shí)候,為其指定索引類型,分兩類
hash類型的索引:查詢單條快,范圍查詢慢
btree類型的索引:b+樹,層數(shù)越多,數(shù)據(jù)量指數(shù)級(jí)增長(zhǎng)(我們就用它,因?yàn)閕nnodb默認(rèn)支持它)
-- 不同的存儲(chǔ)引擎支持的索引類型也不一樣
InnoDB 支持事務(wù),支持行級(jí)別鎖定,支持 B-tree、Full-text 等索引,不支持 Hash 索引;
MyISAM 不支持事務(wù),支持表級(jí)別鎖定,支持 B-tree、Full-text 等索引,不支持 Hash 索引;
Memory 不支持事務(wù),支持表級(jí)別鎖定,支持 B-tree、Hash 等索引,不支持 Full-text 索引;
NDB 支持事務(wù),支持行級(jí)別鎖定,支持 Hash 索引,不支持 B-tree、Full-text 等索引;
Archive 不支持事務(wù),支持表級(jí)別鎖定,不支持 B-tree、Hash、Full-text 等索引;
視頻同步更新
如果覺得幫助到了您,不妨贊賞支持一下吧!
總結(jié)
以上是生活随笔為你收集整理的mysql 2006测试_狂神说MySQL06:事务和索引的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据库access和mysql_数据库a
- 下一篇: go iris 连接 mysql 异步_