msql 學(xué)習(xí)筆記整理

學(xué)習(xí)mysql的幾天,將筆記整理一下

SQL(Structured Query Language): 結(jié)構(gòu)化查詢語言。

數(shù)據(jù)庫軟件稱為: DBMS(數(shù)據(jù)管理系統(tǒng)庫)

DBMS可分為兩類:

  • 基于共享文件系統(tǒng)的DBMS。Microsoft Access、FileMaker
  • 基于客戶機(jī)——服務(wù)器的DBMS。MySQL、Oracle、Microsoft SQL Server

數(shù)據(jù)庫(database): 數(shù)據(jù)庫是一個(gè)以某種有組織的方式存儲(chǔ)的數(shù)據(jù)集合。通常是一個(gè)文件或一組文件。

(table): 是一種結(jié)構(gòu)化的文件,可用來存儲(chǔ)某種特定類型的數(shù)據(jù)。數(shù)據(jù)庫中的每個(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ù)庫管理軟件。

MySQL的特點(diǎn):

  1. 可伸縮性(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ù)庫或表的SQL語句
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 語句,能夠更動(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)。

  1. 不要過度使用通配符,如果其他的操作符能達(dá)到相同的目的,應(yīng)該使用其他的操作符。
  2. 除非絕對(duì)有必要,否則不要把他們用在搜索模式的開始處,搜索起來是最慢的。
  3. 注意使用通配符所在位置。
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排除的行不包括在分組中。

子查詢

子查詢:嵌套在其他查詢語句中的查詢

聯(lián)結(jié)

foreign key
外鍵:為某個(gè)表中的一列,它包含另一個(gè)表的主鍵值,定義了兩個(gè)表之間的關(guān)系。


聯(lián)結(jié)
是一種機(jī)制,用來在一條 SELECT 語句中關(guān)聯(lián)表。
使用特殊語法,可以聯(lián)結(jié)多個(gè)表返回一組輸出。聯(lián)結(jié)在運(yùn)行時(shí)關(guān)聯(lián)表中正確的行。

聯(lián)結(jié)在實(shí)際的數(shù)據(jù)庫表中并不存在,聯(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語句中可以聯(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é)通常作為外部語句用來代替從相同表中檢索數(shù)據(jù)時(shí)使用的子查詢語句。

自然聯(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語句。
MySQL也允許執(zhí)行多個(gè)查詢(多條SELECT語句),并將結(jié)果作為單個(gè)查詢結(jié)果集返回。

有兩種情況需要使用組合查詢:

  1. 在單個(gè)查詢中從不同的表返回類似結(jié)構(gòu)的數(shù)據(jù)。
  2. 對(duì)單個(gè)表執(zhí)行多個(gè)查詢,按單個(gè)查詢返回?cái)?shù)據(jù)。

UNION

  1. 必須由兩條或兩條以上的SELECT語句組成,SELECT語句之間用UNION關(guān)鍵字分割。
  2. UNION中的每個(gè)查詢必須包含相同的列,表達(dá)式或聚集函數(shù)(各個(gè)列不需要以相同的次序列出)。
  3. 列數(shù)據(jù)類型必須兼容,類型不必完全相同,但必須是DBMS可以隱含轉(zhuǎn)換的類型(例如不用的數(shù)值類型或不同的日期類型)。

消掉重復(fù)的行:

UNION 默認(rèn)返回結(jié)果會(huì)消掉重復(fù)的行;
UNION ALL 則不消掉重復(fù)的行。


對(duì)組合查詢結(jié)果進(jìn)行排序:

SELECT語句的輸出用order by 語句排序,再用 UNION 組合查詢時(shí),只能使用一條 order by子句,
它必須出現(xiàn)在最后一條SELECT語句之后。


可以組合不同的表

插入數(shù)據(jù)

