資料庫系統概念 第4章 中級SQL
第四章 中級SQL
4.1 連線表示式
SQL提供了連線運算的其他形式,通過這些形式能在結果中包含被自然連線排除在外的元組。
4.1.1 連線條件
SQL使用on
來在參與連線的關係上設定通用的謂詞,和where
相似,但在外連線運算中表現結果與where
不同。
on
的用法如下。
select * from student join takes on student.ID = takes.ID;
上面的on
條件表明,若來自student的元組的ID
屬性和來自takes的元組的ID
屬性相同,則把它們連線起來,作為結果的元組。
上述結果雖然和下列語句在邏輯上相同
select * from student natural join takes;
但是on
語句並不取出重複的元組,也就是說結果關係中會出現兩個ID
屬性,student.ID
和takes.ID
實際上,等價語句是
select * from student, takes where student.ID = takes.ID;
4.1.2 外連線
外連線的引入
考慮查詢“找出所有學生的選課資訊”,如果使用如下查詢語句。
select * from student natural join takes;
此時,對於那些沒有選課的學生來說,即在takes中沒有對應的ID,那麼這個學生的選課結果不會被顯示,而我們希望即使學生沒有選課就設其選課資訊為null
。此時,我們便引入了外連線。
總的來說,外連線在內連線的結果上通過在一些屬性上設定null
來保留原來在內連線的結果上不匹配的元組。
外連線有三種,左外連線、右外連線和全外連線。
- 左外連線。先做內連線,然後把左邊關係中未被包含的元組包含進去,對於這些元組在右邊關係的項被置為
null
。 - 右外連線。先做內連線,然後把右邊關係中未被包含進去的元組包含進去,對於這些元組的左邊關係中的項被置為
null
。 - 全外連線。左外連線和右外連線的並集。
使用外連線後,查詢“找出所有學生的選課資訊”可以被如下表示。
select *
from student left outer join takes;
使用左外連線後,即使存在一些不選課的學生,其也被包含在結果中,只不過其在選課資訊的值被置為null
。
相似的,右外連線和全外連線表示為right outer join
和full outer join
注意,on和where在外連線上表現得結果是不一樣的。在外連線中,on作用於內連線的結果,也就是對被補上null然後插入的元組不起作用。但where是在內連線和補上null插入後得到的結果上發生作用。例如,上面的查詢等價於
select *
from student left outer join takes on student.ID = takes.ID;
但下面的查詢
select *
from student natural left outer join takes
where student.ID = takes.ID;
不存在包含了空值屬性的元組。
4.2 檢視
4.2.1 檢視的定義
很多時候,我們並不希望讓所有使用者看到整個關係的邏輯模型。出於安全考慮,需要向使用者隱藏特定資料。因此,SQL中引入了檢視。檢視是通過查詢語句定義的,但是,其中並不預先包含資料,而是在使用過程中才通過定義它的查詢語句計算出來。
SQL使用create view
來定義檢視
create view view_name as <query expression>
view_name
是檢視名稱,<query expression>
是任何合法的查詢語句。
例如,可以定義一個檢視,“列出Physics系在2009年秋季學期所開設的所有課程段”
create view physics_fall_2009 as
select course, course_id, sec_id, building, room_number
from section, course
where course.course_id = section.course_id and
course.dept_name = 'Physics' and
section.semester = 'Fall' and
section.year = '2009';
4.2.2 SQL查詢中使用檢視
檢視可以被當成一個關係來使用,例如,“找出所有在2009年秋季學期在Waston大樓開設的Physics課程”
select course_id
from physics_fall_2009
where building = 'Watson';
4.2.3 物化檢視
特定資料庫允許儲存檢視關係,但是它們保證,如果用於定義檢視的實際關係被改變,檢視也跟著修改,這樣的檢視被稱為物化檢視。
4.2.4 檢視更新
儘管對查詢而言,檢視是一個有用的工具,但如果我們用它們來表達更新、插入或刪除,它們可能帶來嚴重的問題。困難在於,用檢視表達的資料庫修改必須被翻譯為對資料庫邏輯模型中實際關係的修改。所以,檢視如果被稱為可更新的,需要滿足如下限制
- from子句中只有一個資料庫關係。
- select子句中只包含關係的屬性名,不包含任何表示式、聚集函式和distinct宣告。
- 在任何沒有出現在select子句中的屬性可以取空值。
- 查詢部分不包含group by和having子句。
4.3 事務
事務由查詢和(或)更新語句的序列組成。SQL標準規定當一條SQL語句被執行時,就隱式地開啟了一個事務。下列兩條SQL語句之一會結束一個事務。
- commit work。提交當前事務,也就是將該事務所做的更新在資料庫中持久儲存。在事務被提交後,一個新的事務自動開始。
- rollback work。回滾當前事務,即撤銷事務中所有SQL語句對資料庫的更新。這樣,資料庫就恢復到執行該事務第一條語句之前的狀態。
如果一個事務還未完成commit work,其影響將被回滾。在執行事務過程中,若發生斷點和系統崩潰,在資料庫重啟時回滾將被自動執行。若事務已經完成commit work,在其影響將不能通過回滾來撤銷。
事務的完成是具有原子性的。即一個事務或者在完成所有步驟後提交其行為,或者在不能完成其所有動作的情況下回滾其所有動作。
在很多SQL語句中,預設方式下每個SQL語句自成一個事務,執行完後便自動提交。如果一個事務要完成多個SQL語句,則需要關閉自動提交。
4.4 完整性約束
完整性約束保證授權使用者對資料所作的修改不會破壞資料的一致性。
4.4.1 單個關係上的約束
單個關係上的約束包括
- not null。例如,
name varchar(20) not null
- unique。例如,
unique(Aj1, Aj2, ..., Ajn)
,unique
定義的屬性元組構成候選碼。 - check(<謂詞>)。例如,
check(semester in ('Fall', 'Winter', 'Spring', 'Summer'))
。check
子句來保證屬性值滿足的條件。
上面3條語句是在create table
上加入的。
4.4.2 斷言
一個斷言就是一個謂詞,它表達了我們希望資料庫總能滿足的一個條件。域約束和參照完整性約束是斷言的特殊形式。斷言的定義一般如下形式
create assertion <assertion-name> check <predicate>;
注意,還沒有一個廣泛使用的資料庫系統支援斷言結構。
4.5 SQL的資料型別與模式
4.5.1 SQL的日期和時間型別
SQL支援日期型別的資料,如下所示
date # 日曆日期,包括年、月和日,如'2001-04-25'
time # 一天中的時間,包括時、分和秒,如'09:30:00',可以用time(p)來指定秒的小數點後的數字數,用time with time zone來將時區和時間一起儲存
timestamp # date和time的組合,如'2001-04-25 10:29:01.45'。可以用變數timestamp(p)來指定秒的小數點後的數字數,用timestamp with time zone來將時區和時間一起儲存
我們可以利用case e as t
形式的表示式來將一個字串e轉換成型別t,其中t是data, time, timestamp
中的一種,而且字串也必須符合正確的格式。
我們可以利用extract (field from d)
,從date
或time
的值d中提取出單獨的域,這裡的域可以是year, month, day, hour, minute, second
中的任意一種。時區資訊可以用timezone_hour
和timezone_minute
來提取。
還有其他的函式可以獲取當前的日期和時間。current_date
返回當前日期,current_time
返回當前時間(帶有時區),local_time
返回當前的本地時間(不帶時區)。timestamp由current_timestamp
和local_timestamp
返回。
4.5.2 預設值
SQL允許在建立表中使用default
來指定預設值,如下所示
create table student(
...
tot_cred numeric(3, 0) default 0,
...
);
4.5.3 建立索引
索引(index)可以幫助資料庫高效地找到關係中那些在索引屬性上取給定的元組。例如,如果我們在student關係的屬性ID上建立了索引,資料庫系統就不用掃描關係中的其他元組,就可以直接找到任何像22201或44553那樣具有指定ID值的記錄。
常用資料庫一般使用如下語句來定義索引
create index studentID_index on student(ID);
上述語句在student關係的屬性ID上建立了一個名為studentID_index的索引。
4.5.4 大物件型別
SQL提供字元資料的大物件型別clob
和二進位制資料的大物件資料型別blob
,如下所示
book_revoew clob (10kb)
image blob (10MB)
4.5.5 使用者定義的型別
SQL標準定義了可使用create type
和create domain
來分別定義型別和域,但這些結構形式還沒有被大多數資料庫實現完全支援。
4.5.6 create table的擴充套件
SQL提供了create table like
來支援基於某一個表的結構建立一個新表,如下所示。
create table temp like student;
但上述語句只是建立了一個和student結構完全相同的新表temp,其內容為空。
我們也可以基於查詢結果來建立一個新表,如下所示。
create table tl as (
select * from instructor where dept_name = 'music'
)
with data;
如果不加data將不會插入資料。新表的屬性是根據查詢結果的屬性來推匯出來的,當然也可以在新表的名稱後指定屬性名。
4.6 授權
我們可以會限制使用者在資料庫上的許可權,並通過授權的方式來提供許可權。許可權的授權有兩種,對資料的授權(select, update, insert, delete)和對資料庫模式的授權(允許使用者建立、修改和刪除關係)。當使用者執行了未被授權的許可權時,系統將拒絕執行。
4.6.1 許可權的授予與收回
許可權的授予使用grant
,如下所示
grant <許可權列表>
on <關係名或檢視>
to <使用者或角色>
例如
grant select on department to Amit, Satashi;
該語句授予了使用者Amit和Satashi在department關係上的select許可權。
有時我們希望許可權可以具體到部分屬性,如下所示
grant update(budget)
on department
to Amit, Satashi;
該語句授予了使用者Amit和Satashi在department關係上的update許可權,但只能update budget。我們也可以在授予insert許可權中指定屬性,其餘未被指定的屬性要麼被指定為null,要麼被指定為default值。
將許可權授予給pulic
相當於對當前所有使用者和將來使用者的授權。
我們可以使用revoke
收回許可權,用法語句和grant
時完全相同,如下所示
revoke update(budget)
on department
to Amit, Satashi;
授予使用者的許可權也可以被使用者在授予其他使用者,此時許可權的收回將會更加複雜。
4.6.2 角色
在SQL中,我們可以將許可權授予角色。此時,當新使用者建立時,我們直接將角色授予該使用者,使得新使用者直接獲得角色擁有的許可權,省去了單獨為新使用者授權的麻煩。
因此,一個使用者或角色擁有的許可權包括兩部分
- 直接授予的許可權。
- 被授予的角色帶來的許可權。
建立角色使用create role
,如下所示
create role instructor;
然後我們可以將許可權授予角色
grant select
on department
to instructor;
然後角色可以被授予到使用者或角色,如下所示
grant dean to Amit;
create role dean;
grant instructor to dean;
4.6.5 許可權的轉移
我們可以在執行grant
命令時附加with grant option
來允許被授權使用者將該授權再次授予到其他使用者,如下所示。
grant select on department to Amit with grant option;
許可權從一個使用者到另一個使用者的傳遞可以表示為授權圖,但是,相互授權的行為可以導致授權圖中存在迴路。
使用者存在許可權的充要條件是存在從授權圖的根節點到代表該使用者頂點的路徑。
4.6.6 許可權的收回
當收回一個使用者的許可權時,其授予其他使用者的許可權也會被預設級聯收回,但可以在revoke
後加上restrict
來防止級聯收回。
相關文章
- SQL Server 系統資料庫恢復SQLServer資料庫
- Sql Server系列:資料庫組成及系統資料庫SQLServer資料庫
- 如何將外部資料庫 匯入到系統的SQL中資料庫SQL
- 資料庫概念資料庫
- 易學筆記-系統分析師考試-第5章 資料庫系統/5.1 資料庫模式/筆記資料庫模式
- 《資料庫系統概論》 (第4版) 個人筆記資料庫筆記
- 《資料庫技術原理與應用教程第2版》——第3章資料管理中的資料模型3.1資料模型的基本概念...資料庫模型
- 谷歌升級雲端資料庫Cloud SQL谷歌資料庫CloudSQL
- 重建 SQL Server 2008 系統資料庫SQLServer資料庫
- 《OceanBase 資料庫系統概念》首次釋出,系統精準定義 OceanBase !資料庫
- 【MySQL】資料庫系統中的“黑天鵝”MySql資料庫
- Oracle資料庫系統中的引數Oracle資料庫
- Oracle資料庫中的系統引數Oracle資料庫
- 資料庫的概念資料庫
- Sql Server資料庫資料匯入到SQLite資料庫中Server資料庫SQLite
- 把64位的unix系統資料庫遷移到32位的windows系統資料庫中資料庫Windows
- 在SQL Server資料庫中匯入MySQL資料庫Server資料庫MySql
- 資料庫概論 (一)資料庫概念資料庫
- SQL語句在oracle資料庫中的初級應用(上)SQLOracle資料庫
- sql觸發器刪除資料庫中的級聯記錄SQL觸發器資料庫
- 13 使用SQL Apply 升級資料庫SQLAPP資料庫
- SQL Server資料庫級別觸發器SQLServer資料庫觸發器
- 資料庫應用系統中的資料庫完整性(上)KP資料庫
- SQL資料庫中Truncate的用法SQL資料庫
- Oracle資料庫系統中的引數(續)Oracle資料庫
- 資料庫系統概述之國產資料庫資料庫
- 資料庫系統概述資料庫
- 資料庫系統原理資料庫
- 王珊資料庫系統概論第5版視訊教材資料庫
- Oracle資料庫-----資料庫的基本概念Oracle資料庫
- NoSQL資料庫概念與NoSQL資料庫家族SQL資料庫
- oracle資料庫SCN概念Oracle資料庫
- 【資料庫系統】資料庫系統概論====第十三章 資料庫技術發展資料庫
- 資料庫系統操作規範及SQL書寫建議資料庫SQL
- SQL Server2000 如何恢復系統資料庫?SQLServer資料庫
- 異構資料庫系統遷移到Oracle 工具 - Oracle SQL Developer資料庫OracleSQLDeveloper
- 常見資料庫系統之比較 - SYBASE 和 SQL SERVER(轉)資料庫SQLServer
- 華為雲PB級資料庫GaussDB(for Redis)揭秘第13期:如何搞定推薦系統儲存難題資料庫Redis