層次模型 --> 網狀模型 --> (IBM Codd)關系模型 --> No-SQL關系型數據庫管理系統(RDBMS):范式:第一范式,第二范式,第三范式;表:二維表;Row:Record,記錄;Column:Field,字段;描述每個記錄的特定屬性;任何一張RDBMS的表中,可以沒有任何Row,但至少應該有一個Column;對表的操作:關系運算:選擇:從指定的表中檢索符合條件的行;SELECT * FROM tbl_name WHERE clause;投影:從指定的表中檢索符合條件的列;SELECT column1,column2,column3 as column3_alias FROM tbl_name;注意:可以同時實現選擇和投影的關系運算操作;SELECT column1,column2,column3 as column3_alias FROM tbl_name WHERE clause;數據庫:表,索引,視圖(虛表),SQL_interface,存儲過程,存儲函數,觸發器,事件調度器;DDLDML約束:主鍵約束:數據唯一且不能為空,每張表只能有一個主鍵;唯一鍵約束:數據唯一,可以為空,每張表中不限制唯一鍵的數量;外鍵約束:引用性約束或參考性約束;即:如果某表中頻繁出現冗余信息,應該將此類信息存儲于其他的表中,而此表中該字段的數據為另一張表的主鍵中所包含的值;檢查性約束:表達式約束;DBMS的三層模型:視圖層;面向最終用戶;邏輯層;面向程序員或DBA;物理層;面向系統管理員;RDBMS的應用實現:商業版:Oracle,DB2,Sybase,Infomix,SQL Server,MySQL;開源版:MySQL Community Server,MariaDB,PostgreSQL,SQLlite;MySQL/MariaDB:MySQL:5.1 --> 5.5 --> 5.6 --> 5.7 --> 8.0 --> 8.0.11 (mysql shell, mysqlsh)MariaDB:5.5.x --> 10.x特性:插件式的存儲引擎:存儲引擎于MySQL/MariaDB而言,也被稱為"表類型";MyISAM,InnoDB,XtraDB(InnoDB),Aria,BlackHole,...單進程多線程;在Linux(CentOS)中安裝MySQL/MariaDB的方式:1.rpm包:OS VendorThird Side官方;2.Binary Package:OS:Linux、windowsArch:i686,x86_64,ppc,...Glibc:msyql-linux-glibc214Init/Systemd:Systemd3.SourceCode Package:mysql/mariadb-Version.tar.gzcmake配置文件:位于不同位置的多個配置文件,通常按照一定的順序來讀取其中的配置參數:Default options are read from the following files in the given order:/etc/mysql/my.cnf /etc/my.cnf /etc/my.cnf.d ~/.my.cnf已經被指定順序的配置中如果出現同一配置參數且具有不同的值,最后讀取的文件中的參數值將成為最終生效的參數值;在使用mysqld_safe命令啟動mysqld服務進程時,可以通過一些選項來更改或附加配置文件的讀取順序;-c, --defaults-file=name Like --config-file, except: if first option, then readthis file only, do not read global or per-user configfiles; should be the first option如果在命令行中給出此選項,則此選項必須是第一個選項,此時,僅從此選項指定的配置文件中讀取參數值,不會再讀取任何其他的配置文件,包括全局的和個人的;-e, --defaults-extra-file=name Read this file after the global config file and beforethe config file in the users home directory; should bethe first option如果在命令行中給出此選項,則此選項必須是第一個選項,此時,將所有其他的配置文件按照指定順序讀取完成之后,最后再附加讀取此選項指定的配置文件中參數值配置,只要有參數配置沖突,則必然以此選項指定的文件中的參數中為最終生效的參數值;配置文件的風格:ini風格的配置文件;即:分段式配置文件;為MySQL的各應用程序提供與之對應的配置參數信息:服務器端應用程序:[server]socket=datadir=basedir=[mysqld]socket=[mysqld_safe]socket=[mysqld_multi]客戶端應用程序:[client]user=password=host=[mysql]user=password=host=[mysqladmin][mysqldump]配置文件中各參數的定義方法:PARAMETER_NAME = VALUEPARAMETER_NAME=VALUEPARAMETER_NAMEinnodb_file_per_table = ONinnodb-file-per-table = ONdefaults-file=/tmp/my.cnfdefaults_file=/tmp/my.cnfskip_name_resolve=ONskip_name_resolve程序環境:程序文件:服務器端程序:mysqld_safe、mysqld_multi客戶端程序:msyql、mysqladmin、mysqldump、...服務器端輔助管理工具程序:myisam*、my_print_defaults、mysql_secure_installation、mysql_install_db、...mysql:交互式命令行工具和非交互式命令行工具;-u, -h, -p, -P, -D, -S, -e交互式模式:客戶端命令:?(\?,\h), \c, \d, \g, \G, \q, \., \!, \s, \u, ... 服務器端命令:SQL語句,需要使用語句結束符;help COMMANDDDL:CREATE、DROP、ALTER、SHOW;DML:SELECT、INSERT、UPDATE、DELETE;DCL:GRANT、REVOKE;mysql命令支持mysql腳本的執行:mysql [options] [DB_NAME] < /PATH/TO/SOME_SQL_SCRIPT_FILE mysqladmin命令:mysqladmin - client for administering a MySQL server常用選項:-u, -h, -p, -P, -D, -S各選項功能同mysql命令的選項功能;常用子命令:create db_name:創建數據庫;drop db_name:刪除數據庫;flush-hosts:清除服務器緩存中所有信息;flush-logs:清除日志,讓日志滾動;flush-privileges:刷新授權表;flush-tables:為表加鎖;password new-password:為指定的用戶設置新密碼;start-slave:在msyql的集群服務中的從節點啟動用于實施復制功能的線程;stop-slave:在msyql的集群服務中的從節點關閉用于實施復制功能的線程;shutdown:停止服務;mysqld_safe命令:用于啟動mysql服務,定義mysql的工作特性;格式:/usr/bin/mysqld_safe [OPTIONS]注意:所有給出的 OPTION(--option)都是一次性生效;如果期望配置參數永久有效,需要將此類配置參數及參數值直接定義在配置文件中即可;服務器運行時變量/服務器運行時參數:MySQL的運行工作特性;這里特性有兩種:1.全局特性:在全局范圍均有效的服務器參數所配置定義的工作特性;將會作為每個mysql的會話連接的默認特性參數;2.會話特性:僅針對于本次mysql的連接會話生效的特性參數;查看已經生效的mysql運行參數(特性,變量)SHOW [GLOBAL | SESSION] VARIABLES [like_or_where]示例:show [global] variables like '%innodb%';查看所有名字中包含innodb字樣的服務器參數及參數值;可以一次顯示多個;show [global] variables like 'innodb_file_per_table';僅查看指定名稱的服務器參數的參數值;select @@[global.]innodb_file_per_table;僅查看指定名稱的服務器參數的參數值;服務器狀態參數/服務器狀態變量:MySQL工作時的統計信息;有兩種狀態參數:1.全局2.會話查看與狀態及統計信息相關的參數/變量的值;SHOW [GLOBAL | SESSION] STATUS [like_or_where]示例:show [global] status like '%innodb%';查看所有名字中包含innodb字樣的服務器狀態參數及其值;可以一次顯示多個;show [global] staus like 'Com_select';僅查看指定名稱的服務器狀態參數的值;服務器變量/服務器參數的修改或調整方法:1.運行時修改:MariaDB [(none)]> SET [GLOBAL|SESSION] system_var_name = expr;MariaDB [(none)]> SET @@[GLOBAL.|SESSION.]system_var_name = expr;示例:set global innodb_file_per_table=1;set @@global.innodb_file_per_table=0;2.永久修改:通過在配置文件中直接書寫服務器參數或變量的賦值語句;重啟服務即可生效;innodb_file_per_table = ONmysql_secure_installation:安全初始化腳本;
修改數據庫的字符集或排序規則:ALTER {DATABASE | SCHEMA} [db_name] [DEFAULT] [CHARACTER SET [=] charset_name | [DEFAULT] COLLATE [=] collation_name]刪除數據庫:DROP {DATABASE | SCHEMA} [IF EXISTS] db_name使用客戶端命令創建數據庫:~]# mysqladmin create mydb~]# mysql -e "create database mydb;"使用客戶端命令刪除數據庫:~]# mysqladmin drop mydb //會對刪除數據庫的操作進行確認;~]# mysql -e "drop database mydb;"表:創建表:CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name(create_definition,...)[table_options][partition_options]//使用SQL語句全新的定義出一張新表,包括表的名稱、字段數量、數據類型、存儲引擎的選擇等各種屬性;Or:CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name[(create_definition,...)][table_options][partition_options]select_statement//利用SELECT語句的查詢結果來填充新表的內容,但是新表的表格式可能與基表不一致,很多的數據類型的修飾符可能會丟失;Or:CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name{ LIKE old_tbl_name | (LIKE old_tbl_name) }//直接復制基本的表格式到新表上,但新表中沒有任何數據,即為空表;注意:1.對于MySQL或MariaDB的表來說,存儲引擎是非常重要的概念,通常需要在創建表的時候來指定;如果沒有明確指定,則使用默認的存儲引擎;2.對于已經創建完成的空表,可以任意調整其存儲引擎;3.對于非空表,不建議直接修改表的存儲引擎;良心建議:在創建表之初或者存儲數據之前,確定表的存儲引擎;刪除表:DROP [TEMPORARY] TABLE [IF EXISTS] tbl_name [, tbl_name] ... [RESTRICT | CASCADE]建議:使用修改表名稱的方式使指定表不再被繼續使用;修改表格式:ALTER [ONLINE | OFFLINE] [IGNORE] TABLE tbl_name [alter_specification [, alter_specification] ...]可以修改的內容:ADD:字段,索引,約束,鍵(主鍵,唯一鍵,外鍵)CHANGE:字段名稱,字段定義格式和字段的位置;MODIFY:字段定義格式和字段的位置;DROP:字段,索引,約束,鍵;RENAME:修改表名稱;查看表結構:DESC [db_name.]tbl_name;查看表的定義方式:SHOW CREATE TABLE tbl_name;查看表的狀態和屬性信息:SHOW TABLE STATUS [from | in db_name] like 'PATTERN' | where expr;示例:MariaDB [hellodb]> show table status where name='students'\G視圖:VIEW,虛表;就是一個SELECT語句的執行結果;創建視圖:CREATE VIEW view_name [(column_list)] AS SELECT clause;示例:MariaDB [hellodb]> create view student as select StuID,Name,Gender from students;刪除視圖:DROP VIEW [IF EXISTS] view_name [, view_name] ... [RESTRICT | CASCADE]示例:MariaDB [hellodb]> drop view student;注意:能否在視圖中實現插入新的數據記錄,取決于基表中沒有被視圖選擇的字段是否要求不能為空,如果有此類約束,則結果是無法插入新數據;否則可以插入新數據,沒有被視圖選擇的字段內容,默認都為"NULL";索引:索引的類型:聚集索引、非聚集索引:聚集索引:索引和數據存放在一起,找到索引即找到數據;非聚集索引:索引和數據不存放在一起,索引通過索引指針指向數據所在位置;稠密索引、稀疏索引:是否索引了每一條數據記錄;稠密索引:每條數據記錄都有一條索引與之對應;稀疏索引:并不是每條數據記錄都有一條索引與之對應,而是一條索引對應某個或某些數據塊;主鍵索引、輔助索引:BTree:Balance Tree,B- Tree,BTree,B+Tree左前綴索引:注意:在使用BTree索引進行檢索時,給出的PATTERN的最左側字符不要出現通配符,否則,無法使用索引進行檢索;只能全文遍歷;Hash索引:R Tree:Spacial,空間索引;FULLTEXT:全文索引;覆蓋索引:索引中的內容就是要檢索的內容,通過檢索索引內容即可立即找到數據,并直接返回檢索結果;EXPLAIN:分析查詢語句的執行路由;創建索引:1.在創建表時,通過指定主鍵或唯一鍵,可以自動創建索引;2.如果在創建表時,沒有指定主鍵或唯一鍵,則可以在表成功創建之后添加索引;CREATE [ONLINE|OFFLINE] [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name [index_type] ON tbl_name (index_col_name,...) [index_option] ...示例:MariaDB [hellodb]> create index name_index on students(Name);查看索引:SHOW {INDEX | INDEXES | KEYS} {FROM | IN} tbl_name [{FROM | IN} db_name] [WHERE expr]示例:MariaDB [hellodb]> show index from students\G刪除索引:DROP [ONLINE|OFFLINE] INDEX index_name ON tbl_name示例:MariaDB [hellodb]> drop index name_index on students;DML:操縱數據;INSERT/REPLACE、DELETE、UPDATE、SELECEINSERT:向表中插入新的數據記錄;每次可以向表中插入一行或多行數據;INSERT [INTO] tbl_name [(col_name,...)] {VALUES | VALUE} ({expr | DEFAULT},...),(...),...示例:MariaDB [hellodb]> insert into students (Name,Age,Gender) values ('Rio Messi',31,'M');MariaDB [hellodb]> insert into students (Name,Age,Gender) values ('Guo Jing',40,'M'),('Huang Rong',27,'F');沒有明確的規定字段名稱,則意味著為一行中的各個字段添加數據內容:MariaDB [hellodb]> insert into students values (30,'Liu Bei',57,'M',1,2);注意:添加的數據內容,必須要嚴格的對應每個數據字段,需要保證數據類型的匹配;INSERT [INTO] tbl_name SET col_name={expr | DEFAULT}, ...示例:MariaDB [hellodb]> insert into students set Name='Tang Xuanzang',Age=35,Gender='M';INSERT [INTO] tbl_name [(col_name,...)] SELECT ...將后面SELECT語句的查詢結果插入到選中的目標表中;注意下列問題:1.SELECT語句的查詢結果中包含的字段數量,應該和目標表中的指定字段數量相同;2.SELECT語句的查詢結果中包含的各字段的數據類型,必須要與目標表中各字段的數據類型保持一致;此種插入數據的方法,更多的用于表復制操作;此前曾經使用CREATE TABLE命令通過復制表格式的方式創建過一個空的新表,然后再將原表中的數據以方法復制到新表中;REPLACE命令與INSERT命令的功能幾乎完全相同,除了一種特殊情況之外:當向表中插入數據時,如果主鍵位置或唯一鍵位置出現重復數據時,不會繼續插入而是選擇替換對應行中各字段的數據;DELETE:Single-table syntax:DELETE FROM tbl_name [WHERE where_condition] [ORDER BY ...] [LIMIT row_count]Multiple-table syntax:DELETE tbl_name[.*] [, tbl_name[.*]] ... FROM table_references [WHERE where_condition]Or:DELETE FROM tbl_name[.*] [, tbl_name[.*]] ... USING table_references [WHERE where_condition]注意:默認情況下,MySQL或MariaDB都不會阻止不帶有WHERE條件子句的刪除操作,這將意味著,有可能會因為此操作導致清空整張表中的數據;限制條件:WHERE where_conditionLIMIT row_countORDER BY ... LIMIT row_countWHERE where_condition LIMIT row_countWHERE where_condition ORDER BY ... LIMIT row_count示例:MariaDB [hellodb]> delete from students limit 3;刪除正常的查詢結果中的前三行數據記錄;MariaDB [hellodb]> delete from students where Age<20;刪除Age字段中值小于20的所有數據記錄;MariaDB [hellodb]> delete from students where Name like 'h%' limit 2;刪除Name字段以"H|h"開頭的所有數據記錄中的前兩條記錄;MariaDB [hellodb]> delete from students order by age desc limit 3;刪除根據Age字段進行降序排序的查詢結果中的前三條數據記錄;UPDATE:Single-table syntax:UPDATE table_reference SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ... [WHERE where_condition] [ORDER BY ...] [LIMIT row_count]Multiple-table syntax:UPDATE table_references SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ... [WHERE where_condition]注意:默認情況下,MySQL或MariaDB都不會阻止不帶有WHERE條件子句的修改操作,這將意味著,有可能會因為此操作導致整張表中的所有數據記錄被同時修改;限制條件:WHERE where_conditionLIMIT row_countORDER BY ... LIMIT row_countWHERE where_condition LIMIT row_countWHERE where_condition ORDER BY ... LIMIT row_count示例:同DELETE的示例;注意:在MySQL或MariaDB中,如果服務器變量sql_safe_updates=ON,則可以阻止不帶有限制條件的UPDATE更新操作或DELETE刪除操作;臨時調整:MariaDB [hellodb]> set @@sql_safe_updates=ON;永久生效:/etc/my.cnfsql_safe_updates=ONMariaDB [hellodb]> update students set ClassID=1;ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY columnSELECTQuery Cache:MySQL/MariaDB的查詢結果緩存;K/V對存儲;Key:查詢語句經過hash之后的hash值;Value:查詢語句的執行結果;MySQL/MariaDB的查詢執行路徑:1.用戶發送請求 --> 查詢緩存(命中) --> 響應用戶;2.用戶發送請求 --> 查詢緩存(未命中) --> 解析器 --> 預處理器 --> [查詢優化器 -->] 查詢執行引擎 --> 存儲引擎 --> 查詢執行引擎 --> [緩存查詢結果 -->] 響應用戶;SELECT[ALL | DISTINCT | DISTINCTROW ][SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]select_expr [, select_expr ...][FROM table_references[WHERE where_condition][GROUP BY {col_name | expr | position}[ASC | DESC], ... [WITH ROLLUP]][HAVING where_condition][ORDER BY {col_name | expr | position}[ASC | DESC], ...][LIMIT {[offset,] row_count | row_count OFFSET offset}][PROCEDURE procedure_name(argument_list)][INTO OUTFILE 'file_name'[CHARACTER SET charset_name]export_options| INTO DUMPFILE 'file_name'| INTO var_name [, var_name]][FOR UPDATE | LOCK IN SHARE MODE]]DISTINCT:數據去重;即:重復出現的數據僅顯示一次;SQL_CACHE:顯式的指出必須將此次的查詢語句的執行結果存放至查詢緩存;SQL_NO_CACHE:顯式的指出絕對不能將此次的查詢語句的執行結果存放至查詢緩存;query_cache_type服務器變量是MySQL的緩存開關,通常有三個取值:1.ON:啟用緩存功能;默認緩存所有符合緩存條件的查詢結果;除非使用SQL_NO_CACHE參數明確指出不緩存查詢結果;2.OFF:關閉緩存功能;默認不緩存任何查詢結果;僅能緩存使用SQL_CACHE參數明確的指出的查詢結果;3.DEMAND:按需緩存;如果明確指出SQL_CACHE,即緩存查詢結果,否則,默認隱式關閉查詢緩存;query_cache_limit | 1048576query_cache_min_res_unit | 4096select_expr:*:表示表中的所有字段(列);col1,col2,...coln:普通的列名列表;通常用于執行投影運算;col_name1 as col_alias1,col_name2 as col_alias2, ...對于查詢結果中的各字段名稱使用別名進行重定義;table_references:[db_name.]tbl_namedb_name.*[db_name.]tbl_name1,[db_name.]tbl_name2, ...[db_name.]tbl_name1 as tbl_alias1,[db_name.]tbl_name2 as tbl_alais2, ...單表查詢:select select_expr1,select_expr2,... from tbl_name where expr group by col_name having expr order by col_name limitWHERE條件子句:通過指明特定的過濾條件或表達式來實現"選擇"運算;過濾條件有下列幾種:1.算術表達式:Age+10,算術操作符:+, -, *, /, %;2.比較表達式:Age+10<20;比較操作符:=, <=>, <>, !=, >, >=, <, <=;3.邏輯表達式:邏輯操作符:AND, OR, NOT, XOR;4.其他表達式:空值判斷:IS NULL, IS NOT NULL;連續區間判斷:BETWEEN ... AND ... 相當于<=100 AND >=50;列表從屬關系判斷:IN (LIST);模糊值判斷:LIKE:可以支持通配符,%和_;如果想要使用索引實現加速檢索,則最左側字符不能使用通配符;RLIKE或REGEXP:可以支持正則表達式元字符;只要在查詢條件中包含正則表達式元字符,則一定無法使用索引進行檢索;功能很強大,但檢索性能可能變差;GROUP BY子句:根據指定的字段將查詢結果進行分組歸類,以方便進行聚合運算;常用的聚合運算函數:avg():取平均值運算;max():取最大值運算;min():取最小值運算;sum():做和運算;count():做次數統計;示例:統計每個班級里面的人數:MariaDB [hellodb]> select ClassID,count(ClassID) as nos from students group by ClassID;統計每個班級里面所有人的平均年齡:MariaDB [hellodb]> select ClassID,avg(Age) as nos from students where ClassID is not null group by ClassID;統計所有學生中男生和女生的平均年齡:MariaDB [hellodb]> select Gender,avg(Age) as nos from students group by Gender;HAVING子句:對于經過分組歸類并進行了聚合運算以后的結果進行條件過濾;其條件表達式的書寫格式與WHERE子句相同;示例:統計人數超過3人的班級及其人數數據:MariaDB [hellodb]> select ClassID,count(ClassID) as nos from students where ClassID is not null group by ClassID having nos>=3;ORDER BY子句:根據指定的字段將查詢結果進行排序,可以使用升序或降序,默認是升序;升序:ASC降序:DESC示例:MariaDB [hellodb]> select ClassID,count(ClassID) as nos from students where ClassID is not null group by ClassID having nos>=3 order by nos desc;LIMIT子句:對于查詢的結果進行限定行數的輸出;LIMIT {[offset,] row_count | row_count OFFSET offset}1.LIMIT [offset,] row_countoffset:偏移量,在輸出結果中,從第一行開始(含)跳過的不顯示的行數;row_count:要顯示的行數;示例:顯示查詢結果中的第二行和第三行;MariaDB [hellodb]> select ClassID,count(ClassID) as nos from students where ClassID is not null group by ClassID having nos>=3 order by nos desc limit 1,2;2.LIMIT row_count OFFSET offset示例:顯示查詢結果中的第二行和第三行;MariaDB [hellodb]> select ClassID,count(ClassID) as nos from students where ClassID is not null group by ClassID having nos>=3 order by nos desc limit 2 offset 1;多表查詢:建議:在生成環境中,能使用單表查詢即可得到結果的操作,盡可能使用單表查詢;因為多表查詢會給服務器造成過大的負載壓力;所謂多表查詢,即指通過對多個表內容的查詢,以獲得具有一定關聯關系的查詢結果的查詢方式;也稱為連接操作,連接操作也就是將多張表關聯在一起的方法;連接操作:交叉連接:也稱為笛卡爾積連接;內連接:等值連接:讓表和表之間通過某特定字段的等值判斷的方式建立的內連接;非等值連接:讓表和表之間通過某特定字段的不等值判斷的方式建立的內連接;在極少的場合中才有應用;外連接:以某張為基準表,判斷參考表與基準表之間的連接關系;左外連接:以左表為基準表,右表為參考表,顯示出基準表中所有的行,并將參考表中與基準表中有關聯關系的行合并輸出,如果基準表中的行與參考表中無關,則輸出NULL;連接操作符:LEFT JOIN右外連接:以右表為基準表,左表為參考表,顯示出基準表中所有的行,并將參考表中與基準表中有關聯關系的行合并輸出,如果基準表中的行與參考表中無關,則輸出NULL;連接操作符:RIGHT JOIN自然連接:通過MySQL的進程自行判斷并完成的連接過程。通常MySQL會使用表中的名稱相同的字段作為基本的連接條件;連接操作符:NATRUAL INNER自然外連接:自然左外連接:連接操作符:NATURAL LEFT JOIN自然右外連接:連接操作符:NATURAL RIGHT JOIN自連接:人為的將一張表中的兩個字段之間建立的連接關系;示例:交叉內連接:每個學生所在的班級名稱:MariaDB [hellodb]> select Name,Class from students as s,classes as c where s.CLassID=c.ClassID;MariaDB [hellodb]> select Name,Class from students,classes where students.CLassID=classes.ClassID;交叉左外連接:每個學生所在班級的名稱,即使該學生不屬于任何班級:MariaDB [hellodb]> select Name,Class from students left join classes on students.CLassID=classes.ClassID;交叉右外連接:每個班級的學生姓名,即使該班級中沒有任何學生;MariaDB [hellodb]> select Class,Name from students right join classes on students.ClassID=classes.ClassID;||MariaDB [hellodb]> select Class,Name from classes left join students on students.ClassID=classes.ClassID;子查詢:嵌套查詢;在SELECT查詢語句中嵌套另一個SELECT查詢語句;等同于從某個視圖中獲取查詢結果;SELECT col1,col2,* FROM tbl_name WHERE col OPTS VALUE;示例:用于WHERE子句中的子查詢:查詢學生中年齡大于全班平均年齡的學生的姓名和年齡;MariaDB [hellodb]> select Name,Age from students where Age>(select avg(Age) from students);用于IN子句中的子查詢:查詢學生的年齡和老師的年齡相同的學生的名字:MariaDB [hellodb]> select Name from students where Age in (select Age from teachers);查詢學生的年齡和老師的年齡相同的學生和老師的名字:MariaDB [hellodb]> select t.Name as Teacher,s.Name as Student from students as s,teachers as t where s.Age=t.Age;用于FROM子句的子查詢:查詢有班級的學生對應的班級名稱:MariaDB [hellodb]> select s.Name,s.Class from (select StuID,students.Name,students.Age,Gender,Class from students,classes where students.ClassID=classes.ClassID) as s;聯合查詢:將多張表的內容通過多個SELECT語句查詢得到的結果組合輸出;注意:使用聯合查詢的前提條件:多張表需要有相同數據類型的字段;操作符:UNION示例:MariaDB [hellodb]> select StuID as ID,Name,Age,Gender from students union select TID as ID,Name,Age,Gender from teachers;select查詢:單表查詢 --> 多表查詢(交叉內連接) --> 多表查詢(外連接) --> 子查詢 --> 聯合查詢;MySQL的用戶和權限管理:用戶賬號:'Username'@'Hostname'skip_name_resolve = ON'user'@'172.16.0.1''user'@'a.qhdlink.com'skip_name_resolve = OFFClient_IP --> Client_Hostname在MySQL上能夠實施的用戶賬戶的管理操作:CREATE USERDROP USERGRANTRENAME USERREVOKESET PASSWORDMySQL中的權限類別:庫級別;表級別;字段級別;管理類;程序類;管理類的權限:CREATE USERDROP USERRELOADLOCK TABLESREPLICATION CLIENTREPLICATION SLAVESHUTDOWNFILESHOW DATABASESPROCESSSUPER程序類的權限:FUNCTIONPROCEDURETRIGGER操作:CREATE,ALTER,DROP,EXECUTE庫級別和表級別的權限:CREATEALTERSHOWDROPINDEXCREATE VIEWSHOW VIEWGRANT OPTION:能夠將管理員自身獲得的權限生成一個副本,并轉贈給目標用戶;表級別的數據操作的權限:INSERTREPLACEDELETEUPDATESELECT字段級別(列級別)的數據操作的權限:SELECT(col1,col2,...)UPDATE(col1,col2,...)INSERT(col1,col2,...)所有的權限:ALLALL PRIVILEGESMySQL的元數據數據庫:mysql數據字典數據庫;hostdbusercolumn_privprocs_privproxies_privetables_priv上述元數據數據庫中的表統稱為"授權表";如果對于授權表的內容進行了修改,MySQL每300秒會自動重讀并使新設置生效;如果不打算等待,可以手動刷新授權表:MariaDB [mysql]> FLUSH PRIVILEGES;MySQL用戶管理:'Username'@'Hostname'Username:任意的字符串組合,只能包含基本意義的字符;可以包含"_"、"."、"-";Hostname:FDQNDomain_nameIP_ADDRESS可以使用MySQL的專用通配符:%, _skip_name_resolve={ON|OFF}創建用戶賬戶:CREATE USER語句:CREATE USER user [IDENTIFIED BY [PASSWORD] 'password' | IDENTIFIED WITH auth_plugin [AS 'auth_string']]示例:MariaDB [mysql]> create user 'testuser'@'%';MariaDB [mysql]> create user 'testuser'@'%' identified by 'qhdlink';也可以使用DML語句創建用戶賬戶:INSERT INTO mysql.user SET User='testuser',Host='%',Password=PASSWORD('qhdlink');示例:MariaDB [mysql]> insert into user set User='user1',Host='%',Password=PASSWORD('qhdlink'),ssl_cipher='',x509_issuer='',x509_subject='',authentication_string='';重命名用戶賬戶:RENAME USER語句:RENAME USER old_user TO new_user [, old_user TO new_user] ...示例:MariaDB [mysql]> rename user 'testuser'@'%' to 'test'@'172.16.%.%';也可以使用DML語句重命名用戶賬戶:示例:MariaDB [mysql]> update user set User='user01',Host='172.16.75.%' where User='user1';刪除用戶賬戶:DROP USER語句:DROP USER user [, user] ...示例:MariaDB [mysql]> drop user 'test'@'172.16.%.%';也可以使用DML語句刪除用戶賬戶:示例:MariaDB [mysql]> delete from user where User='user01';用戶賬戶的密碼管理:1.SET PASSWORD語句:SET PASSWORD [FOR user] = { PASSWORD('cleartext password') | OLD_PASSWORD('cleartext password') | 'encrypted password' }示例:MariaDB [mysql]> set password for 'test'@'%' = PASSWORD('qhdlink');2.也可以使用DML語句修改用戶賬戶密碼:示例:MariaDB [mysql]> update user set Password=PASSWORD('qhdlink.com') where User='test';3.mysqladmin工具:# mysqladmin -uUSERNAME -hHOSTNAME -p password 'NEW_PASSWORD'注意:執行此操作的MySQL用戶需要對mysql.user表有修改權限;忘記MySQL管理員的密碼的解決辦法:方法一:1.停止當前的MySQL或MariaDB服務;2. 在/etc/my.cnf文件中加入下列兩條服務器參數:skip-grant-tables = ONskip-networking = ON3.啟動MySQL或MariaDB服務,使用mysql或mysqladmin客戶端工具以空秘密的root用戶登錄,進行root用戶的密碼修改;4.從/etc/my.cnf中刪除上述兩條服務器參數,再重啟服務即可;方法二:1.停止當前的MySQL或MariaDB服務;2.使用命令啟動MySQL服務:# mysqld_safe --skip-grant-tables --skip-networking3.啟動另一個會話連接,并使用mysql或mysqladmin客戶端工具以空密碼的root用戶的身份修改其密碼;4.kill掉此前的mysqld-safe及衍生的mysqld服務;5.再正常啟動服務即可;對于已經建立的用戶或未建立的用戶進行授權:GRANT語句:GRANT priv_type [(column_list)] [, priv_type [(column_list)]] ...ON [object_type] priv_levelTO user_specification [, user_specification] ...[REQUIRE {NONE | ssl_option [[AND] ssl_option] ...}][WITH with_option ...]priv_type:SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, RELOAD, REPLICATION CLIENT, REPLICATION SLAVE, SHUTDOWN, FILE, SHOW DATABASES, PROCESS, SUPERobject_type:TABLE | FUNCTION | PROCEDUREpriv_level:* | *.* | db_name.* | db_name.tbl_name | tbl_name | db_name.routine_name*:表示所有的數據庫;*.*:表示所有數據庫中的所有表對象;db_name.*:表示指定數據庫中的所有表對象;db_name.tbl_name:表示指定數據庫中的指定的表對象;tbl_name:表示當前正在使用的數據庫中的指定的表對象;db_name.routine_name:表示指定數據庫中的指定存儲函數后存儲過程對象;通常需要使用object_type參數共同決定;user_specification:user [ IDENTIFIED BY [PASSWORD] 'password' | IDENTIFIED WITH auth_plugin [AS 'auth_string' ] ]ssl_option:SSL | X509 | CIPHER 'cipher' | ISSUER 'issuer' | SUBJECT 'subject'with_option:GRANT OPTION | MAX_QUERIES_PER_HOUR count | MAX_UPDATES_PER_HOUR count | MAX_CONNECTIONS_PER_HOUR count | MAX_USER_CONNECTIONS count示例:MariaDB [mysql]> grant all privileges on hellodb.* to 'test'@'%';MariaDB [mysql]> grant select,update on hellodb.students to 'test'@'%';MariaDB [mysql]> grant select(Name,Age,ClassID) on hellodb.students to 'test'@'%';也可以對某些基本表創建視圖之后,再對視圖進行用戶權限授權:MariaDB [hellodb]> create view stu_base as select Name,Age,ClassID from students;MariaDB [hellodb]> grant all on hellodb.stu_base to 'test'@'%';取消授權/收回授權:REVOKE語句:REVOKE priv_type [(column_list)] [, priv_type [(column_list)]] ...ON [object_type] priv_levelFROM user [, user] ...REVOKE ALL PRIVILEGES, GRANT OPTIONFROM user [, user] ...示例:MariaDB [mysql]> revoke delete on hellodb.* from 'test'@'%';MariaDB [mysql]> revoke all on hellodb.students from 'test'@'%';MariaDB [mysql]> revoke select(Age,ClassID) on hellodb.students from 'test'@'%';注意:在取消已經做出的授權時,REVOKE語句所指定的priv_level部分應該和授權時GRANT語句所指定的priv_level保持絕對一致;否則判定此次取消授權的操作失敗;示例:前提是testdb數據庫中包含有tb1和tb2兩張表;MariaDB [testdb]> grant all on testdb.* to 'test'@'%';MariaDB [testdb]> revoke all on testdb.tb2 from 'test'@'%';ERROR 1147 (42000): There is no such grant defined for user 'test' on host '%' on table 'tb2'正確的取回授權的方式:MariaDB [testdb]> revoke all on testdb.* from 'test'@'%';MariaDB [testdb]> grant all on testdb.tb1 to 'test'@'%';此時,'test'@'%'用戶就只有對testdb數據庫中tb2表有所有操作權限;查看用戶的授權:SHOW GRANTS語句:SHOW GRANTS [FOR user]