學(xué)習(xí)mysql的幾天野哭,將筆記整理一下
SQL(Structured Query Language): 結(jié)構(gòu)化查詢語(yǔ)言挂滓。
數(shù)據(jù)庫(kù)軟件稱為: DBMS(數(shù)據(jù)管理系統(tǒng)庫(kù))
DBMS可分為兩類:
- 基于共享文件系統(tǒng)的DBMS屋匕。Microsoft Access命雀、FileMaker
- 基于客戶機(jī)——服務(wù)器的DBMS翔始。MySQL倒脓、Oracle撑螺、Microsoft SQL Server
數(shù)據(jù)庫(kù)(database): 數(shù)據(jù)庫(kù)是一個(gè)以某種有組織的方式存儲(chǔ)的數(shù)據(jù)集合。通常是一個(gè)文件或一組文件崎弃。
表(table): 是一種結(jié)構(gòu)化的文件甘晤,可用來存儲(chǔ)某種特定類型的數(shù)據(jù)。數(shù)據(jù)庫(kù)中的每個(gè)表都有一個(gè)名字饲做,用來標(biāo)識(shí)自己线婚,此名字是唯一的。
列(column): 表中的一個(gè)字段盆均,所有表都是由一個(gè)或多個(gè)列組成的塞弊。
分解數(shù)據(jù): 正確的將數(shù)據(jù)分解成多個(gè)列極為重要,通過把他們分解開,才有可能利用特定的列對(duì)數(shù)據(jù)進(jìn)行排序和過濾游沿。
數(shù)據(jù)類型(datatype): 數(shù)據(jù)類型限制可存儲(chǔ)在列中的數(shù)據(jù)類型饰抒。
行(row):表中的一條記錄。
主鍵(primary key):
外鍵(foreign key):
自增量(auto_increment):
默認(rèn)值(default):
描述(comment):
存儲(chǔ)引擎
- engine=InnoDB:可靠的事務(wù)處理引擎诀黍,不支持全文搜索袋坑。
- MyISAM:是一個(gè)性能極高的引擎,支持全文搜索眯勾,但不支持事務(wù)處理咒彤。
- MEMORY:功能等同于MyISAM,但由于數(shù)據(jù)存儲(chǔ)在內(nèi)存(不是磁盤中)咒精,速度很快,特別適合于臨時(shí)表旷档。
注意:外鍵不能跨引擎模叙。
MySQL是一種DBMS,即一種數(shù)據(jù)庫(kù)管理軟件鞋屈。
MySQL的特點(diǎn):
- 可伸縮性(scale):
====================================================
show database;
show tables;
show colunms from table_name;
show status;
用于顯示廣泛是服務(wù)器狀態(tài)信息
show create database / show create table;
顯示創(chuàng)建特定數(shù)據(jù)庫(kù)或表的SQL語(yǔ)句
show grants;
從來顯示授權(quán)用戶(所有用戶或特定用戶)的安全權(quán)限
show errors / show warnings;
顯示服務(wù)器錯(cuò)誤或警告的信息
help show
來獲取更多的命令
檢索數(shù)據(jù)
select [distinct] column_name, .... from table_name;
distinct: 只返回不同的值(該關(guān)鍵字應(yīng)用于所有列)
使用通配符:
select * from table_name;
檢索返回指定的條數(shù):
limit num;
從指定位置開始檢索指定的條數(shù):
limit start_index, num;
(index起始值為0)
limit num offset start_index;
注意:有的時(shí)候需要使用完全限定名:
db_name.table_name
table_name.column_name
排序:
按單個(gè)列排序:
order by column_name [DESC|ASC];
按多個(gè)列排序:(每個(gè)列都要指明排序的方向)
order by column_name1 [DESC|ASC], column_name2 [DESC|ASC], ...;
在按多個(gè)列排序時(shí)范咨,排序完全按所規(guī)定的順序進(jìn)行。(僅有在多個(gè)行具有相同的column_name1
時(shí)厂庇,才會(huì)按column_name2
排序渠啊。如果column_name1
中的所有值都是唯一的,則不會(huì)按column_name2
排序)
默認(rèn)的排序方向?yàn)樯颍ˋSC):
ASC ===> A-->Z
DESC===> Z-->A
SELECT子句的順序:
- select
- from
- where
- group by
- having
- order by
- limit
過濾數(shù)據(jù)
使用 WHERE
子句
MySQL在執(zhí)行匹配時(shí)权旷,默認(rèn)不區(qū)分大小寫替蛉。
使用單引號(hào)''
限定字符串,
where子句的操作符:
=
等于
<>
不等于
!=
不等于
<
小于
<=
小于等于
>
大于
>=
大于等于
BETWEEN
在指定的兩個(gè)值之間
BETWEEN start_value AND end_value; (包括 start_value和end_value)
空值檢查:
WHERE column_name IS NULL;
組合 WHERE 子句:
AND
操作符拄氯,可以添加多個(gè)過濾條件躲查,使用 AND 連接。OR
操作符
注意:(操作時(shí)使用圓括號(hào)明確地分組操作符译柏。)IN (value1, value2)
指定條件的范圍
注意:IN 操作符 與 OR 操作符功能相同镣煮,可以包含其他的 SELECT 語(yǔ)句,能夠更動(dòng)態(tài)地建立WHERE子句鄙麦。NOT
操作符
用來否定后跟的條件典唇。
注意:MYSQL中支持使用 MOT 對(duì)IN、BETWEEN胯府、EXISTS子句取反的操作
用通配符進(jìn)行過濾:
LIKE 子句介衔, 后跟匹配的條件
百分號(hào)(%)通配符:表示任意字符出現(xiàn)任意次數(shù)。
'jre%'
---- 以 jre 開頭
'%jar%'
--- 包含 jar下劃線(_)通配符:只匹配單個(gè)字符盟劫。
注意: 通配符的搜索一般要比其他搜索所花的時(shí)間更長(zhǎng)夜牡。
- 不要過度使用通配符,如果其他的操作符能達(dá)到相同的目的,應(yīng)該使用其他的操作符塘装。
- 除非絕對(duì)有必要急迂,否則不要把他們用在搜索模式的開始處,搜索起來是最慢的蹦肴。
- 注意使用通配符所在位置僚碎。
WHERE子句內(nèi)使用正則表達(dá)式進(jìn)行搜索:
REGEXP
子句,后跟匹配的條件阴幌。默認(rèn)匹配不區(qū)分大小寫勺阐,
可使用REGEXP BINARY
子句來是的區(qū)分大小寫。
'.'
:表示匹配任意一個(gè)字符矛双。'.name'
'|'
: 正則表達(dá)式中的OR操作符渊抽。'a|b'-----匹配a或b
'[]'
:匹配任何單一字符,也是OR操作符飛另一種形式议忽。[abc]---匹配a或b或c
'[^abc]'
----匹配除a懒闷、b、c以外的字符栈幸。
'[0-9]'
:匹配0~9.
'[a-z]'
'\\.'
:表示查找 '.'
計(jì)算字段
拼接字段:
在MySQL中 Concat()
函數(shù)用來拼接字段串愤估,即拼接在一起顯示特定的信息。
多個(gè)字段用,
隔開速址。
RTirm()
函數(shù)玩焰,刪除數(shù)據(jù)右側(cè)多余的空格。
LTirm()
函數(shù)芍锚,刪除數(shù)據(jù)左側(cè)多余的空格昔园。
使用別名:
AS alias_name;
SELECT Concat(RTrim(vend_nmae), '(', RTrim(vend_country), ')') AS wend_title FROM vendors ORDER BY vend_name;
列別名:
表別名:表別名只在查詢中使用,表別名不返回到客戶機(jī)闹炉。
執(zhí)行算術(shù)計(jì)算:
+
-
*
/
SELECT prod_id, quantity, item_price,
quantity*item_price AS expanded_price
FROM orderitems
WHERE order_num = 20005;
數(shù)據(jù)分組
group by
SELECT vend_id, COUNT(*) AS num_prods
FROM products
GROUP BY vend_id;
過濾分組:
having
having 支持所有 where操作蒿赢。
SELECT cust_id, COUNT(*) AS orders
FROM orders
GROUP BY cust_id
HAVING COUNT(*) >= 2;
having 和 where 的區(qū)別:
- where 過濾行,having過濾分組渣触;
- where 在數(shù)據(jù)分組前進(jìn)行過濾羡棵,having在數(shù)據(jù)分組后進(jìn)行過濾;
- where排除的行不包括在分組中嗅钻。
子查詢
子查詢:嵌套在其他查詢語(yǔ)句中的查詢
聯(lián)結(jié)
foreign key
外鍵:為某個(gè)表中的一列皂冰,它包含另一個(gè)表的主鍵值,定義了兩個(gè)表之間的關(guān)系养篓。
聯(lián)結(jié):
是一種機(jī)制秃流,用來在一條 SELECT 語(yǔ)句中關(guān)聯(lián)表。
使用特殊語(yǔ)法柳弄,可以聯(lián)結(jié)多個(gè)表返回一組輸出舶胀。聯(lián)結(jié)在運(yùn)行時(shí)關(guān)聯(lián)表中正確的行概说。
聯(lián)結(jié)在實(shí)際的數(shù)據(jù)庫(kù)表中并不存在,聯(lián)結(jié)由MySQL根據(jù)需要建立嚣伐,它存在于查詢的執(zhí)行當(dāng)中糖赔。
SELECT vend_name, prod_name, prod_price
FROM vendors, products
WHERE vendors.vend_id = products.vend_id
ORDER BY vend_name, prod_name;
注意:
- 在聯(lián)結(jié)中的WHERE子句是很關(guān)鍵的,應(yīng)該保證所有聯(lián)結(jié)都有WHERE子句轩端,否則MySQL將返回比想要的數(shù)據(jù)多的多的數(shù)據(jù)放典。
- 還應(yīng)保證WHERE子句的正確性,不正確的過濾條件將導(dǎo)致mysql返回不正確的數(shù)據(jù)基茵。
內(nèi)部聯(lián)結(jié)(最常用的形式):
到目前為止奋构,所有的聯(lián)結(jié)都稱為等值聯(lián)結(jié),它基于兩個(gè)表之間的相等測(cè)試拱层,這種聯(lián)結(jié)也稱為內(nèi)部聯(lián)結(jié)弥臼。
SELECT vend_name, prod_name, prod_price
FROM vendors INNER JOIN products
ON vendors.vend_id = products.vend_id;
這樣的寫法與上邊的寫法的結(jié)果是等同的,
聯(lián)結(jié)多個(gè)表:
SQL對(duì)于一條SELECT語(yǔ)句中可以聯(lián)結(jié)的表的數(shù)目沒有限制根灯。
創(chuàng)建的規(guī)則也基本相同醋火,首先列出所有表,然后定義表之間的關(guān)系箱吕。
SELECT prod_name, vend_name, prod_price, quantity
FROM orderitems, vendors, products
WHERE products.vend_id = vendors.vend_id
AND orderitems.prod_id = products.prod_id
AND order_num = 20005;
自聯(lián)結(jié):
用一個(gè)問題來說明
SELECT prod_id, prod_name
FROM products
WHERE vend_id = (SELECT vend_id FROM products WHERE prod_id = 'DTNTR');
下面使用自聯(lián)結(jié)將達(dá)到相同的效果:
SELEC p1.prod_id, p1.prod_name
FROM products AS p1, products AS p2
WHERE p1.vend_id = p2.vend_id
AND p2.prod_id = 'DTNTR';
自聯(lián)結(jié)通常作為外部語(yǔ)句用來代替從相同表中檢索數(shù)據(jù)時(shí)使用的子查詢語(yǔ)句。
自然聯(lián)結(jié):
外部聯(lián)結(jié):
許多聯(lián)結(jié)將一個(gè)表中的行與另一個(gè)表中的行相關(guān)聯(lián)柿冲。但有時(shí)候會(huì)需要包含沒有關(guān)聯(lián)行的那些行茬高。這種類型的聯(lián)結(jié)稱為外部聯(lián)結(jié)。
LEFT|RIGHT OUTER JOIN
表示從左邊表或右邊表中選擇所有行假抄。
組合查詢
多數(shù)SQL查詢都只包含從一個(gè)或多個(gè)表中返回?cái)?shù)據(jù)的單條SELECT語(yǔ)句怎栽。
MySQL也允許執(zhí)行多個(gè)查詢(多條SELECT語(yǔ)句),并將結(jié)果作為單個(gè)查詢結(jié)果集返回宿饱。
有兩種情況需要使用組合查詢:
- 在單個(gè)查詢中從不同的表返回類似結(jié)構(gòu)的數(shù)據(jù)熏瞄。
- 對(duì)單個(gè)表執(zhí)行多個(gè)查詢,按單個(gè)查詢返回?cái)?shù)據(jù)谬以。
UNION
- 必須由兩條或兩條以上的SELECT語(yǔ)句組成强饮,SELECT語(yǔ)句之間用UNION關(guān)鍵字分割。
- UNION中的每個(gè)查詢必須包含相同的列为黎,表達(dá)式或聚集函數(shù)(各個(gè)列不需要以相同的次序列出)邮丰。
- 列數(shù)據(jù)類型必須兼容,類型不必完全相同铭乾,但必須是DBMS可以隱含轉(zhuǎn)換的類型(例如不用的數(shù)值類型或不同的日期類型)剪廉。
消掉重復(fù)的行:
UNION
默認(rèn)返回結(jié)果會(huì)消掉重復(fù)的行;
UNION ALL
則不消掉重復(fù)的行炕檩。
對(duì)組合查詢結(jié)果進(jìn)行排序:
SELECT語(yǔ)句的輸出用order by 語(yǔ)句排序斗蒋,再用 UNION 組合查詢時(shí),只能使用一條 order by子句,
它必須出現(xiàn)在最后一條SELECT語(yǔ)句之后泉沾。
可以組合不同的表
插入數(shù)據(jù)
再插入數(shù)據(jù)時(shí)需要注意的問題:
- 一般使用明確給出列的列表的insert語(yǔ)句捞蚂。即使表結(jié)構(gòu)發(fā)生改變,也可以正確插入爆哑。
- 省略某些列:
省略列必須滿足以下的條件:
該列定義為允許NULL值(無值或空值)洞难。
在表的定義中給出默認(rèn)值。
不滿足上述的條件則會(huì)產(chǎn)生一條錯(cuò)誤的消息揭朝,并且相應(yīng)的行插入不成功队贱。
使用 insert low_priority into 語(yǔ)句可以指示mysql降低insert語(yǔ)句的優(yōu)先級(jí)。
因?yàn)閕nsert語(yǔ)句執(zhí)行很耗時(shí)潭袱,這樣可以提高性能柱嫌。
這也適用于update和delete語(yǔ)句。插入檢索出的數(shù)據(jù)
insert into table_name(column_name1, column_name2,...)
values(value1, value2...)
select column_nam1, column_name2,... from table_name;
更新語(yǔ)句
update table_name set colunm_name1=value1, column_name2=value2,... where 過濾條件;
如果用 update 更新語(yǔ)句更新多行屯换,并且在更新這些行找中的一行或者多行出現(xiàn)錯(cuò)誤编丘,則整個(gè)的update操作將被取消。
為了即使是發(fā)生了錯(cuò)誤彤悔,也繼續(xù)進(jìn)行更新嘉抓,可使用 ignore 關(guān)鍵字。
update ignore table_name set....;
刪除語(yǔ)句
delete from table_name where 過濾條件;
- delete語(yǔ)句刪除表中的行晕窑,甚至是所有的行抑片,但是不刪除表本身。
- 若想要更快的刪除表中的所有數(shù)據(jù)杨赤,可使用:
truncate table 語(yǔ)句敞斋,(實(shí)際是刪除了原來的表并重新創(chuàng)建了一個(gè)表,而不是逐行刪除表中的數(shù)據(jù))疾牲。
對(duì)于表的操作
創(chuàng)建表:
create table [IF NOT EXISTS] table_name();
更新表:
alert table table_name 要操作的語(yǔ)句;
添加一個(gè)字段
ALERT TABLE vendors ADD vend_phone char(20);
刪除一個(gè)字段
ALERT TABLE vendors DROP COLUMN vend_phone;
alert的一種常見操作是定義外鍵植捎。
ALERT TABLE table_name ADD CONSTRAINT fk_tableName1_tableName2 FOREIGN KEY (column_name) REFERENCES table_name(column_name);
刪除表:
drop table table_name;
重命名表:
rename table old_table_name to new_table_name;
全文搜索
MyISAM引擎支持全文搜索。
在使用全文本搜索時(shí)阳柔,MySQL不需要分別查看每個(gè)行焰枢,不需要分別分析和處理每個(gè)詞,MySQL創(chuàng)建指定列中個(gè)詞的一個(gè)索引舌剂,搜索可以針對(duì)這些詞進(jìn)行医咨。這樣,MySQL就可以快速有效地決定哪些詞匹配(哪些行包含他們)架诞,哪些詞不匹配 拟淮,他們的匹配頻率,等等谴忧。
使用全文本搜索:
為了進(jìn)行全文本搜索很泊,必須索引被搜索的列角虫,而且要隨著數(shù)據(jù)的改變不斷地重新索引,在對(duì)表列進(jìn)行適當(dāng)?shù)脑O(shè)計(jì)后委造,MySQL會(huì)自動(dòng)進(jìn)行所有的索引和重新索引戳鹅。
啟用全文搜索支持(創(chuàng)建索引):
一般在創(chuàng)建表時(shí)啟用全文本搜索,
CREATE TABLE productnotes(
note_id INT NOT NULL AUTO_INCREMENT,
prod_id VARCHAR(10) NOT NULL,
note_date DATETIME NOT NULL,
note_text TEXT NULL,
PRIMARY KEY (note_id),
FULLTEXT (note_text) // 多個(gè)索引列用逗號(hào)隔開
) ENGINE = MyISAM;
在定義之后昏兆,MySQL會(huì)自動(dòng)的維護(hù)該索引枫虏,在增加、更新爬虱、修改行時(shí)隶债,索引隨之自動(dòng)更新。
進(jìn)行全文搜索:
在索引之后跑筝,使用兩個(gè)函數(shù) Match() 和 Against() 執(zhí)行全文搜索死讹。
Match()
--指定被搜索的列
Against()
--指定要使用的搜索表達(dá)式(要搜索的東西)
SELECT note_text FROM productnotes
WHERE Match(note_text) Against('rabbit');
注意:傳遞給Match()的值必須與 FULL TEXT() 定義中的相同,如果指定多個(gè)列曲梗,則必須列出他們(而且次序正確)赞警。
搜索不區(qū)分大小寫,除非使用BINARY方式虏两。
全文本搜搜的一個(gè)重要的部分就是會(huì)對(duì)搜索結(jié)果進(jìn)行排愧旦,具有較高等級(jí)的先返回。
(兩個(gè)行包含同樣的詞定罢,但包含該詞作為第3個(gè)詞的行的等級(jí)比作為第20個(gè)詞的行高)
使用查詢擴(kuò)展:
查詢擴(kuò)展用來設(shè)法放寬所返回的全文本搜索結(jié)果的范圍忘瓦。(返回相關(guān)的數(shù)據(jù),也就是數(shù)有聯(lián)系的)
SELECT note_text FROM productnotes
WHERE Match(note_text) Against('rabbit' WITH QUERY EXPANSION );
布爾文本搜索:
布爾文本搜索是MySQL支持全文本搜索的另外一種形式引颈。
布爾文本搜索可以提供關(guān)于如下內(nèi)容的細(xì)節(jié):
- 要匹配的詞
- 要排斥的詞(某行包含該詞將不返回)
- 排列提示(指定某些詞比其他詞更重要,重要的詞等級(jí)更高)
- 表達(dá)式分組
- 另外的一些內(nèi)容
SELECT note_text FROM productnotes
WHERE Match(note_text) Against('rabbit' IN BOOLEAN MODE );
匹配包含 heavy 但不包含任意以 rope 開頭的詞的行境蜕,如下:
SELECT note_text FROM productnotes
WHERE Match(note_text) Against('heavy -rope*' IN BOOLEAN MODE );
全文本布爾搜索操作符:
+
:包含蝙场,詞必須存在
-
:排除,詞必須不出現(xiàn)
>
:包含粱年,且增加等級(jí)值
<
:包含售滤,且減小等級(jí)值
()
:用于組成子表達(dá)式
~
:取消一個(gè)詞的排序值
*
:
""
:定義一個(gè)短語(yǔ)
視圖
MySQL5 增加了對(duì)視圖的支持。
視圖(View):是虛擬的表台诗,與包含數(shù)據(jù)的表不一樣完箩,視圖只包含使用時(shí)動(dòng)態(tài)檢索數(shù)據(jù)的查詢。
視圖的一些常見應(yīng)用:
- 重用SQL語(yǔ)句拉队。
- 簡(jiǎn)化復(fù)雜的SQL操作弊知。在編寫查詢后,可以方便的重用他而不必知道它的基本查詢細(xì)節(jié)粱快。
- 使用表的組成部分而不是整個(gè)表秩彤。
- 保護(hù)數(shù)據(jù)叔扼。可以給用戶授予表的特定部分的訪問權(quán)限而不是整個(gè)表的訪問權(quán)限漫雷。
- 更改數(shù)據(jù)格式和表示瓜富。視圖可返回與底層表的表示和格式不同的數(shù)據(jù)。
在視圖創(chuàng)建之后降盹,可以用域表基本相同的操作方式來來操作它与柑。
可以對(duì)視圖執(zhí)行select操作,過濾蓄坏、排序价捧、聯(lián)結(jié)到其他視圖或表、添加數(shù)據(jù)剑辫、更新數(shù)據(jù)(添加和更新數(shù)據(jù)存在某些限制)干旧。
視圖的規(guī)則和限制:
- 視圖必須唯一命名。
- 對(duì)于可以創(chuàng)建的視圖數(shù)目沒有限制妹蔽。
- 為了創(chuàng)建視圖椎眯,必須具有足夠的訪問權(quán)限。通常由數(shù)據(jù)庫(kù)管理人員授予胳岂。
- 視圖可以嵌套编整。即可以使用視圖中的檢索查詢來構(gòu)造一個(gè)視圖。
- order by 可以用在視圖中乳丰,但如果從該視圖中檢索數(shù)據(jù)的select中也含有order by掌测,
那么該視圖中的order by 將被覆蓋。 - 視圖不能索引产园,也不能有關(guān)聯(lián)的觸發(fā)器和默認(rèn)值汞斧。
- 視圖可以和表一起使用。比如和表聯(lián)結(jié)什燕。
創(chuàng)建視圖:
create view as select語(yǔ)句
查看創(chuàng)建的視圖:
show create view view_name;
刪除視圖:
drop view view_name;
更新視圖:
- 先使用
drop
粘勒,在用create
- 直接使用
create or replace view
如果要更新的視圖不存在,該語(yǔ)句會(huì)創(chuàng)建一個(gè)視圖屎即;
如果要更新的視圖存在庙睡,該語(yǔ)句會(huì)替換原有的視圖。
視圖是可更新的(insert技俐、update乘陪、delete),更新一個(gè)是將更新其基表雕擂。
并非所有的視圖都是可更新的啡邑,如果視圖定義中有如下的操作,則不能進(jìn)行視圖的更新:
- 分組(使用group by或 having)
- 聯(lián)結(jié)
- 子查詢
- 并
- 聚集函數(shù)
- distinct
- 導(dǎo)出(計(jì)算)列
注意:一般應(yīng)該將視圖用于檢索井赌,而不是更新谣拣。
存儲(chǔ)過程
MySQL5增加了對(duì)存儲(chǔ)過程的支持募寨。
存儲(chǔ)過程:為以后的使用而保存的一條或多條MySQL語(yǔ)句的集合。
為什么要使用存儲(chǔ)過程:
- 通過把處理封裝在容易使用的單元中森缠,簡(jiǎn)化復(fù)雜的操作拔鹰。
- 不再反復(fù)建立一系列的處理步驟,保證了數(shù)據(jù)的完整性贵涵。
比如列肢,開發(fā)人員和應(yīng)用程序都使用同一存儲(chǔ)過程,則所使用的代碼都是相同的宾茂。這樣就保證數(shù)據(jù)的一致性瓷马,不容易出錯(cuò)。 - 簡(jiǎn)化對(duì)變動(dòng)的管理跨晴。如表名欧聘、列名、或業(yè)務(wù)邏輯等有變化端盆,只需改動(dòng)存儲(chǔ)過程的代碼怀骤。
- 提高性能。
- 存儲(chǔ)過程可以用來編寫功能更強(qiáng)更靈活的代碼焕妙。
創(chuàng)建存儲(chǔ)過程需要訪問權(quán)限蒋伦,這通常是由數(shù)據(jù)庫(kù)管理員賦予。
創(chuàng)建存儲(chǔ)過程:
create procedure procedure_name([參數(shù)1, 參數(shù)2, ...])
begin
存儲(chǔ)過程執(zhí)行代碼(過程體)
end;
使用存儲(chǔ)過程:
call procedure_name([@參數(shù)1, @參數(shù)2, ...]);
刪除存儲(chǔ)過程:
drop procedure procedure_name;
僅當(dāng)存在時(shí)刪除焚鹊,不存在會(huì)產(chǎn)生錯(cuò)誤痕届,可使用:
drop procedure if exists procedure_name;
參數(shù):
一般存儲(chǔ)過程并不返回結(jié)果,而是把結(jié)果返回給你指定的變量末患。
CREATE PROCEDURE productpricing(
OUT p1 DECIMAL(8, 2),
OUT p2 DECIMAL(8, 2),
OUT p2 DECIMAL(8, 2)
)
BEGIN
SELECT min(prod_price)
INTO p1
FROM products;
SELECT max(prod_price)
INTO p2
FROM products;
SELECT avg(prod_price)
INTO p3
FROM products;
END;
該存儲(chǔ)過程接受了三個(gè)參數(shù)研叫,每個(gè)參數(shù)必須具有指定的類型
IN
傳遞給存儲(chǔ)過程
OUT
從存儲(chǔ)工程傳出
INOUT
對(duì)存儲(chǔ)過程傳入和傳出
INTO
保存到相應(yīng)的變量
注意:不能通過一個(gè)參數(shù)返回多個(gè)行和列。
使用該存儲(chǔ)過程:
CALL productpricing(@pricelow, @pricehigh, @priceaverage);
顯示該存儲(chǔ)過程的結(jié)果:
SELECT @pricelow, @pricehigh, @priceaverage;
CREATE PROCEDURE ordertotal(
IN onumber INT,
OUT ototal DECIMAL(8,2)
)
BEGIN
SELECT sum(item_price*quantity)
FROM orderitems
WHERE order_num = onumber
INTO ototal;
END;
CALL ordertotal(20005, @total);
SELECT @total;
局部變量:
在過程體中定義局部變量(BEGIN--END之間)璧针,使用:
DECLARE taxrate INT DEFAULT 6;
局部變量要指定變量名和數(shù)據(jù)類型嚷炉。
CREATE PROCEDURE ordertotal(
IN onumber INT,
IN taxable BOOLEAN,
OUT ototal DECIMAL(8,2)
)
BEGIN
-- 創(chuàng)建局部變量
DECLARE total DECIMAL(8, 2);
DECLARE taxrate INT DEFAULT 6;
SELECT sum(item_price*quantity)
FROM orderitems
WHERE order_num = onumber
INTO total;
-- ELSEIF | ELSE
IF taxable THEN
SELECT total+(total/100*taxrate) INTO total;
END IF;
SELECT total INTO ototal;
END;
-- 0為假,非0為真
CALL ordertotal(20005, 1, @total);
SELECT @total;
檢查存儲(chǔ)過程:
顯示創(chuàng)建存儲(chǔ)過程的create語(yǔ)句:
show create procedure procedure_name;
獲得詳細(xì)的存儲(chǔ)信息列表:
show procedure status;
游標(biāo)
MySQL5添加了對(duì)游標(biāo)的支持陈莽。
MySQL檢索操作返回一組稱為結(jié)果集的行。返回的行都是與sql語(yǔ)句相匹配的行(零行或多行)虽抄。有的時(shí)候是需要在檢索出來的行中前進(jìn)或后退一行或多行走搁,使用簡(jiǎn)單的select語(yǔ)句是沒有辦法得到的。這就是使用游標(biāo)的原因了迈窟。
游標(biāo)(cursor):是一個(gè)存儲(chǔ)在mysql服務(wù)器上的數(shù)據(jù)庫(kù)查詢私植,它不是一條select語(yǔ)句。而是被該語(yǔ)句檢索出來的結(jié)果集车酣。
在存儲(chǔ)了游標(biāo)之后曲稼,應(yīng)用程序可以根據(jù)需要滾動(dòng)或?yàn)g覽其中的數(shù)據(jù)索绪。
游標(biāo)主要用于交互式應(yīng)用,其中用戶需要滾動(dòng)屏幕上的數(shù)據(jù)贫悄,并對(duì)數(shù)據(jù)進(jìn)行瀏覽或作出更改瑞驱。
MySQL游標(biāo)只能用于存儲(chǔ)工程(和函數(shù))。
使用游標(biāo)的步驟:
- 在使用游標(biāo)前必須聲明(定義)它窄坦,這個(gè)過程實(shí)際上沒有檢索數(shù)據(jù)唤反,它只是定義要使用的select語(yǔ)句。
- 一旦聲明后鸭津,必須打開游標(biāo)以供使用彤侍。這個(gè)過程要用到前面定義的select語(yǔ)句把數(shù)據(jù)實(shí)際檢索出來。
- 對(duì)于填有數(shù)據(jù)的游標(biāo)逆趋,根據(jù)需要取出(檢索)各行盏阶。
- 在結(jié)束游標(biāo)使用時(shí),必須關(guān)閉游標(biāo)闻书。
在聲明游標(biāo)后可根據(jù)需要頻繁地打開和關(guān)閉游標(biāo)名斟。在游標(biāo)打開后,可根據(jù)需要頻繁地執(zhí)行取操作惠窄。
創(chuàng)建游標(biāo):
游標(biāo)使用 DECLARE蒸眠,DECLARE命名游標(biāo),并定義相應(yīng)的select 語(yǔ)句杆融。
CREATE PROCEDURE processorders()
BEGIN
DECLARE ordernumbers CURSOR FOR
SELECT order_name FROM orders;
END;
存儲(chǔ)過程處理完后楞卡,游標(biāo)就消失(因?yàn)樗窒抻诖鎯?chǔ)過程)。
打開和關(guān)閉游標(biāo):
在定義了游標(biāo)之后就可以打開它脾歇。
OPEN ordernumbers;
在處理open語(yǔ)句時(shí)執(zhí)行查詢蒋腮,存儲(chǔ)檢索出來的數(shù)據(jù)以供瀏覽和滾動(dòng)。
關(guān)閉:
CLOSE ordernumbers;
close釋放游標(biāo)使用的所有內(nèi)部?jī)?nèi)存和資源藕各,每個(gè)游標(biāo)在不需要時(shí)都應(yīng)該關(guān)閉池摧。
游標(biāo)關(guān)閉后,沒有重新打開是不能使用的激况。
使用過的游標(biāo)不需要再次聲明作彤,使用open打開就可以了。
如果沒有明確的關(guān)閉游標(biāo)(CLOSE)乌逐,mysql會(huì)在 END 時(shí)自動(dòng)關(guān)閉它竭讳。
CREATE PROCEDURE processorders()
BEGIN
DECLARE ordernumbers CURSOR FOR
SELECT order_name FROM orders;
OPEN ordernumbers;
相應(yīng)的處理操作
CLOSE ordernumbers;
END;
使用游標(biāo)數(shù)據(jù):
使用 FETCH 可以訪問它的每一行:
CREATE PROCEDURE processorders()
BEGIN
DECLARE o INT;
DECLARE ordernumbers CURSOR FOR
SELECT order_name FROM orders;
OPEN ordernumbers;
FETCH ordernumbers INTO o;
CLOSE ordernumbers;
END;
該例只訪問的是第一行數(shù)據(jù)。
CREATE PROCEDURE processorders()
BEGIN
DECLARE done BOOLEAN DEFAULT 0;
DECLARE o INT;
DECLARE ordernumbers CURSOR FOR
SELECT order_name FROM orders;
-- SQLSTATE '02000' 是一個(gè)未找到條件
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;
OPEN ordernumbers;
REPEAT
FETCH ordernumbers INTO o;
UNTIL done END REPEAT;
CLOSE ordernumbers;
END;
循環(huán)檢索數(shù)據(jù)浙踢,從第一行到最后一行绢慢。
CREATE PROCEDURE processorders()
BEGIN
DECLARE done BOOLEAN DEFAULT 0;
DECLARE o INT;
DECLARE t DECIMAL(8, 2);
DECLARE ordernumbers CURSOR FOR
SELECT order_name FROM orders;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;
DROP TABLE IF EXISTS ordertotals;
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;
SELECT * FROM ordertotals;
觸發(fā)器
MySQL5增加了對(duì)觸發(fā)器的支持。
想要某條語(yǔ)句(或某些語(yǔ)句)在事件發(fā)生時(shí)自動(dòng)執(zhí)行洛波,這時(shí)就用到了觸發(fā)器胰舆。
觸發(fā)器:是MySQL響應(yīng)以下任意一條語(yǔ)句而自動(dòng)執(zhí)行的一條SQL語(yǔ)句(或位于BEGIN 和 END語(yǔ)句之間的一組語(yǔ)句 )骚露。
- delete
- update
- insert
其他的語(yǔ)句不支持觸發(fā)器。
注意:只有表支持觸發(fā)器缚窿,視圖不支持(臨時(shí)表也不支持)棘幸。
創(chuàng)建觸發(fā)器:
在創(chuàng)建觸發(fā)器時(shí)的 4 部分:
- 唯一的觸發(fā)器名。(在表中唯一)建議:在數(shù)據(jù)庫(kù)中使觸發(fā)器名唯一滨攻。
- 觸發(fā)器關(guān)聯(lián)的表够话。
- 觸發(fā)器應(yīng)該響應(yīng)的事件(delete、update光绕、insert)女嘲。
- 觸發(fā)器何時(shí)執(zhí)行after|before(處理之前或之后)。
CREATE TRIGGER newproduct // 創(chuàng)建名為newproduct的觸發(fā)器
AFTER INSERT ON products // 在insert語(yǔ)句成功執(zhí)行后執(zhí)行
FOR EACH ROW // 對(duì)每個(gè)插入行執(zhí)行
BEGIN
SELECT 'Product added' INTO @o; // 觸發(fā)器執(zhí)行的動(dòng)作
END;
SELECT @o; // 在插入之后查看該信息
每個(gè)表每個(gè)事件每次只允許有一個(gè)觸發(fā)器诞帐,因此欣尼,每個(gè)表最多支持6個(gè)觸發(fā)器(每條insert、update停蕉、delete的之前和之后)愕鼓。
刪除觸發(fā)器:
DROP TRIGGER newproduct;
觸發(fā)器不能更新或覆蓋,為了修改一個(gè)觸發(fā)器慧起,必須先刪除它菇晃,然后再重新創(chuàng)建。
使用觸發(fā)器:
事務(wù)處理
事務(wù)處理(transaction processing):可以用來維護(hù)數(shù)據(jù)庫(kù)的完整性蚓挤,它保證成批的MySQL操作要么完全執(zhí)行磺送,要么完全不執(zhí)行。
事務(wù)處理是一種機(jī)制灿意。
在事務(wù)處理中的幾個(gè)術(shù)語(yǔ):
事務(wù)(transaction):一組SQL語(yǔ)句估灿。
回退(rollback):撤銷指定SQL語(yǔ)句的過程。
提交(commit):將未存儲(chǔ)的SQL語(yǔ)句結(jié)果寫入到數(shù)據(jù)庫(kù)缤剧。
保留點(diǎn)(savepoint):事務(wù)處理中設(shè)置的臨時(shí)占位符(placeholder)馅袁,你可以對(duì)它發(fā)布回退(與回退整個(gè)事務(wù)處理不同,是部分的)荒辕。
控制事務(wù)處理:
管理事務(wù)處理的關(guān)鍵在于將SQL語(yǔ)句組分解為邏輯塊汗销,并明確規(guī)定數(shù)據(jù)何時(shí)應(yīng)該回退,何時(shí)不應(yīng)該回退抵窒。
標(biāo)識(shí)事務(wù)開始:
START TRANSACTION;
使用回滾(rollback):
SELECT * FROM ordertotals;
START TRANSACTION;
DELETE FROM ordertotals;
SELECT * FROM ordertotals;
ROLLBACK ;
SELECT * FROM ordertotals;
rollback只能在一個(gè)事務(wù)處理內(nèi)使用(在執(zhí)行一條start transaction語(yǔ)句之后)弛针。
注意:事務(wù)處理用來管理insert、update估脆、delete钦奋,不能回退select語(yǔ)句座云。
也不能回退create或drop操作疙赠,在事務(wù)處理塊中可以有這兩條語(yǔ)句付材,但如果你執(zhí)行回退,他們不會(huì)被撤銷圃阳。
使用提交(commit):
在事務(wù)處理塊中厌衔,提交不是自動(dòng)進(jìn)行的,需要使用 commit 明確地提交捍岳。
START TRANSACTION ;
DELETE FROM orderitems WHERE order_num = 20010;
DELETE FROM orders WHERE order_num = 20010;
COMMIT ;
注意:當(dāng)commit 或 rollback 語(yǔ)句執(zhí)行后富寿,事務(wù)會(huì)自動(dòng)關(guān)閉。
使用保留點(diǎn)(標(biāo)記):
為了支持回退部分事務(wù)處理锣夹,必須要在事務(wù)處理塊中合適的位置放置占位符(保留點(diǎn))页徐,這樣,如果需要回退银萍,可以回退到某個(gè)占位符变勇。
創(chuàng)建占位符:
SAVEPOINT delete1;
-- 回滾到保留點(diǎn)
ROLLBACK TO delete1;
保留點(diǎn)標(biāo)識(shí)名要唯一。以便在回退時(shí)知道在何處贴唇。
釋放保留點(diǎn):
- 在執(zhí)行一條rollback 或 commit后自定釋放保留點(diǎn)搀绣。
- MySQL5以后可以使用 RELEASE SAVEPOINT delete1;明確地釋放保留點(diǎn)。
修改MySQL默認(rèn)的提交行為:
SET autocommit=0; // 不自動(dòng)提交
注意:autocommit標(biāo)志是針對(duì)每個(gè)連接的戳气,而不是服務(wù)器链患。(標(biāo)志為連接專用)
MySQL的全球化和本地化
在MySQL的正常的數(shù)據(jù)庫(kù)活動(dòng)中,不需要操心太多的東西瓶您,使用何種字符局和校對(duì)麻捻,決定在服務(wù)器、數(shù)據(jù)庫(kù)和表級(jí)進(jìn)行览闰。
MySQL支持眾多的字符局芯肤。
SHOW CHARACTER SET
顯示所有可用的字符集以及每個(gè)字符集的描述和默認(rèn)校對(duì)。
SHOW COLLATION
顯示所有可用的校對(duì)压鉴,以及他們適用的字符集崖咨。
_cs
:表示區(qū)分大小寫。
_ci
:表示不區(qū)分大小寫油吭。
對(duì)整個(gè)表指定:
CREATE TABLE mytable(
column1 INT,
column2 VARCHAR(20)
) DEFAULT CHARACTER SET hebrew COLLATE hebrew_general_ci;
指定了一個(gè)字符集和一個(gè)校對(duì)順序击蹲。
對(duì)某個(gè)列指定:
CREATE TABLE mytable(
column1 INT,
column2 VARCHAR(20),
column3 VARCHAR(10) CHARACTER SET latinl COLLATE latinl_general_ci
) DEFAULT CHARACTER SET hebrew COLLATE hebrew_general_ci;
安全管理
訪問控制:管理訪問控制需要?jiǎng)?chuàng)建和管理用戶賬號(hào)。并賦予相應(yīng)的權(quán)限婉宰。
注意:在日常的工作中歌豺,決不能使用root,應(yīng)該創(chuàng)建一系列 的賬號(hào)來使用心包,有的用于管理类咧,有的供用戶使用,有的用于開發(fā)者使用。
管理用戶:
MySQL用戶賬號(hào)和信息存儲(chǔ)在名為 mysql的數(shù)據(jù)庫(kù)中痕惋。
USE mysql;
SELECT user FROM user;
創(chuàng)建用戶賬號(hào):
CREATE USER user_name IDENTIFIED BY 'password';
重新命名用戶賬號(hào):(MySQL5支持)
RENAME USER old_name TO new_name;
刪除用戶賬號(hào):(刪除用戶及相關(guān)權(quán)限)
DROP USER user_name;
在MySQL5之前只能使用update來更新区宇。
在5版本之前 DROP USER只能用來刪除用戶,不能刪除相關(guān)權(quán)限值戳,需先使用 REVOKE 來刪除相關(guān)的權(quán)限议谷,在刪除用戶。
更改指定用戶的口令:
SET PASSWORD FOR user_name = Password('password');
新口令必須傳遞到Password()函數(shù)進(jìn)行加密堕虹。
更改當(dāng)前用戶的口令:
SET PASSWORD = Password('password');
設(shè)置訪問權(quán)限:
在創(chuàng)建用戶賬號(hào)之后卧晓,接著給該賬號(hào)分配權(quán)限,否則登陸上mysql什么也干不了赴捞。
查看用戶所擁有的權(quán)限:
SHOW GRANTS FOR user_name;
設(shè)置權(quán)限:
GRANT SELECT ON db_name.* TO user_name;
這樣就賦予了用戶對(duì)該數(shù)據(jù)庫(kù)所有表的select權(quán)限逼裆。
GRANT要求至少要給出以下信息:
- 要授予的權(quán)限。
- 被授予訪問權(quán)限的數(shù)據(jù)庫(kù)或表赦政。
- 用戶名波附。
撤銷特定的權(quán)限:
REVOKE SELECT ON db_name.* FROM user_name;
本撤銷的訪問權(quán)限必須存在,否則會(huì)出錯(cuò)昼钻。
多個(gè)授權(quán):(用逗號(hào)隔開)
GRANT SELECT, INSERT ON db_name.* TO user_name;
GRANT 和 REVOKE 可在幾個(gè)層次上控制訪問權(quán)限:
- 整個(gè)服務(wù)器掸屡,使用GRANT ALL 和 REVOKE ALL
- 整個(gè)數(shù)據(jù)庫(kù),使用 ON databaseName.*
- 特定的表然评,使用 ON databaseName.tableName
- 特定的列
- 特定的存儲(chǔ)過程
MySQL的權(quán)限表: