1. 程式人生 > >mysql複習筆記

mysql複習筆記

 --   註釋
//自增插入資料,必須一一對應表的每一個數據列,不可空出來。
CREATE TABLE class(id int PRIMARY KEY auto_increment,
sname VARCHAR(50) not null DEFAULT '');
# 插入改INSERT INTO class(sname) VALUES('豆豆');
INSERT INTO class VALUES(null,'123d ');
INSERT INTO class(name,sex) VALUES('123d ','nan'); //id自增這裡可以省略id項

//提高整體效能  LOW_PRIORITY  插入耗時影響select效能的時候使用
//INSERT LOW_PRIORITY INTO
//單條 INSERT 語句處理多個插入比使用多條 INSERT語句快。


#一次性insert 多行 逗號隔開即可
INSERT INTO class VALUES(null,'我'),(null,'是');
//update     UPDATE class SET id=8,sname ='是我' WHERE id = 7;       where  表示式;  表示式為真就修改
//delete     delete from  class  where id = 7;   
//# truncate 表名;  delete 區別  前者複製表的結構,刪除舊錶 後者刪行記錄
// SELECT sname,id from class where id = 6;
建表 即宣告欄位

//欄位型別
數值型
   整型
       Tinyint//為 1 位元組 -128    127
       smallint//2 個位元組
       mediumint//一箇中等大小整數,有符號的範圍是-8388608到8388607,無符號的範圍是0到16777215。 一位大小為3個位元組。
       int//一個正常大小整數。有符號的範圍是-2^31 (-2,147,483,648) 到 2^31 - 1 (2,147,483,647) 的整型資料(所有數字),無符號的範圍是0到4294967295。一位大小為 4 個位元組。
int 的 SQL-92 同義詞為 integer。
  bigint//從 -2^63 (-9223372036854775808) 到 2^63-1 (9223372036854775807) 的整型資料(所有數字),無符號的範圍是0到18446744073709551615。一位為 8 個位元組  
//zerofill 必須是unsigned型別      /資料型別(M)zerofill/ M 的解析  補0寬度
 小數(浮點/定點型)    
Float(M,D)    decimal(M,D) // M為標度 代表小數總位數  D代表精度 代表小數點右邊的位數
//Float(6,2)   -9999.99  9999.99    無符號的話 0   9999.99
//decimal(M,D)  為定點型 整數小數 分開儲存比float精確 資料過長float會損失精度
字串  
//char(M)   varchar(M)  text文字型別   blob存影象音訊等二進位制資訊防止因為字符集的問題導致資訊丟失
//定長 查詢快速 浪費空間   不夠N補空格到N,取出時刪除右側所有空格    利用率<=100%              M 0 255  限制的是字元而不是位元組
//變長 相對慢    節約空間   增刪效率低  資料前會有一個標識位1-2byte 標記往後讀幾個字元 利用率<100%     M 0 65535
    
日期型別  date  能儲存1000-01-01 到 9999-12-31  沒有資料可以修為特殊值 0000-00-00   3byte
時間型別time  20:20:20     3byte          // year  1byte  1901-2155 未填為0000
日期時間型別datetime  YYYY-mm-dd HH:ii:ss    8byte 
timestamp  和時間型別相同 不賦值的或可以   ts timestamp default CURRENT_TIMESTAMP    4byte

 

增加列
alter table 表名 add 列名 列型別 列引數;    --加的列在表的最後

alter table 表名 add 列名 列型別 列引數 after 某列;
alter table 表名 add 列名 列型別 列引數 first;

刪除列
alter table 表名 drop 列名

修改列的型別引數
alter table 表名 modify 列名 列型別 列引數;

修改列的名字型別番薯
alter table 表名 change 舊列名 新列名 新列型別 新列引數



重命名錶名
ALTER TABLE user10 RENAME TO user11;
RENAME TABLE user11 TO user10;

                                                                               a desc,b asc 先a降序,在b升序排序

select 5種子句                                                  desc   asc升(預設)       2,3   跳過兩條,取接下來的兩條

where 條件,group by 分組,having 篩選,order by排序,limit限制結果條數

