《MariaDB必知必會》筆記

###############################################################################

第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. ...






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章