一.mariadb的安裝與配置
(1)mariadb的安裝
1.虛擬機(jī)上的base源yum安裝
yum install mariadb-server
2.在www.mariadb.org綠色安裝gz格式的包,然后解壓即可
現(xiàn)在常用5版本的mariadb
(2)mariadb的相關(guān)配置
- 首先通過(guò)命令my_print_defaults --verbose來(lái)查看對(duì)應(yīng)加載時(shí)讀取文件配置的順序
-
在開(kāi)啟mariadb服務(wù)之前先對(duì)其配置文件進(jìn)行簡(jiǎn)單的配置與定義
vim /etc/my.cnf.d/server.cnf
在[server]下定義
skip_name_reslove = ON——跳過(guò)域名解釋,節(jié)省時(shí)間
innodb_file_per_table = ON——每個(gè)表使用單獨(dú)的表空間文件
max_connection = 20000——最大并發(fā)連接數(shù)的設(shè)置
搜狗截圖20171109090500.png
創(chuàng)建的數(shù)據(jù)庫(kù)的數(shù)據(jù)一般多會(huì)放在/var/lib/mysql下
例如在數(shù)據(jù)庫(kù)中創(chuàng)建一個(gè)名為hellodb的數(shù)據(jù)庫(kù)時(shí),cd /var/lib/mysql中就會(huì)看見(jiàn)一個(gè)名為hellodb的數(shù)據(jù)庫(kù)
搜狗截圖20171109091037.png -
配置好后開(kāi)啟數(shù)據(jù)庫(kù)服務(wù)
systemctl start mariadb——對(duì)應(yīng)監(jiān)聽(tīng)端口為3306
通過(guò)mysql命令進(jìn)入數(shù)據(jù)庫(kù),SHOW ENGINES;來(lái)查看存儲(chǔ)引擎的類型,默認(rèn)為innodb類型。
搜狗截圖20171109095740.png
或是SHOW ENGINE INNODB STATUS;來(lái)查看引擎的狀態(tài)
注意:在centos7版本以后當(dāng)使用SHOW ENGINE MYISAM STATUS命令時(shí),雖然可以查看但是只能看見(jiàn)一個(gè)空的值
搜狗截圖20171109091653.png
二.有關(guān)innodb存儲(chǔ)引擎的介紹
(1)數(shù)據(jù)存儲(chǔ)于“表空間(table space)"中:
(2) 所有數(shù)據(jù)庫(kù)中的所有類型為InnoDB的表的數(shù)據(jù)和索引存儲(chǔ)于同一個(gè)表空間中;
表空間文件:datadir定義的目錄中
文件:ibdata1, ibdata2, ...
(3) innodb_file_per_table=ON,意味著每表使用單獨(dú)的表空間文件;
每表的數(shù)據(jù)文件(數(shù)據(jù)和索引,存儲(chǔ)于數(shù)據(jù)庫(kù)目錄)存儲(chǔ)于自己專用的表空間文件中,并存儲(chǔ)于數(shù)據(jù)庫(kù)目錄下: tbl_name.ibd
表結(jié)構(gòu)的定義:在數(shù)據(jù)庫(kù)目錄,tbl_name.frm
在數(shù)據(jù)庫(kù)庫(kù)中創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)
create database hellodb character set 'utf8';
use hellodb
create table mydb1(id int ,name char(20)) engine=innodb;
創(chuàng)建成功后在/var/lib/mysql中cd 到hellodb中查看
事務(wù)型存儲(chǔ)引擎,適合對(duì)事務(wù)要求較高的場(chǎng)景中;但較適用于處理大量短期事務(wù);
基于MVCC(Mutli Version Concurrency Control)支持高并發(fā);支持四個(gè)隔離級(jí)別,默認(rèn)級(jí)別為REPEATABLE-READ;間隙鎖以防止幻讀;
使用聚集索引(主鍵索引);
支持”自適應(yīng)Hash索引“;
(4)鎖粒度:
1.行級(jí)鎖——當(dāng)用戶在修改某一行的時(shí)候,加上行級(jí)鎖,其他用戶不能讀也不能寫(xiě),當(dāng)用戶在讀某一行的時(shí)候,其他用戶只能讀不能寫(xiě)
2.間隙鎖——是其他用戶不能再兩行之間加入新的行
(5)總結(jié):
數(shù)據(jù)存儲(chǔ):表空間;
并發(fā):MVCC,間隙鎖,行級(jí)鎖;
索引:聚集索引、輔助索引;
性能:預(yù)讀操作、內(nèi)存數(shù)據(jù)緩沖、內(nèi)存索引緩存、自適應(yīng)Hash索引、插入操作緩存區(qū);
備份:支持熱備;
(6)表創(chuàng)建后的查看
進(jìn)入hellodb數(shù)據(jù)庫(kù)
show table status/G——查看所有表
show table status like 'my'\G——查看my開(kāi)頭的表
show table status where engine = 'innodb'\G——查看存儲(chǔ)引擎為innodb的表
(7)myisam存儲(chǔ)引擎的介紹
1.支持全文索引(FULLTEXT index)、壓縮、空間函數(shù)(GIS);
2.不支持事務(wù)
3.鎖粒度:表級(jí)鎖
4.崩潰無(wú)法保證表安全恢復(fù)
5.適用場(chǎng)景:只讀或讀多寫(xiě)少的場(chǎng)景、較小的表(以保證崩潰后恢復(fù)的時(shí)間較短);
6.文件:每個(gè)表有三個(gè)文件,存儲(chǔ)于數(shù)據(jù)庫(kù)目錄中
tbl_name.frm:表格式定義;
tbl_name.MYD:數(shù)據(jù)文件;
tbl_name.MYI:索引文件;
在mysql中創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)來(lái)查看
create database myisamdb;
use myisamdb;
create table myuser(id int,name char(30)) engine='MYISAM';
在/var/lib/mysql/myisamdb查看
7.特性:
加鎖和并發(fā):表級(jí)鎖;——當(dāng)用戶修改表中的某個(gè)行的時(shí)候整個(gè)表其他用戶都不讀和寫(xiě)
修復(fù):手動(dòng)或自動(dòng)修復(fù)、但可能會(huì)丟失數(shù)據(jù);
索引:非聚集索引;
延遲索引更新;
表壓縮;
三.有關(guān)鎖機(jī)制介紹
(1)鎖類型
讀鎖:共享鎖,可被多個(gè)讀操作共享——能讀,不能寫(xiě)
寫(xiě)鎖:排它鎖,獨(dú)占鎖——其他用戶既不能讀也不能寫(xiě)
(2)鎖粒度
表鎖:在表級(jí)別施加鎖,并發(fā)性較低
行鎖:在行級(jí)別施加鎖,并發(fā)性高,維持鎖狀態(tài)的成本較大
(3)鎖策略
在鎖粒度級(jí)數(shù)據(jù)安全性之間尋求一種平衡機(jī)制
存儲(chǔ)引擎:級(jí)別以及何時(shí)施加或釋放鎖由存儲(chǔ)引擎自行決定
Mysql Server:表級(jí)別,可自行決定,也允許顯示請(qǐng)求
(4)鎖類別
顯示鎖:用戶手動(dòng)請(qǐng)求的鎖
隱式鎖:存儲(chǔ)引擎自行根據(jù)需要施加的鎖
(5)顯示鎖的使用
- LOCK TABLES
示例:
use hellodb;
DESC mydb1;
搜狗截圖20171109110852.png
LOCK TABLES mydb1 write;——將表mydb1設(shè)置寫(xiě)鎖,屬于排他鎖,自己可以讀,但不能寫(xiě),而其他用戶不能寫(xiě)也不能讀
搜狗截圖20171109111344.png
執(zhí)行unlock tables mydb1;對(duì)方才能執(zhí)行讀寫(xiě)命令搜狗截圖20171109111503.png
LOCK TABLES mydb1 read ;-設(shè)置讀鎖
搜狗截圖20171109111653.png
解鎖后才可以執(zhí)行搜狗截圖20171109111755.png
- FLUSH LOCK
直接將hellodb中所有的表都做了鎖機(jī)制
例: FLUSH TABLES WITH READ LOCK;
搜狗截圖20171109112701.png
unlock tables ;
搜狗截圖20171109112748.png
四.事務(wù)
(1)事務(wù):一組原子性的SQL的查詢或是一個(gè)多個(gè)SQL語(yǔ)句組成的獨(dú)立的工作單元
(2)事務(wù)日志
innodb_log_files_in_group
innodb_log_group_home_dir
innodb_log_file_size
innodb_mirrored_log_groups
(3)ACID測(cè)試
A:AUTOMICITY,原子性;整個(gè)事務(wù)中的所有操作要么全部成功執(zhí)行,要么全部失敗后回滾;
C:CONSISTENCY,一致性;數(shù)據(jù)庫(kù)總是應(yīng)該從一個(gè)一致性狀態(tài)轉(zhuǎn)為另一個(gè)一致性狀態(tài);
I:ISOLATION,隔離性;一個(gè)事務(wù)所做出的操作在提交之前,是否能為其它事務(wù)可見(jiàn);出于保證并發(fā)操作之目的,隔離有多種級(jí)別;
D:DURABILITY,持久性;事務(wù)一旦提交,其所做出的修改會(huì)永久保存;
(4)事務(wù)的自動(dòng)提交以及手動(dòng)控制
1.自動(dòng)提交事務(wù):
select @@autocommit;——設(shè)置為自動(dòng)提交
如果想關(guān)掉自動(dòng)提交服務(wù)就要設(shè)置為
set @@session.autocommit=0;
2.手動(dòng)控制事務(wù)
啟動(dòng):START TRANSACTION
提交:COMMIT
回滾:ROLLBACK
事務(wù)特性:支持savepionts——類似做快照,建立存儲(chǔ)點(diǎn)
3.事務(wù)隔離級(jí)別
READ-UNCOMMITTED:讀未提交——臟讀;
READ-COMMITTED:讀可提交——不可重復(fù)讀;
REPEATABLE-READ:可重復(fù)讀——幻讀;
SERIALIZABLE:串行化
以上命令通過(guò)實(shí)驗(yàn)來(lái)進(jìn)行驗(yàn)證以便理解
(1)進(jìn)入hellodb數(shù)據(jù)庫(kù)中
(2)關(guān)閉自動(dòng)提交 set @@session.autocommit=0;
(3)設(shè)置隔離級(jí)別 set @@session.tx_isolation="READ-UNCOMMITTED";
(4)開(kāi)啟事務(wù) start transaction;
(5)以上命令在兩個(gè)虛擬機(jī)上的數(shù)據(jù)庫(kù)做相同操作,交叉式開(kāi)啟事務(wù)
在第一個(gè)hellodb中執(zhí)行delete from mydb1 where id=2;
搜狗截圖20171109161748.png
搜狗截圖20171109161913.png
提交后執(zhí)行,該事務(wù)執(zhí)行完畢
重新設(shè)置隔離級(jí)別為set @@session.tx_isolation="READ-COMMITTED"
重新開(kāi)啟事務(wù) start transaction;
執(zhí)行 inset into mydb1 values(id=2,name=catty);
搜狗截圖20171109163041.png搜狗截圖20171109163142.png
在第一個(gè)數(shù)據(jù)中執(zhí)行commit;
此時(shí)在第二個(gè)數(shù)據(jù)庫(kù)中則可以看見(jiàn),這就是read-committed級(jí)別,只有提交后才能看見(jiàn)最新的修改內(nèi)容搜狗截圖20171109163605.png
但是該級(jí)別一旦提交就無(wú)辦法重復(fù)讀
為此引入第三個(gè)級(jí)別方式 REPEATABLE-READ
依然要先set @@session.tx_isolation="REPEATABLE-READ";
開(kāi)啟事務(wù):START TRANSACTION;
在第一個(gè)數(shù)據(jù)庫(kù)中執(zhí)行insert into mydb1 values(7,"mayun");
select * from mydb1;可以看見(jiàn)新增加的用戶
但是在另一個(gè)數(shù)據(jù)庫(kù)中無(wú)法看見(jiàn)新加的內(nèi)容,即使第一個(gè)數(shù)據(jù)庫(kù)執(zhí)行commit命令第二臺(tái)數(shù)據(jù)庫(kù)中也無(wú)法看見(jiàn),這就是可重復(fù)讀,但屬于幻讀。
幻讀:在第一個(gè)虛擬機(jī)上的數(shù)據(jù)庫(kù)能看見(jiàn)新加的用戶,但是在第二個(gè)數(shù)據(jù)庫(kù)中就無(wú)法看見(jiàn),此時(shí)如果在第二個(gè)表中增加id為7的用戶,就無(wú)法增加成功,這就是幻讀帶來(lái)的影響
搜狗截圖20171109165753.png
第四個(gè)級(jí)別:SERIALIZABLE
set @@session.tx_isolation="SERIALIZABLE";
START TRANSACTION;
第二個(gè)數(shù)據(jù)庫(kù)做相同操作
搜狗截圖20171109170942.png搜狗截圖20171109170600.png
(4)事務(wù)支持savepoints:
該設(shè)置類似建立還原點(diǎn)
此時(shí)設(shè)置一個(gè)還原點(diǎn)
SAVEPOINT first;
delete from mydb1 where id=2;
rollback to first;
當(dāng)建立多個(gè)savepoint時(shí),可以直接執(zhí)行rollback直接回到最初的狀態(tài)
五.MYSQL索引
1.索引的概念:提取索引的創(chuàng)建在的表上字段中的數(shù)據(jù),構(gòu)建出一個(gè)獨(dú)特的數(shù)據(jù)結(jié)構(gòu)
2.索引的作用:
加速查詢操作
副作用:降低寫(xiě)操作性能;
表中數(shù)據(jù)子集:把表中某個(gè)或某些字段的數(shù)據(jù)提取出來(lái)另存為一個(gè)特定數(shù)據(jù)結(jié)構(gòu)組織的數(shù)據(jù);
某個(gè)字段或某些字段:WHERE子句中用到的字段;
3.索引的類型
(1)B+ TREE(balance tree)
B+ TREE:順序存儲(chǔ),每一個(gè)葉子結(jié)點(diǎn)到根結(jié)點(diǎn)的距離相同;左前綴索引,適合于范圍類型的數(shù)據(jù)查詢;
適用于B+ TREE索引的查詢類型:全鍵值、鍵值范圍或鍵前綴;
全值匹配:精確匹配某個(gè)值;
WHERE COLUMN = 'value';
匹配最左前綴:只精確匹配起頭的部分;
WEHRE COLUMN LIKE 'PREFIX%';
匹配范圍值:
精確匹配某一列,范圍匹配另一列;——select name from students where name='wang' and age > 30;
只用訪問(wèn)索引的查詢:覆蓋索引;
index(Name)
SELECT Name FROM students WHERE Name LIKE 'L%';
不適用B+ TREE索引:
如果查詢條件不是從最左側(cè)列開(kāi)始,索引無(wú)效;
index(age,Fname), WHERE Fname='Jerry';——索引不是從左側(cè)匹配,所以索引無(wú)效 ,
WHERE age>30 AND Fname='Smith';——這是正確的索引方式
不能跳過(guò)索引中的某列;
index(name,age,gender)
WHERE name='black' and age > 30;——可以不索引最后一列
WHERE name='black' AND gender='F';——但是不能跳過(guò)中間的列
如果查詢中的某個(gè)列是為范圍查詢,那么其右側(cè)的列都無(wú)法再使用索引優(yōu)化查詢;
WHERE age>30 AND Fname='Smith';
(2) Hash索引:基于哈希表實(shí)現(xiàn),特別適用于值的精確匹配查詢;
適用場(chǎng)景:只支持等值比較查詢,例如=, IN(), <=>
不用場(chǎng)景:
所有非精確值查詢;MySQL僅對(duì)memory存儲(chǔ)引擎支持顯式的hash索引;
4.通過(guò)操作來(lái)演示索引的效果
步驟:
(1)首先執(zhí)行commit命令,提交
(2)選中一個(gè)數(shù)據(jù)例如hellodb,進(jìn)入后創(chuàng)建一個(gè)表 create table students1(id int unsigned auto_increment primary key,name char(30) not null ,age tinyint unsigned,gender enum('F', 'M'),major varchar(200));
insert into students values(1,"yangguo",20,"m","jianfa");
insert into students values(2,"yangbuhui",18,"f","suibian");
搜狗截圖20171109212725.png
(3)批量創(chuàng)建用戶
生成數(shù)組gender=('F' 'M')
echo ${gender[0]}
echo ${gender[1]}
搜狗截圖20171109213136.png
for i in {1..100};do mysql -uroot -pmagedu -e "insert into hellodb.students(name,age,gender) values('stu$i','$[RANDOM%80+18]','${gender[$RANDOM%2]}');";done
創(chuàng)建成功后,在數(shù)據(jù)庫(kù)中select * from students;
驗(yàn)證創(chuàng)建成功
(4)使用explain來(lái)查看查詢邏輯
搜狗截圖20171109213938.png
(5)創(chuàng)建索引
create index age ON students(age);
explain select name from students where age > 10;
通過(guò)age索引來(lái)查詢內(nèi)容
create index age_and_name ON students(name ,age);
會(huì)采用age_and_name來(lái)進(jìn)行索引,屬于覆蓋索引,不會(huì)再使用age索引來(lái)進(jìn)行查詢,因?yàn)檫@樣做效率相對(duì)低效
我們也可以將studnets(name,age)順序調(diào)換一下
首先drop index age_and_name ON students;
然后創(chuàng)建新的索引
create index age_and_name ON students(name,age);
explain select name from students where age >90;
此時(shí)將會(huì)使用age索引而不是age_and_name索引,因?yàn)樗饕С肿髠?cè)匹配索引機(jī)制
所以我們可以使用explain select name from students where name='stu1%' and age >20;來(lái)進(jìn)行索引查詢,此時(shí)查詢索引方式為age_and_name
擴(kuò)展:一般情況默認(rèn)為simple簡(jiǎn)單查詢方式,但是也可以根據(jù)條件來(lái)實(shí)現(xiàn)其他查詢方式
例:select avg(age) from students;計(jì)算平均年齡
再通過(guò)select name ,age from students where age > (select avg(age) from students);來(lái)查詢大于平均年齡的人
通過(guò)explain語(yǔ)句分析使用的查詢方式
六.mysql用戶和權(quán)限管理
首先一般情況下要設(shè)置跳過(guò)數(shù)據(jù)庫(kù)域名解析的問(wèn)題,否則會(huì)很耽誤時(shí)間,skip_name_resolve=ON
(1)用戶賬號(hào)
user@host
user:賬戶名稱;
host:此賬戶可通過(guò)哪些客戶端主機(jī)請(qǐng)求創(chuàng)建連接線程;
%:任意長(zhǎng)度的任意字符;
_:任意單個(gè)字符;
(2)MySQL權(quán)限類別:
庫(kù)級(jí)別:
CREATE,ALTER,DROP
INDEX
CREATE VIEW
SHOW VIEW
GRANT:能夠把自己獲得的權(quán)限生成一個(gè)副本轉(zhuǎn)贈(zèng)給其它用戶;——不建議轉(zhuǎn)增權(quán)限
OPTION
表級(jí)別:
CREATE,ALTER,DROP ,INDEX
CREATE VIEW
SHOW VIEW
GRANT:能夠把自己獲得的權(quán)限生成一個(gè)副本轉(zhuǎn)贈(zèng)給其它用戶;——不建議轉(zhuǎn)增權(quán)限
OPTION
字段級(jí)別:
管理類:
CREATE USER
RELOAD
LOCK TABLES
REPLICATION CLIENT, REPLICATION SLAVE
SHUTDOWN
FILE
SHOW DATABASES
PROCESS
SUPER
程序類:
FUNCTION,PROCEDURE,TRIGGER
操作:CREATE,ALTER,DROP,EXECUTE
(3)修改用戶密碼
1.set password for 'root'@localhost = password(centos);
- UPDATE mysql.user SET Password=PASSWORD('centos') WHERE User='root' AND Host='localhost';
-
mysqladmin -uroot -h127.0..0.1 -p password 'centos';
所以如果當(dāng)我們忘記密碼時(shí),例如修改密碼后忘記后我們可以采用的方法是
首先關(guān)掉mariadb.server
然后 vim /usr/lib/systemd/system/mariadb.server
搜狗截圖20171109223335.png
修改后 systemctl daemon-reload
再開(kāi)啟mariadb.server服務(wù)
執(zhí)行mysql ;進(jìn)入數(shù)據(jù)庫(kù)
使用update命令來(lái)修改新的密碼
UPDATE mysql.user SET Password=PASSWORD('centos') WHERE User='root' ;
再退出
關(guān)閉mariadb
vim /usr/lib/system/systemd/mariadb.server
將之前加的命令刪除后再執(zhí)行systemctl daemon-reload;
執(zhí)行完畢