order by a,b;
重要的是理解在按多個列排序時,排序的順序完全按規定進行。換句話說,對於上述例子中的輸出,僅在多個行具有相同的prod_price值時才
對產品按prod_name進行排序。如果prod_price列中所有的值都是唯一的,則不會按prod_name排序
SELECT prod_id, prod_price, prod_name
FROM Products
ORDER BY 2, 3;
 等價於   prod_price,prod_name;

為什麼要使用IN操作符?其優點為:
在有很多合法選項時,IN操作符的語法更清楚,更直觀。
在與其他AND和OR操作符組合使用IN時,求值順序更容易管理。
IN操作符一般比一組OR操作符執行得更快(在上面這個合法選項很少的例子中,你看不出效能差異)。
IN的最大優點是可以包含其他SELECT語句,能夠更動態地建立WHERE子句。第 11 課會對此進行詳細介紹。

子查詢的SELECT語句只能查詢單個列。企圖檢索多個列將返回錯誤

 

    where    列不變   計算分組別名,列可能改變      having                       order排序limit

表----->滿足條件的行---------------------------->結果集-------->最終結果集-------------->    

and ||  優先順序比  or &&高      in   not !        between...and包括邊界值              列為變數

!=   <>      欄位 as 別名

  like  xx%      _匹配一個   %多個    '[JM]%'   J或M開頭  用 ^否定   '[^JM]%'
                                     僅sqlserver支援 

where只對表中的資料起作用,為表示式,不能對查詢結果起作用必須用having

例如 select user as name from test where name = ‘xxx’;        錯    誤

使用COUNT(*)對錶中行的數目進行計數,不管表列中包含的是空值(NULL)還是非空值。
使用COUNT(column)對特定列中具有值的行進行計數,忽略NULL值。

文字資料時,MIN()返回該列排序後最前面的行MAX同
DISTINCT  ALL
SELECT AVG(DISTINCT prod_price) AS avg_price
FROM Products
WHERE vend_id = 'DLL01';
DISTINCT 不能用於 COUNT(*)
如果指定列名,則DISTINCT只能用於COUNT()。DISTINCT不能用於COUNT(*)。類似地,DISTINCT必須使用列名,不能用於計算或表示式。
TOP和TOP PERCENT。
GROUP  BY與統計函式  
max()        文字資料時返回最後一行    函式忽略列值為 NULL 的行
 min()        文字資料時返回第一行   函式忽略列值為 NULL 的行
sum()                                 函式忽略列值為 NULL 的行
avg()       函式忽略列值為 NULL 的行
count(*)    絕對行數 ,(列名)欄位不統計null


 只包含不同的值,指定 DISTINCT 引數  不指定 DISTINCT ,則假定為 ALL

select AVG(DISTINCT  prices) from goods where id = 100;
DISTINCT 只能用於 COUNT()  不能用於 COUNT(*)  類似地, DISTINCT 必須使用列名

select id,sum(prices )from goods group by id  ;         id有多少組

GROUP  BY a,b,c; select中查詢的欄位一般而言只能從abc中選擇

1.求平均分,並且掛科兩門以上的學生  表名result   name,score,course

select name,avg(score) from result group by name;

select name,course,score,score<60 as guake from result;

select name,avg(score),sum(score<60) as g from result group by name having g>=2

字串拼接  concat(str1,str2,...)   若有一個為空,則查詢為空

     concat_ws(separator,str1,str2,...)   用分隔符分開  分隔符為NULL,則返回結果為
NULL ,引數中存在NULL,則會被忽略

      ifnull(str,設定)  str為空則用設定的值代替    
      rtrim(),ltrim()  去左右空格    

SUBSTRING()  
CONVERT()資料型別轉換   
CURDATE()     
UPPER()  
LOWER()    
LENGTH() 
Locate() 找出串的子串
LEFT(str,n)  左邊數n個字元   RIGTH(str,n)  
SELECT  sname FROM student where SOUNDEX(sname) = SOUNDEX('小')
   Soundex() 是一個將任何文字串轉換為描述其語音表示的字母數字模式的演算法

sname   中發音類似   小  的

SELECT order_num
FROM Orders
WHERE YEAR(order_date) = 2012;    year()取年

Abs()  返回一個數的絕對值
Cos()  返回一個角度的餘弦
Exp()  返回一個數的指數值
Mod()  返回除操作的餘數
Pi()  返回圓周率
Rand()  返回一個隨機數
Sin()  返回一個角度的正弦
Sqrt()  返回一個數的平方根
Tan()  返回一個角度的正切

 

AddDate()  增加一個日期(天、周等)
AddTime()  增加一個時間(時、分等)
CurDate()  返回當前日期
CurTime()  返回當前時間
Date()  返回日期時間的日期部分
DateDiff()  計算兩個日期之差
Date_Add()  高度靈活的日期運算函式
Date_Format()  返回一個格式化的日期或時間串
Day()  返回一個日期的天數部分
DayOfWeek()  對於一個日期,返回對應的星期幾
Hour()  返回一個時間的小時部分
Minute()  返回一個時間的分鐘部分
Month()  返回一個日期的月份部分
Now()  返回當前日期和時間
Second()  返回一個時間的秒部分
Time()  返回一個日期時間的時間部分
Year()  返回一個日期的年份部分
等值聯結( equijoin )也稱為內聯結( inner join )   聯結的表越多,效能下降越厲害
SELECT vend_name, prod_name, prod_price
FROM Vendors INNER JOIN Products
ON Vendors.vend_id = Products.vend_id;

SELECT vend_name, prod_name, prod_price
FROM Vendors, Products
WHERE Vendors.vend_id = Products.vend_id;
自聯結( self-join )  用自聯結而不用子查詢
SELECT c1.cust_id, c1.cust_name, c1.cust_contact
FROM Customers AS c1, Customers AS c2
WHERE c1.cust_name = c2.cust_name
AND c2.cust_contact = 'Jim Jones';

SELECT cust_id, cust_name, cust_contact
FROM Customers
WHERE cust_name = (SELECT cust_name
FROM Customers
WHERE cust_contact = 'Jim Jones');   找到jim工作公司,找到公司的所有人

自然連線    自然聯結排除多次出現,使每個列只返回一次
通過MySql自己的判斷完成連線過程,不需要指定連線條件。MySql會使用表內的,相同的欄位,作為連線條件
select * from student natural join paper;
select * from student natural left join paper;

SELECT c.*,o.id,o.num from cus as c,order as o where c.id = o.id and o.name = 'xx';


外聯結( outer join )
全連線(全外連線)
MySQL目前不支援此種方式,可以用其他方式替代解決
 
left join是以A表的記錄為基礎的,A可以看成左表,B可以看成右表,left join是以左表為準的.  
換句話說,左表(A)的記錄將會全部表示出來,而右表(B)只會顯示符合搜尋條件的記錄(例子中為: 
A.aID = B.bID).  B表記錄不足的地方均為NULL.  
右同理

select * from a_table as a left join b_table as b on a.a_id = b.b_id;
#並( union )或 複合查詢( compound query )
UNION 用於合併兩個或多個 SELECT 語句的結果集,並消去表中任何重複行。
SELECT column_name FROM table1
UNION ALL
SELECT column_name FROM table2

1、UNION 結果集中的列名總是等於第一個 SELECT 語句中的列名
2、UNION 內部的 SELECT 語句必須擁有相同數量的列。列也必須擁有相似的資料型別。同時,
   每條 SELECT 語句中的列的順序必須相同

如果不想去掉重複的行,可以使用union all。
如果子句中有order by,limit,需用括號()包起來。推薦放到所有子句之後,即對最終合併的結果來排序或篩選。
(select * from a order by id) union (select * from b order id)

 複製表

1.複製表結構及資料到新表
    create table 新表 select * from 舊錶 
2.只複製表結構到新表
方法1:(低版本的mysql不支援,mysql4.0.25 不支援,mysql5已經支援了)
    create table 新表 like 舊錶 
方法2:
    create table 新表 select * from 舊錶 limit 0