再插入數(shù)據(jù)時(shí)需要注意的問題:

  1. 一般使用明確給出列的列表的insert語句。即使表結(jié)構(gòu)發(fā)生改變,也可以正確插入。
  2. 省略某些列:
    省略列必須滿足以下的條件:
    該列定義為允許NULL值(無值或空值)。
    在表的定義中給出默認(rèn)值。

不滿足上述的條件則會(huì)產(chǎn)生一條錯(cuò)誤的消息,并且相應(yīng)的行插入不成功。

  1. 使用 insert low_priority into 語句可以指示mysql降低insert語句的優(yōu)先級(jí)。
    因?yàn)閕nsert語句執(zhí)行很耗時(shí),這樣可以提高性能。
    這也適用于update和delete語句。

  2. 插入檢索出的數(shù)據(jù)

insert into table_name(column_name1, column_name2,...) 
values(value1, value2...)
select column_nam1, column_name2,... from table_name;
更新語句

update table_name set colunm_name1=value1, column_name2=value2,... where 過濾條件;

如果用 update 更新語句更新多行,并且在更新這些行找中的一行或者多行出現(xiàn)錯(cuò)誤,則整個(gè)的update操作將被取消。
為了即使是發(fā)生了錯(cuò)誤,也繼續(xù)進(jìn)行更新,可使用 ignore 關(guān)鍵字。
update ignore table_name set....;

刪除語句

delete from table_name where 過濾條件;

  1. delete語句刪除表中的行,甚至是所有的行,但是不刪除表本身。
  2. 若想要更快的刪除表中的所有數(shù)據(jù),可使用:
    truncate table 語句,(實(shí)際是刪除了原來的表并重新創(chuàng)建了一個(gè)表,而不是逐行刪除表中的數(shù)據(jù))。

對(duì)于表的操作

創(chuàng)建表:
create table [IF NOT EXISTS] table_name();

更新表:
alert table table_name 要操作的語句;

添加一個(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é):

  1. 要匹配的詞
  2. 要排斥的詞(某行包含該詞將不返回)
  3. 排列提示(指定某些詞比其他詞更重要,重要的詞等級(jí)更高)
  4. 表達(dá)式分組
  5. 另外的一些內(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è)短語

視圖

MySQL5 增加了對(duì)視圖的支持。

視圖(View):是虛擬的表,與包含數(shù)據(jù)的表不一樣,視圖只包含使用時(shí)動(dòng)態(tài)檢索數(shù)據(jù)的查詢。

視圖的一些常見應(yīng)用:

  1. 重用SQL語句。
  2. 簡(jiǎn)化復(fù)雜的SQL操作。在編寫查詢后,可以方便的重用他而不必知道它的基本查詢細(xì)節(jié)。
  3. 使用表的組成部分而不是整個(gè)表。
  4. 保護(hù)數(shù)據(jù)。可以給用戶授予表的特定部分的訪問權(quán)限而不是整個(gè)表的訪問權(quán)限。
  5. 更改數(shù)據(jù)格式和表示。視圖可返回與底層表的表示和格式不同的數(shù)據(jù)。

在視圖創(chuàng)建之后,可以用域表基本相同的操作方式來來操作它。
可以對(duì)視圖執(zhí)行select操作,過濾、排序、聯(lián)結(jié)到其他視圖或表、添加數(shù)據(jù)、更新數(shù)據(jù)(添加和更新數(shù)據(jù)存在某些限制)。


視圖的規(guī)則和限制:

  1. 視圖必須唯一命名。
  2. 對(duì)于可以創(chuàng)建的視圖數(shù)目沒有限制。
  3. 為了創(chuàng)建視圖,必須具有足夠的訪問權(quán)限。通常由數(shù)據(jù)庫管理人員授予。
  4. 視圖可以嵌套。即可以使用視圖中的檢索查詢來構(gòu)造一個(gè)視圖。
  5. order by 可以用在視圖中,但如果從該視圖中檢索數(shù)據(jù)的select中也含有order by,
    那么該視圖中的order by 將被覆蓋。
  6. 視圖不能索引,也不能有關(guān)聯(lián)的觸發(fā)器和默認(rèn)值。
  7. 視圖可以和表一起使用。比如和表聯(lián)結(jié)。

