這是我參與8月更文挑戰的第11天,活動詳情查看:8月更文挑戰mysql
感謝閱讀,但願能對你有所幫助,博文如有瑕疵請在評論區留言或在主頁我的介紹中添加我私聊我,感謝每一位小夥伴不吝賜教。我是XiaoLin,既會寫bug也會唱rap的男人算法
命令 | 描述 | 備註 |
---|---|---|
create user xiaolin identified by '123456'; | 建立名稱爲xiaolin的用戶,密碼爲123456 | |
select host,user,password,select_priv,insert_priv,drop_priv from mysql.user; | 查看用戶和權限的相關信息 | |
set password = password('123456') | 修改其餘用戶的密碼 | 全部經過 user 表的修改,必須用 flush privileges;命令才能生效 |
update mysql.user set user = 'zs' where user = 'xiaolin' | 修改用戶名 | 全部經過 user 表的修改,必須用 flush privileges;命令才能生效 |
drop user xiaolin | 刪除用戶 | 不要經過delete from user where user = 'xiaolin'進行刪除,系統會有殘留信息保存 |
host表示鏈接類型。sql
user表示用戶名,同一用戶經過不一樣方式鏈接的權限是不同的。數據庫
這裏顯示的是明文密碼經過哦MYSQLSHA1加密算法加密後獲得的密文密碼,是不可逆的,mysql 5.7 的密碼保存到 authentication_string 字段中再也不使用 password 字段。緩存
表示該用戶所擁有的權限。安全
咱們能夠經過命令來授予用戶權限,該權限若是發現沒有該用戶,則會直接新建一個用戶。服務器
格式爲:markdown
grant 權限 1,權限 2,…權限 n on 數據庫名稱.表名稱 to 用戶名@用戶地址 identified by‘鏈接口令
複製代碼
示範:網絡
# 給 xiaolin 用戶用本地命令行方式下,授予 user 這個庫下的全部表的插刪改查的權限。
grant select,insert,delete,drop on user.* to xiaolin@localhost;
# 授予經過網絡方式登陸的的 xiaolin 用戶 ,對全部庫全部表的所有權限,密碼設爲 123.
grant all privileges on *.* to xiaolin@'%' identified by '123';
複製代碼
咱們可使用命令來查看當前用戶的權限。數據結構
show grants;
複製代碼
咱們可使用命令來收回用戶的權限,權限收回後,必須用戶從新登陸後,才能生效。
revoke
[權限 1,權限 2,…權限 n] on 庫名.表名 from 用戶名@用戶地址 ;
複製代碼
示範:
# 收回全庫全表的全部權限
REVOKE ALL PRIVILEGES ON mysql.* FROM joe@localhost;
# 收回 mysql 庫下的全部表的插刪改查權限
REVOKE select,insert,update,delete ON mysql.* FROM xiaolin@localhost;
複製代碼
和其它數據庫相比,MySQL 有點不同凡響,它的架構能夠在多種不一樣場景中應用併發揮良好做用。主要體如今存儲引擎的架構上,插件式的存儲引擎架構將查詢處理和其它的系統任務以及數據的存儲提取相分離。這種架構能夠根據業務的需求和實際須要選擇合適的存儲引擎。
MySql大概分爲四層:
最上層是一些客戶端和鏈接服務,包含本地 sock 通訊和大多數基於客戶端/服務端工具實現的相似於 tcp/ip 的通訊。主要完成一些相似於鏈接處理、受權認證、及相關的安全方案。在該層上引入了線程池的概念,爲經過認證安全接入的客戶端提供線程。一樣在該層上能夠實現基於 SSL 的安全連接。服務器也會爲安全接入的每一個客戶端驗證它所具備的操做權限。
服務層提供各類用戶使用的接口,同時提供SQL優化器,對用戶傳進來的SQL語句進行優化。他有幾個組件。
組件名 | 描述 |
---|---|
Management Serveices & Utilities | 系統管理和控制工具 |
SQL Interface | SQL 接口。接受用戶的 SQL 命令,而且返回用戶須要查詢的結果。好比 select from就是調用 SQL Interface |
Parser | 解析器。 SQL 命令傳遞到解析器的時候會被解析器驗證和解析 |
Optimizer | 查詢優化器。SQL 語句在查詢以前會使用查詢優化器對查詢進行優化,好比有where 條件時,優化器來決定先投影仍是先過濾。 |
Cache 和 Buffer | 查詢緩存。若是查詢緩存有命中的查詢結果,查詢語句就能夠直接去查詢緩存中取數據。這個緩存機制是由一系列小緩存組成的。好比表緩存,記錄緩存,key 緩存,權限緩存等 |
存儲引擎層,存儲引擎真正的負責了 MySQL 中數據的存儲和提取,服務器經過 API 與存儲引擎進行通訊。不一樣的存儲引擎具備的功能不一樣,這樣咱們能夠根據本身的實際須要進行選取。
數據存儲層,主要是將數據存儲在運行於裸設備的文件系統之上,並完成與存儲引擎的交互。
mysql 的查詢流程大體是:
咱們手寫一條完整的SQL大概是這樣寫的。
SELECT DISTINCT
< select_list >
FROM
< left_table > < join_type >
JOIN < right_table > ON < join_condition >
WHERE
< where_condition >
GROUP BY
< group_by_list >
HAVING
< having_condition >
ORDER BY
< order_by_condition >
LIMIT < limit_number >
複製代碼
然而它的執行順序是這樣的.。
FROM <left_table>
ON <join_condition>
<join_type> JOIN <right_table>
WHERE <where_condition>
GROUP BY <group_by_list>
HAVING <having_condition>
SELECT
DISTINCT <select_list>
ORDER BY <order_by_condition>
LIMIT <limit_number>
複製代碼
對比項 | MyISAM | InnoDB |
---|---|---|
外鍵 | 不支持 | 支持 |
事務 | 不支持 | 支持 |
行表鎖 | 表鎖,即便操做一條記錄也會鎖住整張表,不適合高併發操做 | 行鎖,操做時只鎖住某一行,不對其餘行有影響,適合高併發操做 |
緩存 | 只緩存索引不緩存真實數據 | 不只僅緩存索引還緩存真實數據,對內存要求較高,並且內存大小對性能有決定性的影響 |
MySQL 官方對索引的定義爲:索引(Index)是幫助 MySQL 高效獲取數據的數據結構。能夠獲得索引的本質:索引是數據結構。能夠簡單理解爲排好序的快速查找數據結構。
在數據以外,數據庫系統還維護着知足特定查找算法的數據結構,這些數據結構以某種方式引用(指向)數據,這樣就能夠在這些數據結構上實現高級查找算法。這種數據結構,就是索引。
左邊是數據表,一共是兩列七條數據,最左邊的是數據記錄的物理地址。爲了加快 Col2 的查找,能夠維護一個右邊所示的二叉查找樹,每一個節點分別包含索引鍵值和一個指向對應數據記錄物理地址的指針,這樣就能夠運用二叉查找在必定的複雜度內獲取到相應數據,從而快速的檢索出符合條件的記錄。
通常來講索引自己也很大,不可能所有存儲在內存中,所以索引每每以索引文件的形式存儲的磁盤上。
MySQL 使用的是 Btree 索引。一顆B樹,淺藍色的塊咱們稱之爲一個磁盤塊,能夠看到每一個磁盤塊包含幾個數據項(深藍色所示)和指針(黃色所示)。
磁盤塊 1 包含數據項 17 和 35,包含指針 P一、P二、P3,P1 表示小於 17 的磁盤塊,P2 表示在 17 和 35 之間的磁盤塊,P3 表示大於 35 的磁盤塊。
真實的數據存在於葉子節點即 三、五、九、十、1三、1五、2八、2九、3六、60、7五、7九、90、99。
非葉子節點只不存儲真實的數據,只是爲了做爲分隔線,存儲指引搜索方向的數據項,如 1七、35 並不真實存在於數據表中。
若是要查找數據項 29,那麼首先會把磁盤塊 1 由磁盤加載到內存,此時發生一次 IO。
在內存中用二分查找肯定 29在 17 和 35 之間,鎖定磁盤塊 1 的 P2 指針,內存時間由於很是短(相比磁盤的 IO)能夠忽略不計。經過磁盤塊 1的 P2 指針的磁盤地址把磁盤塊 3 由磁盤加載到內存,發生第二次 IO。
29 在 26 和 30 之間,鎖定磁盤塊 3 的 P2 指針,經過指針加載磁盤塊 8 到內存,發生第三次 IO,同時內存中作二分查找找到 29,結束查詢,總計三次 IO。
3層的B樹能夠表示上百萬的數據,若是上百萬的數據查找只須要三次 IO,性能提升將是巨大的。
若是沒有索引,每一個數據項都要發生一次 IO,那麼總共須要百萬次的 IO,顯然成本很是很是高。
咱們能夠看到BTree結構圖中,每一個節點不只僅包含key值,同時還有data值,每個頁的存儲空間是有限的,若是data數據較大時會致使每一個節點(即每個頁)能存儲的key數量很小,當存儲的數據量很大的時候會致使BTree的深度很深,增大了查詢時磁盤I/O的次數。
而在B+Tree中,全部數據記錄節點都是按照鍵值大小順序放在同一層的葉子節點上,而非葉子節點只存儲key信息,這樣能夠大大增長每一個節點存儲的key值的數量,下降B+Tree的高度。
實際狀況中每一個節點可能不能填滿,在數據庫中,B+Tree的高度通常在24層之間,MySQL的InnoDB存儲引擎在設計時是將根節點常駐內存的(不動用磁盤I/O,直接上內存找),也就是說查找某一鍵值行記錄時最多隻須要13次磁盤I/O操做。
單值索引指一個索引只包含單個列,一個表能夠有多個單列索引。
# 隨着表的創建一塊兒創建
CREATE TABLE customer (id INT(10) UNSIGNED AUTO_INCREMENT ,customer_no VARCHAR(200),customer_name VARCHAR(200), PRIMARY KEY(id), KEY (customer_name) );
# 單獨建單值索引
CREATE INDEX idx_customer_name ON customer(customer_name);
複製代碼
惟一索引指的是索引列必須惟一,可是容許有空值,且只能有一個。
# 隨着表的創建一塊兒創建
CREATE TABLE customer (id INT(10) UNSIGNED AUTO_INCREMENT ,customer_no VARCHAR(200),customer_name VARCHAR(200), PRIMARY KEY(id), KEY (customer_name), UNIQUE (customer_no) );
# 單獨建惟一索引
CREATE UNIQUE INDEX idx_customer_no ON customer(customer_no);
複製代碼
設定爲主鍵後數據庫會自動創建索引,innodb爲聚簇索引,主鍵索引列值不能爲空。
# 隨表一塊兒建索引
CREATE TABLE customer (id INT(10) UNSIGNED AUTO_INCREMENT ,customer_no VARCHAR(200),customer_name VARCHAR(200), PRIMARY KEY(id) );
# 單獨建主鍵索引
ALTER TABLE customer add PRIMARY KEY customer(customer_no);
# 刪除建主鍵索引
ALTER TABLE customer drop PRIMARY KEY ;
# 若是須要修改建主鍵索引,必須先刪除掉(drop)原索引,再新建(add)索引
複製代碼
他會符合兩個原則:
複合索引是一個索引包含多個列。
# 隨表一塊兒建索引
CREATE TABLE customer (id INT(10) UNSIGNED AUTO_INCREMENT ,customer_no VARCHAR(200),customer_name VARCHAR(200), PRIMARY KEY(id), KEY (customer_name), UNIQUE (customer_name), KEY (customer_no,customer_name) );
# 單獨建索引
CREATE INDEX idx_no_name ON customer(customer_no,customer_name);
複製代碼
主鍵索引是在建表時自動建立的。
建表,主鍵自動建立主鍵索引
create table t_user(id varchar(20) primary key,name varchar(20));
複製代碼
查看索引
show index from t_user;
複製代碼
創表的時候一塊兒建立索引
# 在建表的時候字段後面用key(列名)來建立索引,可是咱們沒辦法指定索引名,默認索引名和列名一致。
create table t_user(id varchar(20) primary key , name varchar(20 , key(name)))
複製代碼
建立完表之後加索引
# 語法格式
create index 索引名 on 表名(列名);
# 示範
create index index_name on t_user(name);
複製代碼
刪除索引
# 語法格式
drop index 索引名 on 表名;
# 示範
drop index index_name on t_user;
複製代碼
建表的時候建立索引
# 在建表的時候字段後面用unique(列名)來建立索引,可是咱們沒辦法指定索引名,默認索引名和列名一致。
create table t_user(id varchar(20) primary key , name varchar(20) , unique(name) );
複製代碼
建立表以後建立索引
# 格式
create unique index 索引名 on 表名(列名);
# 示範
create unique index index_name on t_user(name);
複製代碼
建表的時候建立索引
# 在建表的時候字段後面用key(列名1,列名2...)來建立索引,可是咱們沒辦法指定索引名,默認索引名和列名一致。
create table t_user (id varchar(20) primary key , name varchar(20) , age int , key(name , age) );
複製代碼
建表以後建立
# 語法格式
create index 索引名 on 表名(列名1,列名2...);
# 示範
create index index_name_age on t_user (name , age);
複製代碼