方法3:
    create table 新表 select * from 舊錶 where 不成立條件
3.複製舊錶的資料到新表
1、(假設兩個表結構一樣)
    insert into 新表 select * from 舊錶 
2、(假設兩個表結構不一樣)
    insert into 新表(欄位1,欄位2,…….) select 欄位1,欄位2,…… from 舊錶
更新表
UPDATE Customers                    //若一行出現錯誤整個 UPDATE 操作被取消
SET cust_contact = 'Sam Roberts',
cust_email = '[email protected]'
WHERE cust_id = '1000000006';

UPDATE IGNORE Customers                //若一行出現錯誤忽略繼續修改後面的行
SET cust_contact = 'Sam Roberts',
cust_email = '[email protected]'
WHERE cust_id = '1000000006';




刪除表
DELETE FROM Customers
WHERE cust_id = '1000000006';
                                    truncate table
表中刪除所有行,不要使用DELETE。可使用TRUNCATE TABLE語句,它完成相同的工作,而速度更快(因為不記錄資料的變動)。           刪除原來的表並重新建立一個表 而不是逐行刪除表中的資料


CREATE TABLE Products
(
prod_id CHAR(10) NOT NULL,
vend_id CHAR(10) NOT NULL,
prod_name CHAR(254) NOT NULL DEFAULT ‘’,
prod_price DECIMAL(8,2) NOT NULL,
prod_desc text NULL
);
     LIKE 匹配整個串而 REGEXP 匹配子串 
正則表示式    可以用   |   &  連線多個表示式
select * from dept where dname regexp ‘正則表示式’;

select * from dept where dname regexp BINARY ‘正則表示式’;  //使用BINARY區分大小寫

 [1|2|3] Ton  =  [123] Ton   =[1-3] Ton    
 .   代表任一字元   查詢‘ . ’  需要用轉義符號    \\. 

[:alnum:]  任意字母和數字(同[a-zA-Z0-9])
[:alpha:]  任意字元(同[a-zA-Z])
[:blank:]  空格和製表(同[\\t])
[:cntrl:]  ASCII控制字元(ASCII 0到31和127)
[:digit:]  任意數字(同[0-9])
[:graph:]  與[:print:]相同,但不包括空格
[:lower:]  任意小寫字母(同[a-z])
[:print:]  任意可列印字元
[:punct:]  既不在[:alnum:]又不在[:cntrl:]中的任意字元
[:space:]  包括空格在內的任意空白字元(同[\\f\\n\\r\\t\\v])
[:upper:]  任意大寫字母(同[A-Z])
[:xdigit:]  任意十六進位制數字(同[a-fA-F0-9])

*  0個或多個匹配
+  1個或多個匹配(等於{1,})
?  0個或1個匹配(等於{0,1})
{n}  指定數目的匹配
{n,}  不少於指定數目的匹配
{n,m}  匹配數目的範圍(m不超過255)

select * from dept where dname regexp  ‘\\([0-9] sticks?\\)’;
[0-9] 匹配任意數字 
 ? 匹配它前面的任何字元的0次或1次出現   sticks?   ->  s出現0次或1次

select * from dept where dname regexp  ‘[[:digit:]]{4}’; 
    匹配連在一起的任意4位數字 出現4次 如:1000    =  [0-9][0-9][0-9][0-9]

^  文字的開始     ^[0-9\\.]  搜尋以 一個數字 或 .   開頭
$  文字的結尾
[[:<:]]  詞的開始
[[:>:]]  詞的結尾



外來鍵(foreign key) 外來鍵為某個表中的一列,它包含另一個表的主鍵值,定義了兩個表之間的關係.
    1.供應商資訊不重複,從而不浪費時間和空間;
    2.如果供應商資訊變動,可以只更新 vendors 表中的單個記錄,相
      關表中的資料不用改動;
    3.由於資料無重複,顯然資料是一致的,這使得處理資料更簡單。