創(chuàng)建視圖:
create view as select語句

查看創(chuàng)建的視圖:
show create view view_name;

刪除視圖:
drop view view_name;

更新視圖:

  1. 先使用drop,在用create
  2. 直接使用 create or replace view
    如果要更新的視圖不存在,該語句會(huì)創(chuàng)建一個(gè)視圖;
    如果要更新的視圖存在,該語句會(huì)替換原有的視圖。

視圖是可更新的(insert、update、delete),更新一個(gè)是將更新其基表。

并非所有的視圖都是可更新的,如果視圖定義中有如下的操作,則不能進(jìn)行視圖的更新:

  1. 分組(使用group by或 having)
  2. 聯(lián)結(jié)
  3. 子查詢
  4. 聚集函數(shù)
  5. distinct
  6. 導(dǎo)出(計(jì)算)列

注意:一般應(yīng)該將視圖用于檢索,而不是更新。

存儲(chǔ)過程

MySQL5增加了對(duì)存儲(chǔ)過程的支持。

存儲(chǔ)過程:為以后的使用而保存的一條或多條MySQL語句的集合。

為什么要使用存儲(chǔ)過程:

  1. 通過把處理封裝在容易使用的單元中,簡(jiǎn)化復(fù)雜的操作。
  2. 不再反復(fù)建立一系列的處理步驟,保證了數(shù)據(jù)的完整性。
    比如,開發(fā)人員和應(yīng)用程序都使用同一存儲(chǔ)過程,則所使用的代碼都是相同的。這樣就保證數(shù)據(jù)的一致性,不容易出錯(cuò)。
  3. 簡(jiǎn)化對(duì)變動(dòng)的管理。如表名、列名、或業(yè)務(wù)邏輯等有變化,只需改動(dòng)存儲(chǔ)過程的代碼。
  4. 提高性能。
  5. 存儲(chǔ)過程可以用來編寫功能更強(qiáng)更靈活的代碼。

創(chuàng)建存儲(chǔ)過程需要訪問權(quán)限,這通常是由數(shù)據(jù)庫管理員賦予。


