MySQL高級知識(一)——基礎
MySQL高級知識——基礎
前言:MySQL高級知識主要來自於尚硅谷中的MySQL的視頻資源。(記錄在此,是爲了以後自己能夠很方面的看到這些知識點。)
1. MySQL概述
- 前屬於Oracle公司。
- MySQL是一種關聯數據庫管理系統,將數據保存在不同的表中,而不是將所有數據放在一個大倉庫內,這樣就增加了速度並提高了靈活性。
- Mysql是開源的,所以你不需要支付額外的費用。
- Mysql是可以定製的,採用了GPL協議,你可以修改源碼來開發自己的Mysql系統。
- Mysql支持大型的數據庫。可以處理擁有上千萬條記錄的大型數據庫。
- MySQL使用標準的SQL數據語言形式。
- Mysql可以允許於多個系統上,並且支持多種語言。這些編程語言包括C、C++、Python、Java、Perl、PHP、Eiffel、Ruby和Tcl等。
- MySQL支持大型數據庫,支持5000萬條記錄的數據倉庫,32位系統表文件最大可支持4GB,64位系統支持最大的表文件爲8TB。
- 我們對Markdown編輯器進行了一些功能拓展與語法支持,除了標準的Markdown編輯器功能,我們增加了如下幾點新功能,幫助你用它寫博客:
2. MySQL高手必備
- 數據庫內部結構和原理
- 數據庫建模優化
- 數據庫索引建立
- SQL語句優化
- SQL編程
- mysql服務器的安裝配置
- 數據庫的性能監控分析與系統優化
- 各種參數常量設定
- 主從複製
- 分佈式架構搭建、垂直切割和水平切割
- 數據遷移
- 容災備份和恢復
- shell或者python等腳本語言開發
- 對開源數據庫進行二次開發
3. MySQL的Linux版本安裝(非重點)
3.1. 下載地址
官網下載地址:http://dev.mysql.com/downloads/mysql/
3.2. 拷貝&解壓縮
網上搜索linux的ftp傳輸以及解壓縮命令,之後解壓縮。
3.3. 檢查工作
- 檢查當前系統是否安裝過mysql
執行安裝命令前,先執行查詢命令
rpm -qa|grep mysql
如果存在mysql-libs的舊版本包如下:
請先執行卸載命令:rpm -e --nodeps mysql-libs
- 檢查/tmp文件夾權限、
由於mysql安裝過程中,會通過mysql用戶在/tmp目錄下新建tmp_db文件,所以請給/tmp較大的權限
執行 :chmod -R 777 /tmp
3.4. 安裝
在mysql的安裝文件目錄下執行:
rpm -ivh MySQL-server-5.5.54-1.linux2.6.x86_64.rpm
rpm -ivh MySQL-client-5.5.54-1.linux2.6.x86_64.rpm
3.5. 查看MySQL安裝版本
或者可以執行 mysqladmin --version
命令,類似java -version
如果打出消息,即爲成功。
通過vim 查看 mysql組 和mysql組
3.6. MySQL服務的啓動+停止+查看狀態
- 啓動:
systemctl start mysqld
- 停止:
systemctl stop mysqld
- 狀態:
systemctl status mysqld
此爲centos7以後的linux命令
3.7. 首次登錄
查看此博客:https://blog.csdn.net/dh12313012/article/details/87274385
3.8. MySQL安裝位置
在linux下查看安裝目錄
ps -ef | grep mysql
參數 | 路徑 | 解釋 | 備註 |
---|---|---|---|
–basedir | /usr/bin | 相關命令目錄 | mysqladmin mysqldump等命令 |
–datadir | /var/lib/mysql/ | mysql數據庫文件的存放路徑 | |
–plugin-dir | /usr/lib64/mysql/plugin | mysql插件存放路徑 | |
–log-error | /var/lib/mysql/jack.atguigu.err | mysql錯誤日誌路徑 | |
–pid-file | /var/lib/mysql/jack.atguigu.pid | 進程pid文件 | |
–socket | /var/lib/mysql/mysql.sock | 本地連接時用的unix套接字文件 | |
----- | /usr/share/mysql 配置文件目錄 | mysql腳本及配置文件 | |
----- | /etc/init.d/mysql | 服務啓停相關腳本 |
3.9. 自啓動MySQL服務
- 自啓動命令:
systemctl enable mysqld
- 關閉自啓動:
systemctl disable mysqld
3.10. 修改字符集問題
嘗試插入數據:
原因是字符集的問題。
- 查看字符集
show variables like 'character%'
show variables like '%char%'
默認的是客戶端和服務器都使用了latin1,所以會亂碼。 - 修改my.cnf
在/usr/share/mysql/
中找到my.cnf的配置文件,
拷貝其中的my-huge.cnf 到 /etc/ 並命名爲my.cnf
mysql 優先選中 /etc/ 下的配置文件
然後修改my.cnf:
[client]
default-character-set=utf8
[mysqld]
character_set_server=utf8
character_set_client=utf8
collation-server=utf8_general_ci
[mysql]
default-character-set=utf8
-
重新啓動mysql
但是原庫的設定不會發生變化,參數修改之對新建的數據庫生效 -
已生成的庫表字符集如何變更
修改數據庫的字符集
mysql> alter database mytest character set 'utf8';
修改數據表的字符集
mysql> alter table user convert to character set 'utf8';
但是原有的數據如果是用非'utf8'編碼的話,數據本身不會發生改變。
4. MySQL配置文件(重點了解一下)
- 二進制日誌log-bin該文件主要是主從複製以及備份恢復(瞭解)
log-bin 中存放了所有的操作記錄(寫?),可以用於恢復。相當於 Redis 中的 AOF
my.cnf中的log-bin配置(默認關閉)
- 錯誤日誌log-error——默認是關閉的,記錄嚴重的警告和錯誤信息,每次啓動和關閉的詳細信息等。
- 慢查詢日誌log——默認關閉,記錄查詢的sql語句,如果開啓會降低mysql的整體性能,因爲記錄日誌也是需要小號系統資源的
- Myisam存放方式
- frm文件(framework)——存放表結構
- myd文件(data)——存放表數據
- myi文件(index)——存放表索引
- innodb存放方式
- ibdata1——Innodb引擎將所有表的的數據都存在這裏面 /usr/share/mysql/ibdata1 而frm文件存放在庫同名的包下
- frm文件——存放表結構
- 單獨存放
單獨存放
set innodb_file_per_table=on
create table mmm (id int(20) auto_increment ,name varchar(20),primary key(id));設在爲 on 後 單獨以 table名.ibd 的文件名存儲
特別提出MySQL中的重要配置文件:Windows下名爲my.ini,Linux下爲/etc/my.cnf。對於服務器的調優相關過程都在改配置文件中,需要特別掌握。
5. MySQL的用戶與權限管理
5.1. MySQL的用戶管理
- 創建用戶
create user zhang3 identified by '123123';
表示創建名稱爲zhang3的用戶,密碼設爲123123; - 瞭解user表
查看用戶
select host,user,password,select_priv,insert_priv,drop_priv from mysql.user;
select * from user\G;
將 user 中的數據以行的形式顯示出來(針對列很長的表可以採用這個方法 )
- host: 表示連接類型
% 表示所有遠程通過 TCP方式的連接
IP 地址 如 (192.168.1.2,127.0.0.1) 通過制定ip地址進行的TCP方式的連接
機器名 通過制定i網絡中的機器名進行的TCP方式的連接
::1 IPv6的本地ip地址 等同於IPv4的 127.0.0.1
localhost 本地方式通過命令行方式的連接 ,比如mysql -u xxx -p 123xxx 方式的連接。 - User:表示用戶名
同一用戶通過不同方式鏈接的權限是不一樣的。 - password:密碼
所有密碼串通過 password(明文字符串) 生成的密文字符串。加密算法爲MYSQLSHA1 ,不可逆 。
mysql 5.7 的密碼保存到 authentication_string 字段中不再使用password 字段。 - select_priv , insert_priv等
爲該用戶所擁有的權限。
- 設置密碼
修改當前用戶的密碼:
set password =password('123456')
修改某個用戶的密碼:
update mysql.user set password=password('123456') where user='li4';
flush privileges; #所有通過user表的修改,必須用該命令才能生效。 - 修改用戶
update mysql.user set user='li4' where user='wang5';
flush privileges;
,所有通過user表的修改,必須用該命令才能生效。 - 刪除用戶
drop user li4;
此處不要通過delete from user u where user='li4'
進行刪除,系統會有殘留信息保留。
5.2. 權限設置
- 設置權限
- 格式:grant 權限1,權限2,…權限n on 數據庫名稱.表名稱 to 用戶名@用戶地址 identified by ‘連接口令’;
該權限如果發現沒有該用戶,則會直接新建一個用戶。
比如grant select,insert,delete,drop on atguigudb.* to li4@localhost ;
#給li4用戶用本地命令行方式下,授予atguigudb這個庫下的所有表的插刪改查的權限。grant all privileges on *.* to joe@'%' identified by '123';
#授予通過網絡方式登錄的的joe用戶 ,對所有庫所有表的全部權限,密碼設爲123.
就算 all privileges 了所有權限,grant_priv 權限也只有 root 才能擁有。
給 root 賦連接口令grant all privileges on *.* to root@'%' ;
後新建的連接沒有密碼,需要設置密碼才能遠程連接。update user set password=password('root') where user='root' and host='%';
- 收回權限
- 格式:revoke 權限1,權限2,…權限n on 數據庫名稱.表名稱 from 用戶名@用戶地址 ;
REVOKE ALL PRIVILEGES ON mysql.* FROM joe@localhost;
#若賦的全庫的表就 收回全庫全表的所有權限REVOKE select,insert,update,delete ON mysql.* FROM joe@localhost;
#收回mysql庫下的所有表的插刪改查權限
對比賦予權限的方法。
必須用戶重新登錄後才能生效
5.3. 查看權限
- 查看當前用戶權限
show grants;
- 查看某用戶的全局權限
select * from user ;
- 查看某用戶的某庫的權限
select * from db;
- 查看某用戶的某個表的權限
select * from tables_priv;
5.4. 通過工具遠程訪問
- 先 ping 一下數據庫服務器的ip 地址確認網絡暢通。
- 關閉數據庫服務的防火牆
service iptables stop
- 確認Mysql中已經有可以通過遠程登錄的賬戶
select * from mysql.user where user='li4' and host='%';
如果沒有用戶,先執行如下命令:
grant all privileges on *.* to li4@'%' identified by '123123';
- 測試連接:
6. MySQL的一些雜項配置
6.1. 大小寫問題
show variables like '%lower_case_table_names%';
- windows系統默認大小寫不敏感,但是linux系統是大小寫敏感的
- 默認爲0,大小寫敏感。
- 設置1,大小寫不敏感。創建的表,數據庫都是以小寫形式存放在磁盤上,對於sql語句都是轉換爲小寫對錶和DB進行查找。
- 設置2,創建的表和DB依據語句上格式存放,凡是查找都是轉換爲小寫進行。
設置變量常採用 set lower_case_table_names = 1;
的方式,但此變量是隻讀權限,所以需要在配置文件中改。
當想設置爲大小寫不敏感時,要在my.cnf這個配置文件 [mysqld] 中加入 lower_case_table_names = 1
,然後重啓服務器。
但是要在重啓數據庫實例之前就需要將原來的數據庫和錶轉換爲小寫,否則更改後將找不到數據庫名。
在進行數據庫參數設置之前,需要掌握這個參數帶來的影響,切不可盲目設置。
6.2. sql_mode
MySQL的sql_mode合理設置
sql_mode是個很容易被忽視的變量,默認值是空值,在這種設置下是可以允許一些非法操作的,比如允許一些非法數據的插入。在生產環境必須將這個值設置爲嚴格模式,所以開發、測試環境的數據庫也必須要設置,這樣在開發測試階段就可以發現問題。
使用 set sql_mode=ONLY_FULL_GROUP_BY;
的方式設置會將之前的設置覆蓋掉
同時設置多個限制:set sql_mode='ONLY_FULL_GROUP_BY,NO_AUTO_VALUE_ON_ZERO';
sql_mode常用值如下:
ONLY_FULL_GROUP_BY
:
對於GROUP BY聚合操作,如果在SELECT中的列,沒有在GROUP BY中出現,那麼這個SQL是不合法的,因爲列不在GROUP BY從句中NO_AUTO_VALUE_ON_ZERO
:
該值影響自增長列的插入。默認設置下,插入0或NULL代表生成下一個自增長值。如果用戶 希望插入的值爲0,而該列又是自增長的,那麼這個選項就有用了。STRICT_TRANS_TABLES
:
在該模式下,如果一個值不能插入到一個事務表中,則中斷當前的操作,對非事務表不做限制NO_ZERO_IN_DATE
:
在嚴格模式下,不允許日期和月份爲零NO_ZERO_DATE
:
設置該值,mysql數據庫不允許插入零日期,插入零日期會拋出錯誤而不是警告。ERROR_FOR_DIVISION_BY_ZERO
:
在INSERT或UPDATE過程中,如果數據被零除,則產生錯誤而非警告。如 果未給出該模式,那麼數據被零除時MySQL返回NULLNO_AUTO_CREATE_USER
:
禁止GRANT創建密碼爲空的用戶NO_ENGINE_SUBSTITUTION
:
如果需要的存儲引擎被禁用或未編譯,那麼拋出錯誤。不設置此值時,用默認的存儲引擎替代,並拋出一個異常PIPES_AS_CONCAT
:
將"||"視爲字符串的連接操作符而非或運算符,這和Oracle數據庫是一樣的,也和字符串的拼接函數Concat相類似ANSI_QUOTES
:
啓用ANSI_QUOTES後,不能用雙引號來引用字符串,因爲它被解釋爲識別符ORACLE
:
設置等同:PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS, NO_AUTO_CREATE_USER.
7. MySQL邏輯架構介紹(重點了解一下)
和其它數據庫相比,MySQL有點與衆不同,它的架構可以在多種不同場景中應用併發揮良好作用。主要體現在存儲引擎的架構上,
插件式的存儲引擎架構將查詢處理和其它的系統任務以及數據的存儲提取相分離。這種架構可以根據業務的需求和實際需要選擇合適的存儲引擎。
7.1. 連接層
最上層是一些客戶端和連接服務,包含本地sock通信和大多數基於客戶端/服務端工具實現的類似於tcp/ip的通信。主要完成一些類似於連接處理、授權認證、及相關的安全方案。在該層上引入了線程池的概念,爲通過認證安全接入的客戶端提供線程。同樣在該層上可以實現基於SSL的安全鏈接。服務器也會爲安全接入的每個客戶端驗證它所具有的操作權限。
7.2. 服務層
- Management Serveices & Utilities: 系統管理和控制工具
- SQL Interface: SQL接口
接受用戶的SQL命令,並且返回用戶需要查詢的結果。比如select from就是調用SQL Interface - Parser: 解析器
SQL命令傳遞到解析器的時候會被解析器驗證和解析。 - Optimizer: 查詢優化器。
SQL語句在查詢之前會使用查詢優化器對查詢進行優化。
用一個例子就可以理解:select uid,name from user where gender= 1;
優化器來決定先投影還是先過濾。 - Cache和Buffer: 查詢緩存。
如果查詢緩存有命中的查詢結果,查詢語句就可以直接去查詢緩存中取數據。
這個緩存機制是由一系列小緩存組成的。比如表緩存,記錄緩存,key緩存,權限緩存等
緩存是負責讀,緩衝負責寫。
7.3. 引擎層
存儲引擎層,存儲引擎真正的負責了MySQL中數據的存儲和提取,服務器通過API與存儲引擎進行通信。不同的存儲引擎具有的功能不同,這樣我們可以根據自己的實際需要進行選取。後面介紹MyISAM和InnoDB
7.4. 存儲層
數據存儲層,主要是將數據存儲在運行於裸設備的文件系統之上,並完成與存儲引擎的交互。
8. MySQL存儲引擎
8.1. 查看命令
- 查看mysql現在已經提供什麼樣的存儲引擎:
mysql> show engines;
- 查看mysqll當前默認的存儲引擎:
mysql> show variables like '%storage_engine%';
8.2. 各個引擎簡介
-
InnoDB存儲引擎
InnoDB是MySQL的默認事務型引擎,它被設計用來處理大量的短期(short-lived)事務。除非有非常特別的原因需要使用其他的存儲引擎,否則應該優先考慮InnoDB引擎。行級鎖,適合高併發情況 -
MyISAM存儲引擎
MyISAM提供了大量的特性,包括全文索引、壓縮、空間函數(GIS)等,但MyISAM不支持事務和行級鎖(myisam改表時會將整個表全鎖住),有一個毫無疑問的缺陷就是崩潰後無法安全恢復。 -
Archive引擎
Archive存儲引擎只支持INSERT和SELECT操作,在MySQL5.1之前不支持索引。
Archive表適合日誌和數據採集類應用。適合低訪問量大數據等情況。
根據英文的測試結論來看,Archive表比MyISAM表要小大約75%,比支持事務處理的InnoDB表小大約83%。 -
Blackhole引擎
Blackhole引擎沒有實現任何存儲機制,它會丟棄所有插入的數據,不做任何保存。但服務器會記錄Blackhole表的日誌,所以可以用於複製數據到備庫,或者簡單地記錄到日誌。但這種應用方式會碰到很多問題,因此並不推薦。 -
CSV引擎
CSV引擎可以將普通的CSV文件作爲MySQL的表來處理,但不支持索引。
CSV引擎可以作爲一種數據交換的機制,非常有用。
CSV存儲的數據直接可以在操作系統裏,用文本編輯器,或者excel讀取。 -
Memory引擎
如果需要快速地訪問數據,並且這些數據不會被修改,重啓以後丟失也沒有關係,那麼使用Memory表是非常有用。Memory表至少比MyISAM表要快一個數量級。(使用專業的內存數據庫更快,如redis) -
Federated引擎
Federated引擎是訪問其他MySQL服務器的一個代理,儘管該引擎看起來提供了一種很好的跨服務器的靈活性,但也經常帶來問題,因此默認是禁用的。
8.3. MyISAM和InnoDB(重點了解)
對比項 | MyISAM | InnoDB |
---|---|---|
主外鍵 | 不支持 | 支持 |
事務 | 不支持 | 支持 |
行表鎖 | 表鎖,即使操作一條記錄也會鎖住整個表,不適合高併發的操作 | 行鎖,操作時只鎖某一行,不對其它行有影響,適合高併發的操作 |
緩存 | 只緩存索引,不緩存真實數據 | 不僅緩存索引還要緩存真實數據,對內存要求較高,而且內存大小對性能有決定性的影響 |
表空間 | 小 | 大 |
關注點 | 性能 | 事務 |
默認安裝 | Y | Y |
用戶表默認使用 | N | Y |
自帶系統表使用 | Y | N |
注:MyISAM主要關注性能,因爲其查詢速度快。
innodb 索引 使用 B+TREE myisam 索引使用 b-tree
innodb 主鍵爲聚簇索引,基於聚簇索引的增刪改查效率非常高。
8.4. 阿里巴巴、淘寶使用
-
Percona 爲 MySQL 數據庫服務器進行了改進,在功能和性能上較 MySQL 有着很顯著的提升。該版本提升了在高負載情況下的 InnoDB 的性能、爲 DBA 提供一些非常有用的性能診斷工具;另外有更多的參數和命令來控制服務器行爲。
-
該公司新建了一款存儲引擎叫xtradb完全可以替代innodb,並且在性能和併發上做得更好,
阿里巴巴大部分mysql數據庫其實使用的percona的原型加以修改。AliSql+AliRedis
9. SQL執行順序(重點了解)
sql語句的執行順序可通過下圖瞭解,注意sql是從from開始執行的。