MyISAM 和 InnoDB    
    前者支援全文字搜尋,而後者不支援           搜尋不區分大小寫 除非使用 BINARY 方式
    使用兩個函式 Match() 和 Against() 執行全文字搜尋
     Match(note_text)  指示MySQL針對指定的列進行搜尋
         Match() 的值必須與FULLTEXT() 定義中的相同指定多個列必須列出而且次序正確
     Against('rabbit') 指定詞 rabbit 作為搜尋文字由於有兩行包含詞 rabbit ,這兩個行被返回

    SELECT 可與 Match() 和 Against() 一起使用
啟用全文字索引
    create table productnotes
    {
        note_id int not null auto_increament,
        note_text text null,
        primary key(note_id),
        fulltext(note_text)    //啟用 全文字搜尋
    }engine=MyISAM;

select note_text,match(note_text) against('rabbit') as rank from productnotes;

兩個行都包含詞 rabbit ,但包含詞 rabbit 作為第3個詞的行的等級比作為第20個詞的行高    
  等級的行先返回

指定多個搜尋項,則包含多數匹配詞的那些行先返回


查詢擴充套件,能找出可能相關的結果   表中的行越多查詢擴充套件返回的結果越好
select note_text  from productnotes 
where match(note_text) against('rabbit' with query expansion) ;


布林文字搜尋   沒有 FULLTEXT 索引也可以使用  非常緩慢
select note_text  from productnotes 
where match(note_text) against('rabbit -rope*' in boolean mode) ;
搜尋包含rabbit 不包含 rope-  開頭的行

+  包含,詞必須存在
-  排除,詞必須不出現
>  包含,而且增加等級值
<  包含,且減少等級值
()  把片語成子表示式(允許這些子表示式作為一個組被包含、
排除、排列等)
~  取消一個詞的排序值
*  詞尾的萬用字元
""  定義一個短語(與單個詞的列表不一樣,它匹配整個短語以
便包含或排除這個短語)

select note_text  from productnotes 
where match(note_text) against('+rabbit +rope' in boolean mode) ;
包含 rabbit和rope

select note_text  from productnotes 
where match(note_text) against('rabbit rope' in boolean mode) ;
包含 rabbit或rope

select note_text  from productnotes 
where match(note_text) against('"rabbit rope"' in boolean mode) ;
包含rabbit rope


以下是幾個需要知道的引擎:        // 外來鍵不能跨引擎
 InnoDB 是一個可靠的事務處理引擎(參見第26章),它不支援全文
本搜尋;
 MEMORY 在功能等同於 MyISAM ,但由於資料儲存在記憶體(不是磁碟)
中,速度很快(特別適合於臨時表);
  MyISAM 是一個性能極高的引擎,它支援全文字搜尋(參見第18章),
但不支援事務處理

檢視

重用SQL語句。
  1.簡化複雜的SQL操作。在編寫查詢後,可以方便地重用它而不必
知道它的基本查詢細節。
   2.使用表的組成部分而不是整個表。
   3.保護資料。可以給使用者授予表的特定部分的訪問許可權而不是整個
表的訪問許可權。
   4.更改資料格式和表示。檢視可返回與底層表的表示和格式不同的
資料。



1.與表一樣,檢視必須唯一命名(不能給檢視取與別的檢視或表相
同的名字)。
 2.對於可以建立的檢視數目沒有限制。
 3. 為了建立檢視,必須具有足夠的訪問許可權。這些限制通常由資料
庫管理人員授予。
  4. 檢視可以巢狀,即可以利用從其他檢視中檢索資料的查詢來構造
一個檢視。
  5. ORDER BY 可以用在檢視中,但如果從該檢視檢索資料 SELECT 中也
含有 ORDER BY ,那麼該檢視中的 ORDER BY 將被覆蓋。
  6.檢視不能索引,也不能有關聯的觸發器或預設值。
  7. 檢視可以和表一起使用。例如,編寫一條聯結表和檢視的 SELECT
語句。


CREATE VIEW  建立
SHOW CREATE VIEW viewname   檢視建立檢視的語句
DROP VIEW viewname
CREATE OR REPLACE VIEW 更新檢視

create view as select name,id,sex from class where class.id=dept.id;