創(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語句:

show create procedure procedure_name;

獲得詳細(xì)的存儲(chǔ)信息列表:

show procedure status;

游標(biāo)

MySQL5添加了對(duì)游標(biāo)的支持。

MySQL檢索操作返回一組稱為結(jié)果集的行。返回的行都是與sql語句相匹配的行(零行或多行)。有的時(shí)候是需要在檢索出來的行中前進(jìn)或后退一行或多行,使用簡(jiǎn)單的select語句是沒有辦法得到的。這就是使用游標(biāo)的原因了。

游標(biāo)(cursor):是一個(gè)存儲(chǔ)在mysql服務(wù)器上的數(shù)據(jù)庫查詢,它不是一條select語句。而是被該語句檢索出來的結(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)的步驟:

  1. 在使用游標(biāo)前必須聲明(定義)它,這個(gè)過程實(shí)際上沒有檢索數(shù)據(jù),它只是定義要使用的select語句。
  2. 一旦聲明后,必須打開游標(biāo)以供使用。這個(gè)過程要用到前面定義的select語句把數(shù)據(jù)實(shí)際檢索出來。
  3. 對(duì)于填有數(shù)據(jù)的游標(biāo),根據(jù)需要取出(檢索)各行。
  4. 在結(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 語句。

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語句時(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ā)器的支持。

想要某條語句(或某些語句)在事件發(fā)生時(shí)自動(dòng)執(zhí)行,這時(shí)就用到了觸發(fā)器。

觸發(fā)器:是MySQL響應(yīng)以下任意一條語句而自動(dòng)執(zhí)行的一條SQL語句(或位于BEGIN 和 END語句之間的一組語句 )。

  1. delete
  2. update
  3. insert

其他的語句不支持觸發(fā)器。

注意:只有表支持觸發(fā)器,視圖不支持(臨時(shí)表也不支持)。


創(chuàng)建觸發(fā)器:

在創(chuàng)建觸發(fā)器時(shí)的 4 部分:

  1. 唯一的觸發(fā)器名。(在表中唯一)建議:在數(shù)據(jù)庫中使觸發(fā)器名唯一。
  2. 觸發(fā)器關(guān)聯(lián)的表。
  3. 觸發(fā)器應(yīng)該響應(yīng)的事件(delete、update、insert)。
  4. 觸發(fā)器何時(shí)執(zhí)行after|before(處理之前或之后)。
CREATE TRIGGER newproduct   // 創(chuàng)建名為newproduct的觸發(fā)器
AFTER INSERT ON products    // 在insert語句成功執(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ù)庫的完整性,它保證成批的MySQL操作要么完全執(zhí)行,要么完全不執(zhí)行。

事務(wù)處理是一種機(jī)制。

在事務(wù)處理中的幾個(gè)術(shù)語:
事務(wù)(transaction):一組SQL語句。
回退(rollback):撤銷指定SQL語句的過程。
提交(commit):將未存儲(chǔ)的SQL語句結(jié)果寫入到數(shù)據(jù)庫。
保留點(diǎn)(savepoint):事務(wù)處理中設(shè)置的臨時(shí)占位符(placeholder),你可以對(duì)它發(fā)布回退(與回退整個(gè)事務(wù)處理不同,是部分的)。


控制事務(wù)處理:

管理事務(wù)處理的關(guān)鍵在于將SQL語句組分解為邏輯塊,并明確規(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語句之后)。

注意:事務(wù)處理用來管理insert、update、delete,不能回退select語句。
也不能回退create或drop操作,在事務(wù)處理塊中可以有這兩條語句,但如果你執(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 語句執(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):

  1. 在執(zhí)行一條rollback 或 commit后自定釋放保留點(diǎn)。
  2. 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ù)庫活動(dòng)中,不需要操心太多的東西,使用何種字符局和校對(duì),決定在服務(wù)器、數(shù)據(jù)庫和表級(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ù)庫中。

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ù)庫所有表的select權(quán)限。

GRANT要求至少要給出以下信息:

  1. 要授予的權(quán)限。
  2. 被授予訪問權(quán)限的數(shù)據(jù)庫或表。
  3. 用戶名。
撤銷特定的權(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)限:

  1. 整個(gè)服務(wù)器,使用GRANT ALL 和 REVOKE ALL
  2. 整個(gè)數(shù)據(jù)庫,使用 ON databaseName.*
  3. 特定的表,使用 ON databaseName.tableName
  4. 特定的列
  5. 特定的存儲(chǔ)過程

MySQL的權(quán)限表:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前言 讀《sql必知必會(huì) 第四版》隨手做的筆記,寫的比較亂,可讀性并不好,讀的是中文版,翻譯過來的感覺有點(diǎn)怪怪的。...
    _老徐_閱讀 761評(píng)論 0 0
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,638評(píng)論 18 399
  • 文/陳練 我曾經(jīng)有過一次約稿,某個(gè)公眾號(hào)要我寫讀書的意義,我寫了大概1萬多字的時(shí)候,我發(fā)現(xiàn)我無可避免地陷入一種大而...
    陳練閱讀 760評(píng)論 2 9
  • [鼓掌][鼓掌][鼓掌][鼓掌]盛世贏家《營(yíng)銷策劃系統(tǒng)》大課第三天,精彩一波接一波! 定價(jià)是一種藝術(shù),做企業(yè)是一種...
    好彩妹閱讀 260評(píng)論 0 0
  • 閻云向那個(gè)房間邊走邊思考等會(huì)自己要怎樣才能把那十三個(gè)人都怔住,或者怎樣才能打贏他們,就在接近那個(gè)房間時(shí)閻云突然聞到...
    野性浮云閱讀 262評(píng)論 1 2

友情鏈接更多精彩內(nèi)容