數(shù)據(jù)定義
基本類型:
- char(n):char是定長的椭符,也就是當(dāng)你輸入的字符小于你指定的數(shù)目時(shí)有咨,char(8)座享,你輸入的字符小于8時(shí)渣叛,它會再后面補(bǔ)空值淳衙。當(dāng)你輸入的字符大于指定的數(shù)時(shí)箫攀,它會截取超出的字符靴跛。
- varchar(n):存儲變長數(shù)據(jù)梢睛,但存儲效率沒有char高扬绪。如果一個(gè)字段可能的值是不固定長度的挤牛,我們只知道它不可能超過10個(gè)字符墓赴,把它定義為 VARCHAR(10)是最合算的诫硕。VARCHAR類型的實(shí)際長度是它的值的實(shí)際長度+1章办。為什么“+1”呢挪蹭?這一個(gè)字節(jié)用于保存實(shí)際使用了多大的長度梁厉。從空間上考慮,用varchar合適肉盹;從效率上考慮垮媒,用char合適,關(guān)鍵是根據(jù)實(shí)際情況找到權(quán)衡點(diǎn)航棱。
- Numeric(p,d):定點(diǎn)數(shù)睡雇,精度由用戶指定。有p位數(shù)字饮醇,其中d位數(shù)字在小數(shù)點(diǎn)后面它抱。
- float(n):精度至少位n位的浮點(diǎn)數(shù)
DDL Data Definition Language
create database database_name
create table r(A1 D1,A2 D2,......An Dn,完整性約束1,......,完整性約束k);
Drop table r;
Alter table r add A D; A:要添加的屬性的名字 D:要添加的屬性的類型(關(guān)系中的所有元組在該新屬性的取值將被設(shè)置為null);
create view ; alter view ; delete view;
truncate table;
truncate和delete的區(qū)別
- delete from后面可以寫條件朴艰,truncate不可以观蓄。
- delete from記錄是一條條刪的,所刪除的每行記錄都會進(jìn)日志祠墅,而truncate一次性刪掉整個(gè)頁毁嗦,因此日至里面只記錄頁釋放,簡言之,delete from更新日志巾乳,truncate基本不辑舷,所用的事務(wù)日志空間較少碌廓。
- delete from刪空表后纪挎,會保留一個(gè)空的頁烤蜕,truncate在表中不會留有任何頁橱鹏。
- 當(dāng)使用行鎖執(zhí)行 DELETE 語句時(shí)贮勃,將鎖定表中各行以便刪除泉孩。truncate始終鎖定表和頁,而不是鎖定各行。
- 如果有identity產(chǎn)生的自增id列锡溯,delete from后仍然從上次的數(shù)開始增加夕晓,即種子不變躬贡,而truncate后,種子會恢復(fù)初始。
- truncate不會觸發(fā)delete的觸發(fā)器填帽,因?yàn)閠runcate操作不記錄各個(gè)行刪除。
DML Data Manipulation Language
Delete table r;刪除關(guān)系中所有的元組
INSERT INTO table_name VALUES (值1, 值2,....);
INSERT INTO table_name (列1, 列2,...) VALUES (值1, 值2,....);
update table_name set col1='' where col2='';
DQL Data Query Language
示例數(shù)據(jù)庫結(jié)構(gòu):
![表關(guān)系圖](http://imagekaka.qiniudn.com/%E7%A4%BA%E4%BE%8B%E6%95%B0%E6%8D%AE%E5%BA%93%E7%9A%84%E8%A1%A8%E5%85%B3%E7%B3%BB.png)
Select A1,A2,......An from R1,R2,......Rm Where P;
Select distinct branch_name from loan;
在select后加入關(guān)鍵詞distinct,強(qiáng)行刪除重復(fù)睛约,SQL允許我們使用all來顯式指明不去除重復(fù):
select all branch_name from loan;
保留重復(fù)元組是默認(rèn)的
where子句
- 邏輯連詞:
and or not
- 比較運(yùn)算符:
<、<=藐翎、>末贾、>=昼扛、=浦箱、<>
- 為簡化where子句糕珊,SQL提供
between、not between
菱鸥,
Select loan_number from loan where amount (not) between 3000 and 5000;
更名運(yùn)算
Select loan_number as loan_id from loan;
Select customer_name, T.loan_number, S.amount from borrower as T, loan as S Where T.loan_number=S.loan_number;
元組變量在比較同一關(guān)系中的兩個(gè)元組時(shí)非常有用
Select T.branch_name from branch as T, branch as S Where T.assets>S.assets and S.branch_name=’....’;
字符串運(yùn)算
SQL中使用單引號來標(biāo)示字符串娶靡,如果單引號是字符串的組成部分趾诗,可以使用兩個(gè)單引號標(biāo)示:如表示“It’s right”可用:“It’’s right”來標(biāo)示。
最常見的是使用like運(yùn)算符的模式匹配(大小寫敏感):
-
%
:匹配任意子串 -
_
:匹配任意一個(gè)字符
在like比較運(yùn)算符中,使用escape關(guān)鍵字來定義轉(zhuǎn)義字符袭艺,例子:
Like ‘a(chǎn)b\%cd%’ escape ‘\’ 匹配所有以ad%cd開頭的字符串
排序
Order by desc 表示降序鼻弧,asc 表示升序,默認(rèn)升序
集合運(yùn)算
union intersect except
:并歼捏、交、非腺晾。
(select customer_name from depositor) Union (select customer_name from borrower)
表示在銀行有賬戶、有貸款或者兩者都有的客戶
Union自動除去重復(fù)哩至,如果想保留,使用union all
(如果Jeason在銀行中有三個(gè)賬戶和 兩筆貸款婆殿,那么將會有五個(gè)元組包含Jeason)
(select customer_name from depositor) intersect (select customer_name from borrower)
表示在銀行有賬戶并且有貸款的客戶
intersect自動除去重復(fù)诈乒,如果想保留,使用intersect all
(如果Jeason在銀行中有三個(gè)賬戶和兩筆貸款婆芦,那么將會有2個(gè)元組包含Jeason)
except:(oracle中為minus)
(select customer_name from depositor) except (select customer_name from borrower)
表示在銀行有賬戶但是沒有貸款的客戶怕磨。
except自動除去重復(fù),如果想保留寞缝,使用except all
(如果Jeason在銀行中有三個(gè)賬戶和兩筆貸款癌压,那么將會有1個(gè)元組包含Jeason仰泻;如果Jeason在銀行中有兩個(gè)賬戶和三筆貸款荆陆,那么結(jié)果沒有元組包含Jeason)
聚集函數(shù)
avg min max sum count
使用聚集函數(shù)是可以使用group by
和having
作為輔助:
Select branch_name,avg(balance) From account Group by branch_name;
如果在計(jì)算聚集函數(shù)前先刪掉重復(fù)元組,可以在聚集函數(shù)中使用關(guān)鍵字distinct:
找出每個(gè)支行儲戶數(shù):
Select branch_name count(distinct customer_name) From depositor,account Where depositor.account_number=account.account_number Group by branch_name;
Having
子句用于對分組的限定條件:
Select branch_name avg(balance) From account Group by branch_name Having avg(balance)>1000;
having子句中的謂詞在形成分組后才起作用集侯,因此可以使用聚集函數(shù)被啼。
如果一個(gè)查詢語句中同時(shí)存在where子句和having子句,那么SQL首先應(yīng)用where子句中的謂詞棠枉,滿足where謂詞的元組通過group by子句形成分組浓体,having子句若在,就將作用于每個(gè)分組辈讶,不符合having子句謂詞的分組將被拋棄命浴。
空值
Is null, is not null
:
Select loan_number from loan where amount is null;
如果算術(shù)運(yùn)算的輸入有一個(gè)是空值,則該算術(shù)表達(dá)式(+、-生闲、*媳溺、/)的結(jié)果是空,如果有空值參與比較運(yùn)算碍讯,SQL將比較結(jié)果看成
unknown
Unknown可以被布爾運(yùn)算符處理
Select ... From R1,R2,R3... Where P;
查詢結(jié)果中包含使得P為true的元組悬蔽,如果元組使得P的值為false或者unknown,那么該元組就不會被添加到結(jié)果中去
Is unknown , is not unknown
判斷比較結(jié)果是不是unknown
嵌套子查詢
in, not in
:
Select distinct customer_name from borrower where customer_name in (select customer_name from depositor);
some, all
Select branch_name from branch where assets > some (select assets from branch where branch_city=’Brooklyn’);
some表示至少比某一個(gè)要大
還有=some,=some和<>some(=some等價(jià)于in)
Select branch_name from branch where assets > all (select assets from branch where branch_city=’Brooklyn’);
all:比所有的都大
還有=all,=all和<>all(<>all等價(jià)于not in)
SQL中聚集函數(shù)不能進(jìn)行組合使用捉兴,因而使用max(avg(...))是不允許的
問題:找出平均余額最高的支行
Select branch_name from account group by branch_name having avg(balance)>=all(select avg(balance) from account group by branch_name);
測試是否為空關(guān)系
exists
:測試一個(gè)子查詢的結(jié)果中是否有元組,exists結(jié)構(gòu)在作為參數(shù)的子查詢非空時(shí)返回true
查找在銀行既有賬戶又有貸款的客戶
Select customer_name from borrower where exists (select * from depositor Where depositor.customer_name=borrower.customer_name)
Not exists
:可以模擬集合包含運(yùn)算
關(guān)系A(chǔ)包含B:not exists(B except A)
查找在Brooklyn所有支行都有賬戶的客戶
Select distinct S.customer_name From depositor as S Where not exists ((select branch_name from branch Where branch_city=’Brooklyn’) Except (select R.branch_name From depositor as T,account as R Where T.account_number=R.account_number and S.customer_name=T.customer_name))
測試是否存在重復(fù)元組
關(guān)鍵字:unique
蝎困,如果作為參數(shù)的子查詢的結(jié)果中沒有重復(fù)的元組,unique結(jié)構(gòu)將返回true
例:查找所有在Perryridge支行中只有一個(gè)賬戶的客戶
Select S.customer_name from depositor as S where unique (select R.customer_name from account,depositor as R where account.account_number=R.account_number and Account.branch_name=’Perryridge’ and R.customer_name=T.customer_name)
not unique
:
例:找出所有在Perryridge支行中有兩個(gè)以上賬戶的客戶
Select distinct T.customer_name from depositor as T where not unique (select R.customer_name from account,depositor as R Where account.account_number=R.account_number and Account.branch_name=’Perryridge’ and R.customer_name=T.customer_name)
復(fù)雜查詢
派生關(guān)系
as
:對from子句中的查詢表達(dá)式產(chǎn)生的結(jié)果命名
找出平均賬戶余額大于1200的支行的平均賬戶余額
Select branch_name avg_balance from (select branch_name,avg(balance) From account Group by branch_name) As branch_avg (branch_name,avg_balance) Where avg_balance>1200;
可以用于替換having子句
視圖
任何不是邏輯模型的一部分但作為虛關(guān)系對用戶可見的關(guān)系稱為視圖(view)
Create view view_name as <查詢表達(dá)式>
Create view branch_total_loan(branch_name,total_loan) as Select branch_name sum(amount) From loan Group by branch_name;
因?yàn)楸磉_(dá)式sum(amount)沒有名稱倍啥,其屬性名需要在視圖中顯示指定
視圖的一般實(shí)現(xiàn):當(dāng)我們定義一個(gè)視圖時(shí)禾乘,數(shù)據(jù)庫系統(tǒng)存儲視圖的定義本身,而不存儲定義該視圖的關(guān)系表達(dá)式的計(jì)算結(jié)果虽缕,一旦視圖關(guān)系出現(xiàn)在查詢中盖袭,他就被已存儲的關(guān)系表達(dá)式代替,因此彼宠,無論何時(shí)我們執(zhí)行這個(gè)查詢鳄虱,視圖關(guān)系都被重新計(jì)算。
物化視圖:有些特定數(shù)據(jù)庫允許視圖關(guān)系被存儲凭峡,但是它們保證如果用于定義視圖的實(shí)際關(guān)系發(fā)生改變拙已,視圖也跟著修改。
如果需要頻繁使用一個(gè)視圖摧冀,物化視圖比較合適倍踪;那些需要快速響應(yīng)基于視圖的特定查詢的應(yīng)用也是如此。
連接關(guān)系
<table>
<tr><th>連接類型</th><th>連接條件 </th></tr>
<tr><td>Inner join</td><td> Natural</td></tr>
<tr><td>Left outer join</td><td>On<謂詞></td></tr>
<tr><td>Right outer join</td><td>Using(A1,A2...An)</td></tr>
<tr><td>Full outer join</td><td></td></tr>
</table>
關(guān)鍵字inner和outer是可選的索昂。
對于外連接建车,連接條件是必須的;但是對于內(nèi)連接椒惨,連接條件則是可選的(如果省略缤至,將產(chǎn)生笛卡爾積)。On和using出現(xiàn)在連接表達(dá)式的末尾康谆。
示例表內(nèi)容:
loan:
loan_number branch_name amount
L-170 Downtown 3000
L-230 Redwood 4000
L-260 Perryridge 1700
borrower:
customer_name loan_number
Jones L-170
Smith L-230
Hayes L-155
內(nèi)連接
loan inner join borrower on loan.loan_number = borrower.loan_number;
loan_number branch_name amount customer_name loan_number
L-170 Downtown 3000 Jones L-170
L-230 Redwood 4000 Smith L-230
所得結(jié)果的屬性由左側(cè)關(guān)系的屬性后跟右側(cè)關(guān)系的屬性構(gòu)成领斥。
左外連接
loan left outer join borrower on loan.loan_number = borrower.loan_number;
loan_number branch_name amount customer_name loan_number
L-170 Downtown 3000 Jones L-170
L-230 Redwood 4000 Smith L-230
L-260 Perryridge 1700 null null
左外連接:先計(jì)算內(nèi)連接的結(jié)果,然后沃暗,對左邊關(guān)系(loan)中每個(gè)在內(nèi)連接時(shí)與右邊關(guān)系(borrower)中的任何元組都不匹配的元組t月洛,向結(jié)果中加入一個(gè)元組r,r左邊關(guān)系屬性值為t孽锥,其他屬性為null嚼黔。
自然連接
loan natural inner join borrower;
loan_number branch_name amount customer_name
L-170 Downtown 3000 Jones
L-230 Redwood 4000 Smith
自然連接:連接屬性(公共的屬性)首先出現(xiàn)细层,按照它們在左側(cè)的關(guān)系中的順序,然后是左側(cè)關(guān)系中所有的非連接屬性唬涧,最后是右側(cè)關(guān)系中所有的非連接屬性今艺。
全連接是左外連接和右外連接的組合
loan full outer join borrower using (loan_number);
loan_number branch_name amount customer_name
L-170 Downtown 3000 Jones
L-230 Redwood 4000 Smith
L-260 Perryridge 1700 null
L-155 null null Hayes