檢視定義中有以下操作,則不能進行檢視的更新
  分組(使用 GROUP BY 和 HAVING );
  聯結;
  子查詢;
  並;
  聚集函式( Min() 、 Count() 、 Sum() 等);
  DISTINCT;
  匯出(計算)列。

儲存過程

1.簡化複雜的操作
2.不要求反覆建立一系列處理步驟,這保證了資料的完整性  防止錯誤保證了資料的一致性
3.簡化對變動的管理 如果表名、列名或業務邏輯(或別的內容)有變化,只需要更改儲存過程的程式碼
  安全性 限制對基礎資料的訪問減少了資料訛誤
4.提高效能。因為使用儲存過程比使用單獨的SQL語句要快
5.存在一些只能用在單個請求中的MySQL元素和特性儲存過程可以使用它們來編寫功能更強更靈活的程式碼

create procedure productpricing()     //儲存過程名productpricing
begin
    select avg(prod_price) as priceaverage
    from product;
end;

呼叫
call  productpricing();

刪除
drop procedure productpricing;


create procedure productpricing(out p1 deciaml(8,2),out p1 deciaml(8,2))    
begin
    select min(prod_price) into p1
    from product;
    select max(prod_price) into p2
    from product;
end;

call  productpricing(@p1,@p2);

select @p1,@p2;

//pl 儲存產品min價格   p2 儲存產品max價格
//關鍵字 OUT 指出相應的引數用來從儲存過程傳出一個值(返回給呼叫者)
// IN (傳遞給儲存過程) OUT (從儲存過程傳出,如這裡所用)  INOUT (對儲存過程傳入和傳出)
//  COMMENT 註釋    SHOW PROCEDURE STATUS  (like )'儲存過程名' 的結果中顯示
//IF   THEN   ELSEIF 和 ELSE 

觸發器

只有表才支援觸發器,檢視、臨時表 不支援   每個表最多支援6個觸發器

觸發器是MySQL響應以下任意語句 自動執行的一條MySQL語句
  DELETE ;
  INSERT ;
  UPDATE 

  唯一的觸發器名;
  觸發器關聯的表;
  觸發器應該響應的活動( DELETE 、 INSERT 或 UPDATE );
  觸發器何時執行(處理之前或之後)。

create trigger newproduct after insert on products
for each row select 'Product added';
//  建立名為 newproduct 的新觸發器        after insert 在 INSERT 語句成功執行後執行
// for each row 對每個插入行執行
// select 'Product added'  顯示 Product added 訊息

如果 BEFORE 觸發器失敗,不執行請求的操作              BEFORE 用於資料驗證和淨化
BEFORE 觸發器或語句本身失敗,不執行 AFTER 觸發器

//使用虛擬表
create trigger newproduct after insert on products
for each row select NEW.pname;

create trigger updatevendor before update on vendors
for each row set NEW.vend_state = Upper(NEW.vend_state)
//每次更新一個行時 NEW.vend_state 中的值(將用來更新錶行的值)都用 Upper(NEW.vend_state) 替換

刪除
drop trigger newproduct;



事務管理

來維護資料庫的完整性  不能回退 CREATE 或 DROP 操作

  事務( transaction )指一組SQL語句;
  回退( rollback )指撤銷指定SQL語句的過程;
  提交( commit )指將未儲存的SQL語句結果寫入資料庫表;
  保留點( savepoint )指事務處理中設定的臨時佔位符(place-
holder),你可以對它釋出回退(與回退整個事務處理不同)

start transaction;
rollback;  //只能在一個事務處理內使用
commit;    //僅在不出錯時寫出更改  第一條 DELETE 起作用,但第二條失敗,DELETE 不會提交

//當 COMMIT 或 ROLLBACK 語句執行後動關閉(將來的更改會隱含提交)。

savepoint name;
rollback to name;
//保留點在事務處理完成(執行一條 ROLLBACK 或COMMIT )後自動釋放可以用 RELEASE SAVEPOINT


//更改預設的提交行為    
//autocommit標誌決定是否自動提交更改 0 (假)不自動提交更改直到 autocommit 被設定為真為止
//autocommit針對每個連線  而不是伺服器
set autocommit = 0;