1、SQL
Structured Query Language,即結構化查詢語言。 是關係數據庫的標準語言。
2、sql對關係數據庫模式的支持
3、數據定義
1、SQL 的數據定義語句
SQL 不提供修改模式定義、修改視圖定義和修改索引定義的操作,若想修改需先刪掉再重建。
2、模式的定義與刪除
a、定義模式
create schema <模式名> authorization <用戶名>;
如果沒有指定 模式名,隱含爲 用戶名。
實例:
在 mysql 中定義模式(即創建數據庫)語句爲:
creater schema wtf;
/*或者使用:*/
creater database wtf; /*常用*/
b、刪除模式
drop schema <模式名> <cascade | restrict>;
其中 cascade(級聯)表示刪除數據庫及其中所有對象一起刪除,restrict(限制)只有數據庫中沒有對象時才能刪除。
實例:
在 mysql 中 刪除數據庫語句爲:(mysql是直接刪除整個數據庫,相當於 cascade)
drop schema wtf;
/*或者使用: */
drop database wtf; /*常用*/
3、定義基本表
建表的同時通常還可以定義與該表有關的完整性約束條件,如
primary key 指示爲主鍵,unique 指示取唯一值,not null 指示爲非空。還可以指定外碼如:
create table sc(
sno char(7),
cno char(4),
grade smallint,
primary key(sno,cno),/*主碼*/
foreign key (sno) references student(sno),
/*表級完整性約束條件,標明外碼及其被參照表*/
foreign key (cno) references course(cno)
);
4、SQL 數據類型
要注意,不同的 RDBMS 中支持的數據類型不完全相同
SQL主要數據類型如下:
數據類型 | 含義 |
char(n) | 長度爲 n 的定長字符串 |
varchar(n) | 最大長度爲 n 的變長字符串 |
int | 長整數(也可寫作 integer) |
smallint | 短整數 |
numeric(p,d) | 定點數,由 p 位數字(不包括符號、小數點)組成,小數點後面有 d 位數字 |
real | 取決於機器精度的浮點數 |
double precision | 取決於機器精度的雙精度浮點數 |
float(n) | 浮點數,精度至少爲 n 位數字 |
date | 日期, 包含年月日,格式爲 YYYY-MM-DD |
time | 時間,包含時分秒,格式爲 HH:MM:SS |
5、模式與表
每一個基本表都屬於某一個模式,一個模式包含多個基本表
定義基本表時,定義它所屬的模式的方法如下:
a、在表名中明顯的給出模式名
如:create table "S-T".student(......);
b、在創建模式語句中同時創建表
c、設置所屬模式
如:設置搜索路徑: set search_path to "S-T",public;
在 mysql 中可以使用: use 數據庫名; 來指定使用哪個數據庫
6、修改基本表
alter table <表名>
[ add <新列名> <數據類型> [完整性約束] ]
[ drop <完整性約束名> ]
[ alter column <列名> <數據類型> ];
實例:
alter table student add sage int;
alter table student alter column sage smallint;
mysql 中:
7、刪除表
drop table < 表名 > [ cascade | restrict ];
mysql 中 則直接刪除整個表數據,相當於 cascade
8、建立索引
建立索引是加快查詢速度的有效手段,用戶可以根據應用環境的需要,在基本表上建立一個或多個索引
以提供多種存取路徑,加快查找速度。
create [ unique ] [ cluster ] index <索引表>
on <表名> (<列名> [ <次序> ] [, <列名> [ <次序> ] ]...);
實例:
其中次序可選 asc(升序,缺省值),desc(降序),unique 表明此索引的每一個索引值只對應唯一的數據記錄,
cluster 表示要建立的索引是聚簇索引,所謂聚簇索引是指索引項的順序與表中記錄的物理順序一致的索引組織。
9、刪除索引
drop index <索引名>;
建立索引是爲了減少查詢操作的時間,但如果數據增刪改頻繁,系統會花費許多時間來維護索引,從而降低了查詢效率。
刪除索引表時,系統會同時從數據字典中刪去有關該索引的描述。
4、數據更新
1、插入數據
a、插入元組
insert into <表名> [ ( <屬性列 1 > [, <屬性列 2> ] ... ) ]
values ( <常量 1> [, <常量 2> ] ... );
其功能是將新元組插入指定表中,屬性列與常量列依次對應,沒有出現的屬性列將取空值,但 not null 的屬性列不能取空值。
如果 into 子句中沒有指名任何屬性列名,則新插入的元組必須在每個屬性列上均有值。
實例:
b、插入子查詢結果
insert
into <表名> [ (<屬性列 1> [, <屬性列 2> ] ... ) ]
子查詢;
實例:
insert
into dept_age(sdept, avg_age)
select sdept,avg(sage)
from student
group by sdept;
2、修改數據
修改數據又稱更新操作,一般格式爲
update <表名>
set <列名> = <表達式> [, < 列名> = < 表達式 > ]...
[ where <條件> ];
其功能是修改指定表中滿足 where 子句條件的元組,其中 set 子句給出 表達式 的值用於取代相應的屬性列值,
若省略 where 子句,則表示修改表中所有元組
實例:
a、修改某一元組的值
b、修改多個元組的值
update student
set sage = sage + 1;
c、帶子查詢的修改語句
update sc
set grade = 0
where 'cs' =
(select sdept
from student
where student.sno = sc.sno);
3、刪除數據
delete
from < 表名 >
[ where <條件> ];
若省略 where 子句,表示刪除表中全部元組,但表的定義仍存在。
可以刪除某一個元組的值,可以刪除多個元組的值,還可以使用帶子查詢的刪除語句。
實例:
5、數據查詢
一般格式:
select [ all | distinct ] <目標列表達式> [ , <目標列表達式> ] ...
from <表名或視圖名> [, <表名或視圖名> ] ...
[ where <條件表達式> ]
[ group by <列名 1> [ having <條件表達式> ] ]
[ order by <列名 2> [ asc | desc ] ];
即根據 where 子句的條件表達式,從 from 子句指定的基本表或視圖中找出滿足條件的元組,再按 select 子句的目標表達式,
選出元組中屬性值形成果表,如果有 gruop by 子句,則將結果按 <列名 1> 的值進行分組,該屬性列值相等的元組爲一個組,
通常會在每組中作用聚集函數,如果子句帶 having 短語,則只有滿足條件的組才予以輸出。order by 使結果表按 <列名 2> 排序。
1、單表查詢
(1)選中表中若干列
a、查詢指定列
b、查詢全部列
c、查詢經過計算的值
(2)選中表中的若干元組
a、取消取值重複的行(使用 distinct 關鍵字)
b、查詢滿足條件的元組
常用的查詢條件:
查詢條件 | 謂詞 |
比較 | = , > , < , >= , <= , != , <>(不等於) , !> , !< ; not + 上訴比較運算符 |
確定範圍 | between and , not between and |
確定集合 | in , not in |
字符匹配 | like , not like |
空值 | is null , is not null |
多重條件(邏輯運算) | and , or , not |
字符匹配:
謂詞 like 可以用來進行字符串的匹配,語法格式爲:
[ not ] lile '<匹配串>' [ escape '<換碼字符>' ]
其含義是查找指定的屬性列值 與 <匹配串> 相匹配的元組。
<匹配串>可以是含有通配符 %(任意長度字符) 和 _ (任意單個字符)
實例:查詢以 "DB_" 開頭,且倒數第3個字符爲 i 的課程的詳細情況
select *
from course
where cname like 'DB\_%i__' escape '\';
這裏的第一個 "_ " 前面有轉碼字符 \, 被轉義爲普通字符, escape '\' 表示 "\" 爲轉碼字符
注意在 mysql 裏,轉碼字符 \ 被寫成 /
(3)order by 子句
用此子句對查詢結果按照一個或多個屬性列的升序(asc,缺省值)或降序(desc)排列。
(4)聚集函數
爲增強檢索功能,SQL 提供許多聚集函數,主要有:
count( [ distinct | all ] * ) | 統計元組個數(distinct 表示去除重複值,缺省爲 all) |
count( [ distinct | all ] < 列名 > ) | 統計一列中值的個數 |
sum( [ distinct | all ] < 列名 > ) | 計算一列值的總和(此列必須是數值型) |
avg( [ distinct | all ] < 列名 > ) | 計算一列值的平均值(此列必須是數值型) |
max( [ distinct | all ] < 列名 > ) | 求一列值中的最大值 |
mix( [ distinct | all ] < 列名 > ) | 求一列值中的最小值 |
(5)group by 子句
group by 子句將要查詢結果按某一列或多列的值分組,值相等的爲一組。
實例:對查詢結果按 cno 的值分組,所有具有相同 cno 值的元組爲一組,然後用 count 計算該組的人數
2、連接查詢
若一個查詢同時涉及兩個以上的表,則稱之爲連接查詢。
(1)等值與非等值連接查詢
[ <表名 1> . ] < 列名 1 > < 比較運算符 > [ < 表名 2> . ] < 列名 2 >
其中比較運算符:等值連接: = , 非等值連接:> , < ,>= , <= , != , <> 等
也可以使用:
[ <表名 1> . ] < 列名 1 > between [ < 表名 2> . ] < 列名 2 > and [ < 表名 2> . ] < 列名 3 >
實例:查詢 信息系 的年齡在21歲及以下的男生姓名及其年齡
(2)自身連接
連接操作不僅可以在兩個表之間進行,也可以是一個表與其自己進行連接,稱爲表的自身連接。
實例:查詢每一門課的間接先修課(即先修課的先修課)
在 course 中 cpno 爲 該課程 cno 的先修課程,要查詢先修課的先修課,必須對一門課找到
其先修課,再按此先修課的課程號,查找它的先修課程。爲此要爲 course 表取兩個別名,first 和 second :
(3)外連接
在通常的連接操作中只有滿足連接條件的元組才能作爲結果輸出,如下圖,學生 小明沒有選課,但仍想
把捨棄的 小明 元組保存在結果關係中,而在 sc 表的屬性上填空值就需要使用外連接。
左連接:student 表包容 sc 表,左連接左表是全的,列出左邊關係中所有元組, SQL 語句爲:
select student.sno,sname,sex,deptno,sage,cno,grade
from student left out join sc on(student.sno=sc.sno);
/*也可以使用using來去掉重複值
from student left out join sc using(sno);*/
右連接:sc 表包容 student 表,右連接右表是全的,列出右邊關係中所有元組
(4)內連接
student 與 sc 兩表的交集, inner join 比 left join 快,內連接等價於:
select student.sno,sname,sex,deptno,sage,cno,grade
from student,sc where student.sno=sc.sno;
(5)複合條件連接
where 子句中有多個連接條件稱爲複合條件連接
下面是一個多表複合條件連接實例:
3、嵌套查詢
在 SQL 語言中,一個 select-from-where 語句稱爲一個查詢塊,將一個查詢塊嵌套在另一個查詢塊的 where 子句
或 having 短語的條件中的查詢稱爲嵌套查詢。
(1)帶有 in 謂詞的子查詢
在嵌套查詢中,子查詢的結果往往是一個集合,使用 謂詞 in 如下:
上例中,子查詢的查詢條件不依賴於父查詢,稱爲不相關子查詢。
(2)相關子查詢
查找每個學生超過他選修課程平均成績的課程號及成績:
x 是 表 sc 的別名,又稱元組變量,可以用來表示 sc 的一個元組。內層查詢是求一個學生所有選修課課程
平均成績的,至於是哪個學生的平均成績要看參數 x.sno 的值,而該值是與父查詢相關的,稱爲相關子查詢。
(3)帶有 any (some) 或 all 謂詞的子查詢
實例:查詢其他系中比計算機科學與技術系所有學生年齡都小的學生姓名及年齡:
(4)帶有 exists 謂詞的子查詢
exists 代表存在量詞 ヨ,帶有 exists 謂詞的子查詢不返回任何數據,只產生邏輯 true 或 邏輯 false。
由於沒有全稱量詞,可以使用 兩次 not exists 代替
實例:查詢選修了張星老師開設的全部課程的學生姓名
4、集合查詢
select 語句的查詢結果是元組的集合,所以多個 select 語句的結果可以進行集合操作,包括並操作 union、
交操作 intersect 和差操作 except 。注意 參加集合操作的各查詢結果的列數必須相同,對應項的數據類型也必須相同。
實例:查詢系號爲10以及年齡不大於21的學生,用集合查詢,相當於下面的 or 語句,但前者是分別進行兩次查詢將結果取
並集,而後者是直接進行一次查詢。注意: mysql 並不支持 intersect 和 except 集合操作。
6、視圖
視圖是從一個或幾個基本表(或視圖)導出的表,是一個虛表,數據庫中只存放視圖的定義,而不存放視圖對應的數據。
視圖就像一個窗口,透過它可以看到數據庫中自己感興趣的數據及其變化。其可以有基本表一樣被查詢、刪除,但更新操作有一定的限制
1、建立視圖
一般格式:
create view < 視圖名 > [ ( < 列名 > [, < 列名> ] ... ) ]
as < 子查詢 >
[ with check option ]
其中,子查詢可以是任意複雜的 select 語句,但通常不允許包含 order by 子句和 distinct 短語,with check option 表示
對視圖進行 update,insert 和 delete 操作時要保證更新、插入或刪除的行滿足視圖定義中的謂詞條件(即子查詢中的條件表達式)
組成視圖的屬性列名或者全部省略或者全部指定,但在下列三種情況下必須明確指定組成視圖的所有列名:
(1)某個目標列不是單純的屬性名,而是聚集函數或列表達式
(2)多表連接時選出了幾個同名列作爲視圖的字段
(3)需要在視圖中爲某個列啓用新的更合適的名字
視圖不僅可以建立在一個或多個基本表上,也可以建立在一個或多個已定義好的視圖上,或建立在視圖與基本表上。
實例:建立 系號爲 10 選修了 1 號課程學時的視圖
建立 系號爲 10 選修了 1 號課程且成績在 90 分以上的學生的視圖
2、查詢視圖
實例:查詢選修了 1 號課程的 系號爲 10 的學生
定義 is_student 視圖時 加上了 with check option 子句,以後視圖的增刪時都會自動加上 deptno=10的條件
3、刪除視圖
格式爲:
drop view < 視圖名 > [ cascade ] ;
刪除視圖後視圖的定義將從數據字典中刪除,加上 cascade 級聯刪除後,把該視圖和由它導出的所有視圖一起刪除。
4、更新視圖
更新視圖最終要轉換爲對基本表的更新。
實例:
insert
into is_student
values('1007','逃兵',25);
delete
from is_student
where sno=1001;
有些視圖是不可更新的,個系統實現有差異。
5、視圖的作用
視圖最終是定義在基本表之上的,對視圖的操作最終也要轉換爲對基本表的操作,但合理的使用視圖能夠帶來許多好處
(1)視圖能夠簡化用戶的操作
視圖機制使用戶可以將注意力集中在所關心的數據上。
視圖可以簡化用戶操作,還可以將定義若干表的連接操作隱藏起來,使結構簡單,清晰。
(2)視圖使用戶能以多種角度看待同一數據
(3)視圖對重構數據庫提供了一定程度的邏輯獨立性
(4)視圖能夠對機密數據提供安全保護
(5)適當的利用視圖可以更清晰的表達查詢
例如:經常需要執行查詢“對每個同學找出他獲得最高成績的課程號”,可以先定義一個視圖,求出
每個同學獲得的最高成績,然後用查詢語句完成查詢,如下: