###############################################################################
第1~3章:理解SQL、MariaDB入門、讓MariaDB運行起來
DBMS-數據庫管理系統(Database Management System):
基於共享文件系統的非關係型數據庫、基於客戶端/服務器的關係型數據庫
Mariadb 基於Mysql5的代碼庫
主鍵(primary key):主鍵是數據表的唯一索引,比如學生表裏有學號和姓名,姓名可能有重名的,但學號確是唯一的。數據庫中必須定義主鍵。
describe table; --等價於 show columns from tables;
SQL語句中額外的空格,包括換行會被忽視。因此一條語句可以很長也可以分行。
在沒有use特定的database下,可以用.來完全限定database和table來訪問,如
select user from mysql.user;
註釋:
--xxxx; 內嵌註釋 # 開頭註釋; /* xxxx */ 長註釋
###############################################################################
第4章:檢索數據
檢索:
select 列名,列名 from table;
檢索不同列:
distinct
檢索限定行數:
limit 1 offset 2 / limit 2,1
###############################################################################
第5章:對檢索數據排序
排序:
order by 列名1,列名2 -- 以列名1排序,當列名1相同,以列名2排序。
默認升序,用關鍵字DESC降序。
默認不區分大小。若要做到區分大小寫,要修改列字符集,convert()函數
###############################################################################
第6章 過濾數據
過濾
where 列名=xxxx
字符串用
where 列名=‘’
數字比較>,<,>=,<=,=,!=,between and
特殊的 where 列名 is null
提示:雖然也可以從數據庫取出所有數據後,在應用程序過濾數據。但是不提倡,因爲用數據庫來過濾比較高效,且不需要把所有數據發送給應用程序(浪費帶寬)
警告:需要where過濾後纔可以排序,否則會語法錯誤。
###############################################################################
第7章 高級過濾數據
where 配合and,or,not使用,可以用括號指明優先級,還有
where 列名 in (xx,yy)
###############################################################################
第8章 使用通配符過濾
where 列名 like ‘xx%xx%’ : % 匹配任意字符包括空
下劃線 匹配一個字符
###############################################################################
第9章 正則表達式搜索
where 列名 REGEXP ‘符號’
符號:|,[],\\,?,[:alnum:],[:digit:],{m,n},^,% 等等
###############################################################################
第10章 創建計算字段
把多列數據拼接在一起Concat
別名as
select Concat(列名,'(',列名)) as 新列名
###############################################################################
第11章 數據操作函數
1. 文本操作函數:
Lower(),RTrim(),SubString(),Soundex()
2. 日期函數:
Date(), Now(),
3. 數值操作函數:
Abs(),
###############################################################################
第12章 數據彙總
AVG()列平均,COUNT()行數,MAX(),MIN(),SUM()
select count(*) as num_items, -- * 包含NULL,count(列名)不包含NULL min(列名) as xxx, max(列名) as xxx, from xxx
###############################################################################
第13章 數據分組
1. group by
# 對user中用戶授權的情況進行分組和統計數量
select user,count[*] as user_number from mysql.user group by user;
2. having
類似於where, where對數據分組前過濾,having對分組後過濾
###############################################################################
第14章 子查詢
1. 在語句裏面嵌套
select cust_id from orders where order_num in (select order_num from orderitems where prod_id = 'TNT2')
2.相關子查詢(兩個表格之間的統計關係)
select cust_name, cust_state, (select count(*) from orders where order.cust_id = customers.cust_id) as orders from customers order by cust_name;
###############################################################################
第15章 多表連接
關係表:通過外鍵,在表的一列中包含來自其他表的主鍵值。
select prod_name,vend_name,prod_price from vendors,products -- 如果去掉verdors表, where vendors.vend_id = products.vend_id -- 這裏的vendors.vend_id會提示Unkown column, order by vend_name,prod_name; -- 如果沒有where這一行,會輸出兩個表格行數相乘的數據量
內連接:inner join on, 跟where得到的結果相同
性能考慮:表連接越多,查詢性能越低
###############################################################################
第16章 創建高級連接
1. 表別名 as c, 然後可以用c.xxx 來訪問列
2. 自連接:在同一個表裏面查詢,比如在products表中查詢出問題的product來自哪個供應商,這個供應商的所有產品
3. 自然連接:
例子:在滿足其他列的情況下,得到customers所有的列
select o.order_num, o.order_date, oi.prod_id, oi.quantity,oi.item_price from customers as c, orders as o, orderitems as oi where c.cust_id = o.cust_id and oi.order_num = o.order_num and prod_id = 'FB';
4. 外連接:對應不上的情況下填NULL,可以左對應或者右對應
select xxx,xxx from 表名 LEFT/RIGHT OUTER JOIN 表名 on xxx = xxx;
###############################################################################
第17章 聯合查詢 union
直接在兩個查詢語句中摻入union,要求相同列數,會默認去重複。也可以用where實現
union all 直接把兩次查詢合併在一起
###############################################################################
第18章 全文本搜索
select match() against()
不需要完全匹配,可以搜索特定的單詞,不區分大小寫
create table 時指定FULLTEXT(列名)
rank指定排位,先搜索到的排位高,沒有包含單詞的排位爲0
###############################################################################
第19章 插入數據
insert into 表名(列名,列名) values('xxxx','xxxx'), values('xxxx','xxxx') )
###############################################################################
第20章 更新和刪除數據
update 表名 set 列名 where 列名 = xxx; delete from 表名 where 列名 = xxx
提醒:使用update和delete必須加where,否則會set或者刪除表的所有行。
###############################################################################
第21章 創建和操作表
create table 表名 ( 列名 數據類型 NULL AUTO_INCREMENT 列名 數據類型 NOT NULL DEFAULT 1 xxxx )ENGINE=XXX
設置爲not null 的列必須指定或加default指定,設置爲null的列默認爲null
每個表要設置引擎:
(1) InnoDB: 事務安全,不支持全文本搜索
(2) MEMORY: 數據存儲在內容中,處理快 -> 適用於臨時表
(3) MyISAM: 跟MEMORY類似,支持全文本搜索,不支持事務
(4) ARIA:新的事務安全引擎,支持全文本搜索和重要的崩潰恢復特性
更新表:
(1) 插入一列
alter table if not exists 表名 add 列名 類型
(2) 刪除一列
alter table 表名 drop column 列名
(3) 其他(更新列名等)
刪除表:
drop table 表名
重命名錶:
rename table 表名 to 表名;
外鍵 :
將一個表格的列的內容約束在另一個表格的列裏面。當定義一個表中的列,不在另一個表內容中,就報錯。
例子:
ALTER TABLE pc --(表名) ADD CONSTRAINT fk_cpu_model --(外鍵名字) FOREIGN KEY (cpumodel) --cpumode是表pc中的一列 REFERENCES parts(model) -- parts 是表model中的一列
解釋:pc中的cpumodel列表必須在parts表格中的model裏面
###############################################################################
第22章 視圖
視圖是一些虛表,將複雜的查詢封裝起來。
優點:1.重用SQL語句,簡化複雜的SQL操作; 2.保證數據安全,只暴露表的一部分 3.改變數據呈現的格式
缺點:視圖不包含數據,每次操作都要先執行查詢檢索,所以一旦比較複雜,性能明顯下降。
視圖的使用方式跟普通表相同:select,過濾, 如果是增加或更新數據庫有一些限制條件
舉例:
create view verdorlacation as select Concat(RTrim(vend_name),'{',RTrim(vend_country),'}') as vend_title --查詢語句不需改變 from vendors order by vend_name;
select * from verdorlacation;
提醒:
並非所有視圖都可以更新,更新視圖會改變底層的表。
基本上,如果MariaDB不能正確地查詢出底層需要更新的數據,就不允許更新
使用了以下操作就不可以更新:分組(使用group by/having), 連接(多個表格), 子查詢, 聯合union, 聚合函數(max,min等), distinct, 導出計算列
###############################################################################
第23章 存儲過程
存儲過程是一個可編程的函數,可以看成面向對象編程。預先編譯(SQL語句執行是都需要先編譯),調用即可。
delimiter //--定界符,防止多個分號造成語句識別錯誤 create procedure 存儲函數名字( out 輸出參數名 數據類型, in 輸入參數名 數據類型 ...) begin select xxx into 輸出參數名 from xxx; ... end // --遇到定界符//後執行以上語句
delimiter; call 存儲函數名字(輸入參數,@輸出參數名); --編譯(不輸出) select @輸出參數名; --輸出結果
例子:同時用 IN, OUT, 接收訂單號,返回訂單總額
DELIMITER // CREATE PROCEDURE ordertotal( IN onnumber INT, IN taxable BOOLEAN, OUT ototal DECIMAL(8,2) )COMMENT 'Obtain order total, optionally adding tax' BEGIN DECLARE total DECIMAL(8,2); DECLARE taxrate INT DEFAULT 6; SELECT Sum(item_price*quantity) FROM orderitems WHERE order_num = onnumber INTO total; IF taxable THEN SELECT total+(total/100*taxrate) INTO total; END IF; SELECT total INTO ototal; END // DELIMITER ; --這裏必須要有空格以恢復,否則下面一直要用// 來結束語句 CALL ordertotal(20005,1,@total); SELECT @total;
刪除存儲過程
drop procedure ordertotal
查詢存儲過程細節
show create procedure ordertotal
存儲過程編程還可以用declare定義局部變量、用if語句等
###############################################################################
第24章 遊標
遊標(Cursor)允許用戶逐行訪問SQL Server返回的結果集。
允許程序對由查詢語句select返回的行集合中的每一行執行相同或不同的操作,而不是對整個行集合執行同一個操作。
遊標通常嵌套在存儲過程中
create procedure 名字() BEGIN DECLARE <遊標名>CURSOR FOR <SELECT語句>; END;
例子:用遊標遍歷取得表orders中的order_number給局部變量o,
傳入存儲過程ordertotal(o,1,t),計算得到t並插入新表ordertotals
DELIMITER // create procedure processorders() begin declare done boolean DEFAULT 0; declare o int; declare t decimal(8,2);
declare ordernumbers cursor FOR select order_num from orders; declare continue handler for sqlstate '02000' set done=1; create table if not exists ordertotals (order_num int, total decimal(8,2));
open ordernumbers; repeat fetch ordernumbers into o; call ordertotal(o,1,t); insert into ordertotals(order_num,total) values (o,t); until done end repeat;
close ordernumbers; end // DELIMITER ;
###############################################################################
第25章 觸發器
當對一個表進行delete,insert,update的時候執行觸發器,一個觸發器只對應一個事件一個表,
觸發器不支持視圖以及臨時表。
create trigger 觸發器名 觸發時間 觸發事件 on 表名 [for each row] [begin] pl/sql 語句 [end;]
觸發時間:before/after
觸發事件:insert/update/delete
表名:數據庫觸發器所在的表
例子:在表orders發生insert後,orders_log增加一行
create table orders_log( change_id int not null AUTO_INCREMENT, changed_on datetime not null, change_type char(1) not null, order_num int not null, primary key (change_id) )ENGINE=Maria;
DELIMITER // create trigger neworder after insert on orders for each row begin insert into orders_log(changed_on,change_type,order_num) values(Now(),'A',new.order_num); --new.order_num獲取表orders中新插入的order_num。類似的,也有old的虛表可以使用 end // DELIMITER ;
###############################################################################
第26章 管理事務處理
事務: Transaction
回滾:Rollback --對insert,update,delete回滾,對select回滾沒意義。也不能對create或者drop回滾
提交:Commit --顯示執行commit後,執行rollback沒有用
保存點:Savepoint
數據庫默認是autocommit,只要執行語句,數據庫的改變就是永久的。也可以set autocommit=0,就要手動commit
Savepoint 名字;
rollback to 名字; --因此,越多保存點,有利於回滾;
例子:證明對delete回滾
select * from ordertotals; start Transaction; -- 定義事務處理 delete from ordertotals; select * from ordertotals; rollback -- 回滾上面語句直到遇到 start Transaction select * from ordertotals;
###############################################################################
第27章 全球化和本地化
字符集:show character set;
排序規則:show collation;
###############################################################################
第28章 安全管理
--新建之後usage表示沒有任何權限,SHOW grants for test默認是grant usage on *.* to 'test'@'%'
create user username identified by 'password'
授予權限:
grant select on crashcourse.* to username; --給username 賦予查詢crashcourse所有表格的權限 revoke select on *.* from username; --取消對所有數據庫查詢權限
要記得
flush privileges;
修改密碼:
set password for username = Password('xxx');
###############################################################################
第29章 數據庫維護
執行備份mysqldump之前執行flush tables;
analyze table tablename; check table tablename,tablename;
可以使用repairtable,但不應該經常使用
日誌:
錯誤日誌: hostname.err,包含啓動關閉問題
查詢日誌:hostname.orders_log,記錄所有活動,很快變大
二進制日誌:hostname-bin,記錄更新數據庫的所有語句
慢速查詢日誌:hostname-slow.log, 記錄執行速度慢的查詢,優化用
###############################################################################
第30章 提升性能
1. 使用推薦/指定的硬件
2. 配置參數:調整內存分配,緩衝區尺寸,show variables; show status;
3. show processlist可以看到活動進程,一個進程慢會影響其他;
4. 優化數據庫語句,使用explain解釋select語句
5. 通常存儲過程比單獨的語句執行快
6. 使用正確的數據類型
7. 不要檢索超出你需求的數據,少用select *
8. ...