數據庫
1. 數據庫事務的 4 個特性是:原子性、一致性、持續性、隔離性
1) 原子性:事務是數據庫的邏輯工作單位,它對數據庫的修改要么全部執行,要么全部不執行。
2) 一致性:事務前后,數據庫的狀態都滿足所有的完整性約束。
3) 隔離性:並發執行的事務是隔離的,一個不影響一個。如果有兩個事務,運行在相同的時間內,執行相同的功能,同一時間僅有一個請求用於同一數據。設置數據庫的隔離級別,可以達到不同的隔離效果。
4) 持久性:在事務完成以后,該事務所對數據庫所作的更改便持久的保存在數據庫之中,並不會被回滾。
2. 零散知識點:
1) 數據庫系統的主要特點:數據結構化、數據度的冗余度小、較高的數據獨立性。
2) 關系數據模型的三個組成部分:數據結構,完整性,數據模型
3) 數據庫管理系統的主要功能:數據定義,數據操作,數據庫的運行管理,數據組織、存儲與管理,數據庫的保護和維護,通信
4) 數據庫系統:由數據庫、數據庫管理系統以及其開發工具、應用系統、數據庫管理員構成。其中,數據庫系統軟件包括數據庫管理系統、開發工具和數據庫應用系統。
3. SQL語句如何實現收回 user2 查詢基本表 T 的權限?
revoke select on t from user2
1) deny:在安全系統中創建一項,以拒絕給當前數據庫內的安全帳戶授予權限並防止安全帳戶通過其組或角色成員資格繼承權限。
例如:拒絕user4查詢視圖MyView的權限 deny SELECT on MyView to user4
2) revoke:刪除以前在當前數據庫內的用戶上授予或拒絕的權限。
4. 數據庫中的幾種語言:
1) 數據查詢語言(DQL):用來查詢記錄。保留字:select、where、order by、group by、having。
2) 數據操作語言(DML):用來操縱數據庫記錄。保留字:insert、update、delete。
3) 數據定義語言(DDL):用來定義數據庫的表、庫、列等對象。保留字:create、alter、drop、truncate
4) 數據控制語言(DCL):用來定義訪問權限和安全級別。保留字:commit,rollback、savepoint、grant、revoke。
授予權限 grant privileges on dbname.tablename to‘username’@’host’
a) privileges:可以是SELECT,INSERT,UPDATE等,如果要授予所的權限則用ALL
b) dbname:數據庫名
c) tablename:表名,若要授予該用戶對數據庫中所有表的操作權限則可用表示,如.*
例如:grant select on BookStore.* to UserA
撤銷權限 revoke privilege on dbname.tablename from ‘username’@’host’;
5. 零散知識點:
1) 超鍵(super key):在關系中能唯一標識元組的屬性集稱為關系模式的超鍵
2) 候選鍵(candidate key):不含有多余屬性的超鍵稱為候選鍵
3) 主鍵(primary key):用戶選作元組標識的一個候選鍵稱為主鍵
6. 對於數據庫索引的說法錯誤的是(B)
A 索引可以提升查詢,分組和排序的性能;
B 索引不會影響表的更新、插入和刪除操作的效率;
C 全表掃描不一定比使用索引的執行效率低;
D 對於只有很少數據值的列,不應該創建索引
有關數據庫中索引的相關知識點:
A. 索引的概念
數據庫索引,是數據庫管理系統中一個排序的數據結構,以協助快速查詢、更新數據庫表中數據。索引的實現通常使用B樹及其變種B+樹 。在數據之外,數據庫系統還維護着滿足特定查找算法的數據結構,這些數據結構以某種方式引用(指向)數據,這樣就可以在這些數據結構上實現高級查找算法。這種數據結構,就是索引。為表設置索引要付出代價的:一是增加了數據庫的存儲空間 ,二是在插入和修改數據時要花費較多的時間(因為索引也要隨之變動) 。
B. 創建索引的優點:
1) 通過創建唯一性索引,可以保證數據庫表中每一行數據的唯一性。
2) 大大加快數據的檢索速度,這也是創建索引的最主要的原因。
3) 加速表和表之間的連接,特別是在實現數據的參考完整性方面特別有意義。
4) 使用分組和排序子句進行檢索,減少查詢中分組和排序的時間。
5) 通過使用索引,可以在查詢的過程中,使用優化隱藏器,提高系統的性能。
C. 增加索引的弊端:
1) 對表中的數據進行增刪改時,索引也要動態維護,降低了數據庫的維護性。
2) 索引需要占物理空間,除了數據表占數據空間之外,每一個索引還要占一定的物理空間,如果要建立聚簇索引,那么需要的空間就會更大。
3) 創建索引和維護索引要耗費時間,這種時間隨着數據量的增加而增加。
D. 需要創建索引的列:
索引是建立在數據庫表中的某些列的上面。在創建索引的時候,應該考慮在哪些列上可以創建索引,在哪些列上不能創建索引。 一般來說,應該在以下這些列上創建索引:
1) 在經常需要搜索的列,可以加快搜索的速度;
2) 在作為主鍵的列,強制該列的唯一性和組織表中數據的排列結構;
3) 在經常用在連接的列,這些列主要是一些外鍵,可以加快連接的速度;
4) 在經常需要根據范圍進行搜索的列,因為索引已經排序,其指定的范圍是連續的;
5) 在經常需要排序的列上創建索引,這樣查詢可以利用索引的排序,加快排序查詢時間;
6) 在經常使用在WHERE子句中的列上面創建索引,加快條件的判斷速度。
E. 不適合創建索引的列:
不應該創建索引的的這些列具有下列特點:
1) 在查詢中很少使用或者參考的列不應該創建索引。既然這些列很少使用到,因此有索引或者無索引,並不能提高查詢速度。相反,由於增加了索引,反而降低了系統的維護速度和增大了空間需求。
2) 對於那些只有很少數據值的列也不應該增加索引。由於這些列的取值很少,例如人事表的性別列,在查詢的結果中,結果集的數據行占了表中數據行的很大比例,即需要在表中搜索的數據行的比例很大。增加索引,並不能明顯加快檢索速度。
3) 對於那些定義為text, image和bit數據類型的列不應該增加索引。這些列的數據量要么相當大,要么取值很少。
4) 當修改性能遠遠大於檢索性能時,不應該創建索引。修改性能和檢索性能是互相矛盾的。當增加索引時,會提高檢索性能,但是會降低修改性能。當減少索引時,會提高修改性能,降低檢索性能。因此,當修改性能遠遠大於檢索性能時,不應該創建索引。
F. 索引的分類:
三種索引: 唯一索引、主鍵索引和聚集索引。
1) 普通索引:最基本的索引,而且沒有唯一性之類的限制。
創建:create index [indexName] on [TableName] ([column],…)
刪除:drop index [tableName].[indexName]
唯一索引:不允許其中任何兩行具有相同索引值的索引。當現有數據中存在重復的鍵值時,大多數數據庫不允許將新創建的唯一索引與表一起保存。數據庫還防止添加,將在表中創建重復鍵值的新數據。
例如,如果在 employee 表中職員的姓 (lname) 上創建了唯一索引,則任何兩個員工都不能同姓。
創建: create Unique index [indexName] on [TableName] ([column],…)
刪除:drop index [TableName].[IndexName]
2) 主鍵索引
數據庫表經常有一列或列組合,其值唯一標識表中的每一行。該列稱為表的主鍵。在數據庫關系圖中為表定義主鍵將自動創建主鍵索引,主鍵索引是唯一索引的特定類型。該索引要求主鍵中的每個值都唯一。當在查詢中使用主鍵索引時,它還允許對數據的快速訪問。建議建立唯一索引時,直接創建主鍵索引就好了。
3) 聚集索引
該索引中鍵值的邏輯順序決定了表中相應行的物理順序。聚集索引類似於電話簿,按姓氏排列數據。由於聚集索引規定數據在表中的物理存儲順序,因此一個表只能包含一個聚集索引。但該索引可以包含多個列(組合索引),就像電話簿按姓氏和名字進行組織一樣。
創建:CREATE cluster index [IndexName] ON [TableName]([ColumnName],[ColumnName],...)
聚集索引使用注意事項:
(1) 定義聚集索引鍵時使用的列越少越好;
(2) 使用下列運算符返回一個范圍值的查詢:BETWEEN、>、>=、< 和 <=,可以按物理順序更快的返回一個范圍;
(3) 被連續訪問的列;
(4) 返回大型結果集的查詢;
(5) 經常被使用表聯接或 GROUP BY 子句的查詢訪問的列;一般來說,這些是外鍵列。對 ORDER BY 或 GROUP BY 子句中指定的列進行索引,可以使 SQL Server 不必對數據進行排序,因為這些行已經排序。這樣可以提高查詢性能;
(6) OLTP 類型的應用程序,這些程序要求進行非常快速的單行查找(一般通過主鍵)。應在主鍵上創建聚集索引;
4) 非聚集索引
數據存儲在一個地方,索引存儲在另一個地方,索引帶有指針指向數據的存儲位置。非聚集索引中的項目按索引鍵值的順序存儲,而表中的信息按另一種順序存儲(這可以由聚集索引規定)。對於非聚集索引,可以為在表非聚集索引中查找數據時常用的每個列創建一個非聚集索引。有些書籍包含多個索引。例如,一本介紹園藝的書可能會包含一個植物通俗名稱索引,和一個植物學名索引,因為這是讀者查找信息的兩種最常用的方法。
創建CREATE noclustered index [IndexName] ON [TableName]([ColumnName],[ColumnName]...)
7. 數據表建立復合索引tab_index(“name”,”age”),下面哪些語句能用上索引?(A)
A select*from table where age=18 and name=’test’;
B select*from table where name=’test’and age=18;
C select*from table where name like”%test%”and age=18;
D select*from table where name like”%test”and age=18;
1) 什么是復合索引?
索引可以包含一個、兩個或更多個列。兩個或更多個列上的索引被稱作 復合索引。
2) 復合索引作用
利用索引中的附加列,您可以縮小搜索的范圍,但使用一個具有兩列的索引不同於使用兩個單獨的索引。
3) 例子
CREATE INDEX name ON employee (emp_lname, emp_fname)
復合索引的結構與電話簿類似,它首先按姓氏對雇員進行排序,然后按名字對所有姓氏相同的雇員進行排序。如果您知道姓氏,電話簿將非常有用,如果您知道名字和姓氏,電話簿則更為有用,但如果您只知道名字而不知道姓氏,電話簿將沒有用處。所以復合索引,字段的先后順序是很重要的。 列的順序:在創建復合索引時,應該仔細考慮列的順序。對索引中的所有列執行搜索或僅對前幾列執行搜索時,復合索引非常有用;僅對后面的任意列執行搜索時,復合索引則沒有用處。
解析:
A,沒有注意復合索引順序
B 正確
C 凡是對索引列,使用了‘%XXX’,都不走索引。如果改為where name = 'test%'則可以走索引。
8. 數據庫設計分為四個階段:
1)需求分析階段:編寫軟件規格說明書及初步的用戶手冊,提交評審。
2)概念設計階段:E-R圖設計階段。
3)邏輯設計階段:主要是E_R轉換成關系模式(或者說是建立關系模式的階段)。
4)物理設計階段
注:在數據庫設計中,描述數據間內在語義聯系得到E-R圖的過程屬於(概念設計階段)
9. 數據庫中並發操作的相關知識點:
A. 並發與並行的區分:
1) 並發(Concurrent):當有多個線程在操作時,如果系統只有一個CPU,則它不可能真正同時進行一個以上的線程,它只能把CPU運行時間划分成若干個時間段,再將時間段分配給各個線程執行,在一個時間段的線程代碼運行時,其它線程處於掛起狀。
2) 並行(Parallel):當系統有一個以上CPU時,則線程的操作有可能非並發。當一個CPU執行一個線程時,另一個CPU可以執行另一個線程,兩個線程互不搶占CPU資源,可以同時進行。
3) 區別:並發和並行是即相似又有區別的兩個概念,並行是指兩個或者多個事件在同一時刻發生;而並發是指兩個或多個事件在同一時間間隔內發生。
B. 數據庫事務並發帶來的數據不一致問題有:更新丟失、臟讀、不可重復讀、幻象讀。
1) 丟失修改:一個事務的更新覆蓋了另一個事務的更新。兩個事務讀入同一數據並修改,后提交的結果破壞先提交的結果,導致先提交的事務修改被丟失;
2) 不可重復讀:一個事務兩次讀取同一個數據,兩次讀取的數據不一致。先提交的事務讀取數據后,后提交的事務執行更新操作,使得前面的事務不能讀取前一次結果。
3) 讀臟數據:一個事務讀取了另一個事務未提交的數據。某事務修改某一數據,並將它寫回磁盤,后來的事務讀取同一數據后,前一事務由於某種原因回滾(rollback),這時前面已經修改的數據已經恢復原值,后讀到的數據就與數據庫的數據不一致。
4) 幻象讀:一個事務兩次讀取一個范圍的記錄,兩次讀取的記錄數不一致。
a) 事務T1按一定條件從數據庫中讀取了某些數據記錄后,事務T2刪除了其中部分記錄,當T1再次按照相同條件讀取數據時,發現某些記錄神秘的消失了.
b) 事務T1按一定條件從數據庫中讀取了某些數據記錄后,事務T2插入了一些記錄,當T1再次按照相同條件讀取數據時,發現多了一些記錄.
事務A:張三妻子兩次查詢張三有幾張銀行卡。事務B:張三新辦一張銀行卡。事務A第一次查詢銀行卡數的時候,張三還沒有新辦銀行卡,第二次查詢銀行卡數的時候,張三已經新辦了一張銀行卡,導致兩次讀取的銀行卡數不一樣。幻象讀本質上是讀寫操作的沖突,解決辦法是讀完再寫。
以上三種現象的原因是並發操作破壞了事務的隔離性。為了應對這些數據不一致性,主要技術主要有:封鎖,時間戳,樂觀控制法。
10. 數據庫中的封鎖機制相關知識點
A. 封鎖機制的概念
封鎖就是事務T在對某個數據對象操作之前,先向系統發出請求對其加鎖。加鎖后事務T就對該數據對象有了一定的控制,在事務T釋放它的鎖之前,其他事務不能更新此數據對象。基本的鎖類型有兩種:排他鎖(又稱寫鎖,X鎖)和共享鎖(又稱讀鎖,S鎖),此處再加一個更新鎖和意向鎖
1) 共享鎖(讀鎖S鎖),是讀取操作創建的鎖。事務T對數據A加上共享鎖后,則其他事務只能對A再加共享鎖,不能加排他鎖。獲准共享鎖的事務只能讀數據,不能修改數據。
2) 排他鎖(寫鎖X鎖),如果事務T對數據A加上排他鎖后,則其他事務不能再對A加任任何類型的封鎖。獲准排他鎖的事務T既能讀數據,又能修改數據。
3) 更新鎖(U鎖):更新鎖在修改操作的初始化階段用來鎖定可能要被修改的資源,這樣可以避免使用共享鎖造成的死鎖現象。因為使用共享鎖時,修改數據的操作分為兩步,首先獲得一個共享鎖,讀取數據,然后將共享鎖升級為排它鎖,然后再執行修改操作。這樣如果同時有兩個或多個事務同時對一個事務申請了共享鎖,在修改數據的時候,這些事務都要將共享鎖升級為排它鎖。這時,這些事務都不會釋放共享鎖而是一直等待對方釋放,這樣就造成了死鎖。如果一個數據在修改前直接申請更新鎖,在數據修改的時候再升級為排它鎖,就可以避免死鎖。
4) 意向鎖:對多粒度樹中的結點加意向鎖,則說明該結點的下層結點正在被加鎖;對任一結點加鎖時,必須先對它的上層結點加意向鎖。
意向鎖的作用就是當一個事務在需要獲取資源鎖定的時候,如果遇到自己需要的資源已經被排他鎖占用的時候,該事務可以需要鎖定行的表上面添加一個合適的意向鎖。如果自己需要一個共享鎖,那么就在表上面添加一個意向共享鎖。而如果自己需要的是某行(或者某些行)上面添加一個排他鎖的話,則先在表上面添加一個意向排他鎖。意向共享鎖可以同時並存多個,但是意向排他鎖同時只能有一個存在。
意向鎖是InnoDB自動加的,不需用戶干預。對於UPDATE、DELETE和INSERT語句,InnoDB會自動給涉及數據集加排他鎖(X);對於普通SELECT語句,InnoDB不會加任何鎖;事務可以通過以下語句顯示給記錄集加共享鎖或排他鎖。
共享鎖(S):SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE
排他鎖(X):SELECT * FROM table_name WHERE ... FOR UPDATE
B. 封鎖協議
在運用X鎖和S鎖這兩種基本封鎖對數據對象加鎖時,還需要約定一些規則。例如,何時申請X鎖或S鎖、持鎖時間、何時釋放等。這些規則稱為封鎖協議。通常使用三級封鎖協議來在不同程度上解決並發操作的不正確調度帶來的丟失修改、不可重復讀和讀“臟”數據等不一致性問題。
1) 一級封鎖協議
事務T在修改數據R之前必須先對其加X鎖,直到事務結束才釋放。一級封鎖協議可以防止丟失修改,並保證事務T是可恢復的。
2) 二級封鎖協議
在一級封鎖協議基礎上增加事務T在讀數據R之前必須先對其加S鎖,讀完后釋放S鎖。二級封鎖協議防止丟失修改,讀臟數據。
3) 三級封鎖協議
在一級封鎖協議的基礎上增加事務T在讀數據R之前必須先對其加S鎖,直到事務結束才釋放。三級封鎖協議出防止了丟失修改和讀“臟”數據外,還可以進一步防止了不可重復讀。
C. Mysql中鎖的粒度划分
MySQL各存儲引擎使用了三種級別的鎖定機制:表級鎖定,行級鎖定和頁級鎖定
1) 表級鎖:開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖沖突的概率最高,並發度最低;
MyISAM在執行查詢語句(SELECT)前,會自動給涉及的所有表加讀鎖,在執行更新操作(UPDATE、DELETE、INSERT等)前,會自動給涉及的表加寫鎖,這個過程並不需要用戶干預,因此,用戶一般不需要直接用LOCK TABLE命令給MyISAM表顯式加鎖。
2) 行級鎖:開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖沖突的概率最低,並發度也最高;
3) 頁面鎖:開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,並發度一般。
4) 適用范圍:從鎖的角度來說,表級鎖更適合於以查詢為主,只有少量按索引條件更新數據的應用,如Web應用;而行級鎖則更適合於有大量按索引條件並發更新少量不同數據,同時又有並發查詢的應用,如一些在線事務處理(OLTP)系統。
例題;
若事務 T 對數據 R 已加 X 鎖,則其他事務對數據 R(D)
A 可以加 S 鎖不能加 X 鎖 ;B 不能加 S 鎖可以加 X 鎖
C 可以加 S 鎖也可以加 X 鎖 ; D 不能加任何鎖
11. 數據庫中的三級模式:外模式,(概念)模式,內模式。
1) 模式:模式又稱概念模式或邏輯模式,對應於概念級。它是由數據庫設計者綜合所有用戶的數據,按照統一的觀點構造的全局邏輯結構,是對數據庫中全部數據的邏輯結構和特征的總體描述,是所有用戶的公共數據視圖(全局視圖)。由DDL來描述、定義的,體現、反映了數據庫系統的整體觀。
2) 外模式:外模式又稱子模式或用戶模式,對應於用戶級。它是某個或某幾個用戶所看到的數據庫的數據視圖,是與某一應用有關的數據的邏輯表示。利用數據操縱語言DML對這些數據記錄進行
3) 內模式:內模式又稱存儲模式,對應於物理級,它是數據庫中全體數據的內部表示或底層描述,是數據庫最低一級的邏輯描述,它描述了數據在存儲介質上的存儲方式和物理結構,對應着實際存儲在外存儲介質上的數據庫。內模式由內模式描述語言來描述、定義,它是數據庫的存儲觀。
外模式和模式建立邏輯獨立性數據的邏輯獨立性是指(用戶的應用程序與數據庫的邏輯結構是相互獨立的);模式和內模式建立物理獨立性
12. OODB中,包含其他對象的對象,稱為(復合對象)
ORDB 中,同類元素的無序集合,並且允許一個成員可多次出現,稱為(多集類型也稱作包類型)
13. 數據庫中的幾種故障
1) 事務故障:由非預期的、不正常的程序結束所造成的故障。如輸入數據錯誤、運算溢出、違反存儲保護、並行事務發生死鎖;
2) 系統故障:系統的運行過程中,由於某種原因造成系統停止運轉,致所有正在運行的事務都以非正常的方式終止,要求系統重新啟動。如CPU錯誤、DBMS代碼錯誤;
3) 介質故障:系統在運行過程中,輔助存儲器介質受到破壞,使存儲在外存中的數據部分或全部丟失。
14. 關於JDBC PreparedStatement:可以用來進行動態查詢、通過預編譯和緩存機制提升了執行的效率、有助於防止SQL注入,因為它會自動對特殊字符轉義。
15. 數據庫中范式相關知識點:
A. 有關“鍵”的概念
1) 超鍵:在關系中能唯一標識元組的屬性或屬性集稱為關鍵模式的超鍵。
2) 候選鍵:不含有多余屬性的超鍵稱為候選鍵。也就是在候選鍵中在刪除屬性就不是鍵了。
3) 主鍵:用戶選作元組標識的候選鍵稱為主鍵。一般不加說明,鍵就是指主鍵。
4) 外鍵:如果模式R中屬性K是其他模式的主鍵,那么K在模式R中稱為外鍵。
B. 關系數據庫中的“依賴”定義
若在一張表中,在屬性(或屬性組)X的值確定的情況下,必定能確定屬性Y的值,那么就可以說Y函數依賴於X,寫作 X → Y。
例如在學生表中,找不到任何一條記錄,它們的學號相同而對應的姓名不同。所以我們可以說姓名函數依賴於學號,寫作 學號 → 姓名。但是反過來,因為可能出現同名的學生,所以有可能不同的兩條學生記錄,它們在姓名上的值相同,但對應的學號不同,所以我們不能說學號函數依賴於姓名。
1) 部分函數依賴:設X,Y是關系R的兩個屬性集合,存在X→Y,若X’是X的真子集,存在X’→Y,則稱Y部分函數依賴於X。
舉個例子:學生基本信息表R中(學號,身份證號,姓名)當然學號屬性取值是唯一的,在R關系中,(學號,身份證號)->(姓名),(學號)->(姓名),(身份證號)->(姓名);所以姓名部分函數依賴與(學號,身份證號);
2) 完全函數依賴:設X,Y是關系R的兩個屬性集合,X’是X的真子集,存在X→Y,但對每一個X’都有X’!→Y,則稱Y完全函數依賴於X。
例子:學生基本信息表R(學號,班級,姓名)假設不同的班級學號有相同的,班級內學號不能相同,在R關系中,(學號,班級)->(姓名),但是(學號)->(姓名)不成立,(班級)->(姓名)不成立,所以姓名完全函數依賴與(學號,班級);
3) 傳遞函數依賴:設X,Y,Z是關系R中互不相同的屬性集合,存在X→Y(Y !→X),Y→Z,則稱Z傳遞函數依賴於X。
例子:在關系R(學號 ,宿舍, 費用)中,(學號)->(宿舍),宿舍!=學號,(宿舍)->(費用),費用!=宿舍,所以符合傳遞函數的要求;
C. 幾個范式的定義
1) 第一范式(1NF)
主屬性(主鍵)不為空且不重復,字段不可再分。
2) 第二范式(2NF)
在第一范式的基礎上,要求非主屬性完全依賴主屬性。(不存在非主屬性對主鍵的部分依賴)
3) 第三范式(3NF)
3NF在2NF的基礎之上,消除了非主屬性對於碼的傳遞依賴。(不能存在:非主鍵列 A 依賴於非主鍵列 B,非主鍵列 B 依賴於主鍵的情況。)
4) BC范式(BCNF)
BC范式在 3NF 的基礎上,消除主屬性對於碼的部分與傳遞函數依賴。
(1)所有非主屬性對每一個碼都是完全函數依賴;
(2)所有的主屬性對於每一個不包含它的碼,也是完全函數依賴;
(3)沒有任何屬性完全函數依賴於非碼的任意一個組合。
D. 幾個范式的定義
1) 第一范式
改為
2) 第二范式
當數據表中是聯合主鍵,但是有的列只依賴聯合主鍵中的一個或一部分屬性組成的聯合主鍵,此時需要拆表才能復合第二范式。
兩個主屬性:學號 和 課程。“學號“和”課程“就組成了聯合主鍵。
對於(學號,課名) → 姓名,有 學號 → 姓名,存在非主屬性 姓名 對碼(學號,課名)的部分依賴。
對於(學號,課名) → 系名,有 學號 → 系名,存在非主屬性 系名 對碼(學號,課名)的部依賴。
對於(學號,課名) → 系主任,有 學號 → 系主任,存在非主屬性 系主任 對碼(學號,課名)的部分依賴
3) 第三范式
Employee(emp_id,emp_name,emp_age,dept_id,dept_name,dept_info),當員工表中emp_id能夠唯一確定員工員工信息,但是dept_name可由dept_id唯一確定,此時,該表不符合第三范式,此時可以刪除除了dept_id之外的其他部門信息,把所有部門信息單獨建立一張部門表。
4) BC范式
某公司有若干個倉庫;每個倉庫只能有一名管理員,一名管理員只能在一個倉庫中工作; 一個倉庫中可以存放多種物品,一種物品也可以存放在不同的倉庫中。每種物品在每個倉庫中都有對應的數量。
那么關系模式 倉庫(倉庫名,管理員,物品名,數量) 屬於哪一級范式?
答:已知函數依賴集:倉庫名 → 管理員,管理員 → 倉庫名,(倉庫名,物品名)→ 數量
碼:(管理員,物品名),(倉庫名,物品名)
主屬性:倉庫名、管理員、物品名 ;非主屬性:數量
∵ 不存在非主屬性對碼的部分函數依賴和傳遞函數依賴。∴ 此屬於3NF。
某倉庫被清空后,需要刪除所有與這個倉庫相關的物品存放記錄,會帶來什么問題?——倉庫本身與管理員的信息也被隨之刪除了。 如果某倉庫更換了管理員,會帶來什么問題?——這個倉庫有幾條物品存放記錄,就要修改多少次管理員信息。
但是存在着主屬性對於碼的部分函數依賴與傳遞函數依賴。(在此例中就是存在主屬性 倉庫名 對於碼(管理員,物品名)的部分函數依賴:倉庫名 → 管理員。
倉庫(倉庫名,管理員) 庫存(倉庫名,物品名,數量)。這樣,之前的插入異常,修改異常與刪除異常的問題就被解決了。
16. 按照規范設計,我們將數據庫的設計過程分為六個階段:
1) 系統需求分析階段: 1:調查分析用戶活動;2:收集和分析需求數據,確定系統邊界信息需求,處理需求,安全性和完整性需求;3:編寫系統分析報告
2) 概念結構設計階段:1、需求分析數據;2、局部E-R模型;3、全局E-R模型
3) 邏輯結構設計階段:1、初始關系模式設計;2、關系模式規范化:3:模式評價
4) 物理結構設計階段;1、確定物理結構;2、評價物理結構
5) 數據庫實施階段:1、建立實際數據庫結構;2、裝入數據;3、數據庫試運行;4、應用程序編碼與調試;5、整理文檔
6) 數據庫運行與維護階段:1、維護數據庫的安全性和完整性;2、監測並改善數據庫性能;3、重新組織和構造數據庫
17. 視圖設計一般有3種設計次序
1、自頂向下。先全局框架,然后逐步細化
2、自底向上。先局部概念結構,再集成為全局結構
3、由里向外。先核心結構,再向外擴張
4、混合策略。1與2相結合,先自頂向下設計一個概念結構的框架,再自底向上為框架設計局部概念結構
18. 用命令()可以查看mysql數據庫中user表的表結構?
desc user; show create table user; describe user; 三種都可以。
19. 關系規范化中的刪除異常是指(不該刪除的數據被刪除); 應該刪除的數據未被刪除 是運行時異常,我們一般說的異常都是指運行時異常
20. SQL 語言是(非過程化)的語言,易學習。
21. 在SQL語句中引用宿主變量時,為了區別數據庫中變量,宿主變量前須加“:”,它可與數據庫中變量同名。在宿主語言語句中,宿主變量可與其它變量一樣使用,不須加冒號。當宿主變量的數據類型與數據庫中不一致時,由系統按約定轉換。
22. 數據庫中的視圖(子查詢)相關知識點:
視圖(子查詢):是從一個或多個表導出的虛擬的表,其內容由查詢定義。具有普通表的結構,但是不實現數據存儲。對視圖的修改:單表視圖一般用於查詢和修改,會改變基本表的數據,多表視圖一般用於查詢,不會改變基本表的數據。
1) 定義和概念
① 從一個或幾個基本表中根據用戶需要而做成一個虛表
② 視圖是虛表,它在存儲時只存儲視圖的定義,而沒有存儲對應的數據
③ 視圖只在剛剛打開的一瞬間,通過定義從基表中搜集數據,並展現給用戶
2) 視圖的優點
① 能分割數據,簡化觀點。可以通過select和where來定義視圖,從而可以分割數據基表中某些對於用戶不關心的數據,使用戶把注意力集中到所關心的數據列.進一步簡化瀏覽數據工作
② 為數據提供一定的邏輯獨立性。 如果為某一個基表定義一個視圖,即使以后基本表的內容的發生改變了也不會影響“視圖定義”所得到的數據
③ 提供自動的安全保護功能。 視圖能像基本表一樣授予或撤消訪問許可權,給用戶是表的一部分訪問權限而不是全部。
④ 視圖可以間接對表進行更新,因此視圖的更新就是表的更新
3) 使用視圖的一些限制和規則
① 視圖必須唯一命名,不能和表或者其他視圖重名
② 視圖可以嵌套,可以從其他視圖中構造視圖
③ order by可以用在視圖定義中,但是如果select語句從視圖中檢索數據時候,在視圖中order by將被覆蓋。
4) 視圖和基本表的區別
a) 視圖是已經編譯好的sql語句。而表不是
b) 視圖沒有實際的物理記錄。而表有。
c) 表是內容,視圖是窗口
d) 表只用物理空間而視圖不占用物理空間,視圖只是邏輯概念的存在,表可以及時對它進行修改,但視圖只能有創建的語句來修改
e) 表是內模式,視圖是外模式
f) 視圖是查看數據表的一種方法,可以查詢數據表中某些字段構成的數據,只是一些SQL語句的集合。從安全的角度說,視圖可以不給用戶接觸數據表,從而不知道表結構。
g) 表屬於全局模式中的表,是實表;視圖屬於局部模式的表,是虛表。
h) 視圖的建立和刪除只影響視圖本身,不影響對應的基本表。
5) 視圖的創建、刪除、使用、查看:
CREATE or replace view VIEW view_name AS SELECT column_name(s) FROM table_name WHERE condition |
DROP VIEW view_name |
select * from view當成表使用就好 |
由於視圖相關與一張虛表,使用show tables查看當前數據中的視圖: |
6) 通過視圖變更數據
INSERT INTO v_order(pid,pname,price) VALUES('p010','柴油','34');
跨表插入數據系統反饋報錯,提示不能修改超過一個表的數據。因此,可以通過視圖插入數據,但是只能基於一個基礎表進行插入,不能跨表更新數據。
補充考點:創建視圖的時候的 with check 語句
對視圖進行update或者insert操作時,保證更新或者插入的行滿足圖中定義的謂詞條件。例如:一張表里有個字段是專業的;你創建視圖的時候 create view stu as select 學生 from table where 專業='計算機' with check option 這樣where后面就實現了對專業的限定 以后你如果對視圖添加記錄的時候專業如果不是計算機的話不讓添加進去的。
Access的數據表視圖中,可以修改字段名稱、刪除字段和刪除記錄,但是不能夠修改字段類型。字段的類型需要在設計視圖中修改。
例題:在視圖上不能完成的操作是(C)
A 更新視圖 ; B 查詢 ; C 在視圖上定義新的表 ; D 在視圖上定義新的視圖
23. 數據的物理獨立性是指用戶的應用程序與存儲在磁盤上的數據庫中數據是相互獨立的。即,數據在磁盤上怎樣存儲由DBMS管理,用戶程序不需要了解,應用程序要處理的只是數據的邏輯結構,這樣當數據的物理存儲改變了,應用程序不用改變。
24. 對基本表 S,執行操作 DROP TABLES RESTRICT 的作用是當沒有由 S 中的列產生的視圖或約束時將表 S 刪除
drop table:從一個數據庫中刪除一個表
drop table Restrict:確保只有不存在相關視圖或完整性約束的表才可以被刪除
drop table cascade:任何引用的視圖或完整性約束都將被刪除
25. 查詢訂購單號(字符型,長度為4)尾字符是"1"的錯誤命令是______。
A SELECT * FROM 訂單 WHERE SUBSTR(訂購單號,4)="1"
B SELECT * FROM 訂單 WHERE SUBSTR(訂購單號,4,1)="1"
C SELECT * FROM 訂單 WHERE "1"$訂購單號
D SELECT * FROM 訂單 WHERE RIGHT(訂購單號,1)="1"
SUBSTR用法:
1.SBUSTR(str,pos); 就是從pos開始的位置,一直截取到最后;
2.1.SBUSTR(str,pos,len); 就是從pos開始的位置,截取len長度;
RIGHT用法
right(a,b)函數表示的是從字符表達式最右邊一個字符開始返回指定數目的字符.若 b 的值大於 a 的長度,則返回字符表達式的全部字符a.如果 b 為負值或0,則返回空字符串。
26. 在DDBS中,數據傳輸量是衡量查詢時間的一個主要指標,導致數據傳輸量大的主要原因是( C )
A 場地間距離過大;B數據庫的數據量大;C不同場地間的聯接操作;D在CPU上處理通信的代價高
DDBS 分布式數據庫系統
27. 數據庫中的字符串的連接操作符
連接運算符主要用於連接字符串,其運算符有三個:+,&,||;
1) &用來強調兩個表達式作為字符串連接,如“hello”&23&"word",結果為“hello23word”
2) +連接兩個字符串,要求+兩端的類型必須一致,如“hello”+23+"word",結果會報錯“類型不匹配”
3) 注意點:oracle數據庫:用“||”可以,用“&不可以”
MySQL數據庫:用“||”和“&”都可以
在MySql中,concat函數的作用是是將傳入的參數連接成為一個字符串,則concat(’aaa’,null,’bbb’)的結果是(Null)
CONCAT合並字符串,只要有一個字符串為空,則輸出為空;CONCAT_WS合並字符串,只要第一個字符串不為空,則輸出不為空。
28. 有關數據字典的相關知識點:
數據字典是數據庫的重要組成部分。數據庫數據字典是一組表和視圖結構。它們存放在SYSTEM表空間中。它存放有數據庫所用的有關信息,對用戶來說是一組只讀的表。數據字典內容包括: 1、數據庫中所有模式對象的信息,如表、視圖、簇、及索引等。
2、分配多少空間,當前使用了多少空間等。 3、列的缺省值。 4、約束信息的完整性。 5、用戶的名字。 6、用戶及角色被授予的權限。 7、用戶訪問或使用的審計信息。
8、其它產生的數據庫信息。
29. 有關異常的總結:
1) “插入異常”是指當要往數據庫中插入新的數據的時候,插入不成功導致異常;
2) “刪除異常”是指當要刪除數據庫中數據的時候,不能刪除,刪除不成功;
3) ”修改異常”是指當要修改數據庫中數據的時候,修改不成功;
4) 數據庫中的“插入異常”、“刪除異常”、“修改異常”是數據庫模式中存在依賴關系導致
30. 在數據庫三級模式間引入二級映象的主要作用是( 提高數據與程序的獨立性 )?
31. 模糊查詢語句,數據庫中的模糊查詢關鍵字為like,並提供了四種模糊匹配條件:
1) %:表示0~n個任意個字符
把flow_user這張表里面,列名username中含有“王”的記錄全部查詢出來
select * from flow_user where username like '%王%';
2) _:表示一個字符
只能找到“王英琨”這樣username為三個字且中間一個字是“英”的內容。
select * from flow_user where username like '_英_';
3) []:表示括號內所列字符中的一個
將找出“王飛”“李飛”“張飛”(而不是“張王李飛”)。
select * from flow_user where username LIKE'[王李張]飛';
4) [^]:表示不在括號所列之內的單個字符。
將找出不是“王飛”“李飛”“張飛“的”趙飛“、”吳飛“等。
select * from flow_user where username LIKE'[^王李張]飛';
32. 數據庫技術的根本目標是要解決數據共享的問題;數據庫管理系統的工作不包括:為定義的數據庫提供操作系統
33. 死鎖發生時( 撤消其中一個事務,並恢復到初態 )
34. Mysql實現的四種通信協議(TCP/IP,Socket,共享內存,命名管道)
35. 數據庫中的"空值" 和"NULL"的概念:
1) 空值('')是不占用空間的,判斷空字符用 = '' 或者 <> '' 來進行處理;
2) NULL值是未知的,且占用空間,不走索引;判斷 NULL 用 IS NULL 或者 is not null , SQL 語句函數中可以使用 ifnull ()函數來進行處理.
3) 在進行 count ()統計某列的記錄數的時候,如果采用的 NULL 值,會別系統自動忽略掉,但是空值是統計到其中
36. 設關系模式R(A,B,C),F是R上成立的FD集,F={A→B,C→B},ρ={AB,AC}是R的一個分解,那么分解ρ( C )?
A 保持函數依賴集F;B 丟失了A→B;
C 丟失了C→B;D 丟失了B→C
37. 數據庫恢復的基礎是利用轉儲的冗余數據。這些轉儲的冗余數據包括(日志文件,數據庫后備副本)
38. (1)PCTFREE:為一個塊保留的空間百分比,表示數據塊在什么情況下可以被insert。
(2)PCTUSED:是指當塊里的數據低於多少百分比時,又可以重新被insert。
形象舉例說明:
假如:一個杯子一共可裝10分水:
PCTFREE = 10,說明杯子裝到9分水,就不能再裝了,即:不能進行insert操作,但可以進行update操作。
PCTUSED = 40,說明杯子中的水喝到4分一下,就可以往里面裝水,即:進行insert操作。
39. 某查詢語句運行后返回的結果集為:
則最有可能的查詢語句是以下:C
A SELECT class, AVG(score) FROM test WHERE class<3
B SELECT class, AVG(score) FROM test WHERE class<3 GROUP BY class
C SELECT class, AVG(score) FROM test WHERE class<3 GROUP BY ALL class
D SELECT class, AVG(score) FROM test GROUP BY class HAVING class<3
因為出現了3班 NULL, 所以如果是D的話,就不會出現Null了。條件限制了選擇的class<3 所以只有1 ,2班有成績。
下面是幫助中group by +all的用法:
GROUP BY 子句中提供 ALL 關鍵字。只有在 SELECT 語句還包括 WHERE 子句時,ALL 關鍵字才有意義。如果使用 ALL 關鍵字,那么查詢結果將包括由 GROUP BY 子句產生的所有組,即使某些組沒有符合搜索條件的行。沒有 ALL 關鍵字,包含 GROUP BY 子句的 SELECT 語句將不顯示沒有符合條件的行的組。
注:having與where的區別:
1、 having是在分組后對數據進行過濾的。
Where是在分組前對數據進行過濾的。
2、 having后面可以使用聚合函數(統計函數)
where后面不可以使用聚合函數。
40. 五種基本關系代數運算是? (∪,-,×,π,σ )
關系運算:選擇、投影、連接、除
傳統集合運算:並、差、交、笛卡爾
5種基本運算:並、差、笛卡爾、選擇、投影
關系代數運算中的基本運算包括並(∪)、差(-)、廣義笛卡爾積(×)、投影(π)和選擇(σ),其他運算的功能都可以由這五種基本運算來實現。
投影操作是從表中選出某些列而丟棄另一些列。如果只對一個關系中的某些屬性感興趣,那么就需要使用投影操作在這些屬性上投影該關系。
關系R是的投影是從關系R中選擇出若干屬性列組成新的關系。分為兩步:
(1)選擇出指定的屬性,形成一個可能含有重復行的表。
(2)刪除重復行,形成新的關系
對關系R進行投影運算后,得到關系S,則( 關系R的元組數大於或等於關系S的元組數 )。
41. 在 SQL 語句中,與 X between 20 and 30 等價的表達式是: X>=20 AND X<=30。
42. 關系數據庫規范化是為解決關系數據庫中( 插入、刪除和數據冗余 )問題而引入的。
43. SQL語句性能分析的關鍵字是什么? EXPLAIN
explain命令在解決數據庫性能上是第一推薦使用命令,大部分的性能問題可以通過此命令來簡單的解決,Explain可以用來查看SQL語句的執行效 果,可以幫助選擇更好的索引和優化查詢語句,寫出更好的優化語句。explain語法:explain select … from … [where ...] 例如:explain select * from news;
44. 數據庫中的E-R圖
1) 實體類型的轉換:將一個實體型轉換為一個關系模式,關系的屬性就是實體的屬性;
2) 關系類型轉換分為如下幾種情況
a) 1:1聯系:可以轉換成一個獨立的關系模式,也可以與任意一端對應的關系模式合並。
如果轉換為一個獨立的關系模式,則與該聯系相連的各實體的碼以及聯系本身的屬性均轉換為關系的屬性,每個實體的碼均是該關系的候選碼。
如果與某一端實體對應的關系模式合並,則需要在該關系模式的屬性中加入另一個關系模式的碼和聯系本身的屬性。
b) 1:n聯系:可以轉換為一個獨立的關系模式,也可以與n端對應的關系模式合並。如果轉換為一個獨立的關系模式,則與該聯系相連的各實體的碼以及聯系本身的屬性均轉換為關系的屬性,而關系的碼為n端實體的碼。
c) m:n聯系:轉換為一個關系模式,與該聯系相連的各實體的碼以及聯系本身的屬性均轉換為關系的屬性,各實體的碼組成關系的碼或關系碼的一部分。
實例:
1) 部門(部門號,部門名,經理的職工號,…)
此為部門實體對應的關系模式,該關系模式已包含了聯系“領導所對應的關系模式。經理的職工號是關系的候選碼。
2) 職工(職工號,部門號,職工名,職務,…)
此為職工實體對應的關系模式,該關系模式已包含了聯系“屬於”所對應的關系模式。
3) 產品(產品號,產品名,產品組長的職工號,…)此為產品實體對應的關系模式。
4) 供應商(供應商號,姓名,…)此為供應商實體對應的關系模式 。
5) 零件(零件號,零件名,…)為零件實體對應的關系模式。
6) 生產(職工號,產品號,工作天數,…)此為聯系“生產”所對應的關系模式。
7) 供應(產品號,供應商號,零件號,供應量)此為聯系“聯系”所對應的關系模式。
45. 數據庫中的觸發器
1) 觸發器的概念
觸發器(trigger)是SQL server 提供給程序員和數據分析員來保證數據完整性的一種方法,它是與表事件相關的特殊的存儲過程,它的執行不是由程序調用,也不是手工啟動,而是由事件來觸發,比如當對一個表進行操作( insert,delete, update)時就會激活它執行。觸發器經常用於加強數據的完整性約束和業務規則等。
不會觸發觸發器的包括 SELECT、TRUNCATE、WRITETEXT、UPDATETEXT。
2) 觸發器的語法
Create trigger trigger_name ON {table_name | view_name}
{FOR | After | Instead of } [ insert, update,delete ]
AS sql_statement
刪除觸發器:drop trigger 觸發器名
3) 觸發器的分類
a) After觸發器,After觸發器要求只有執行某一操作insert、update、delete之后觸發器才被觸發,且只能定義在表上。
b) Instead of 觸發器,Instead of 觸發器表示並不執行其定義的操作(insert、update、delete)而僅是執行觸發器本身。既可以在表上定義instead of觸發器,也可以在視圖上定義。
c) 后觸發型觸發器
使用for或after選項定義的觸發器,執行過程如下:1. 執行到引發觸發器執行的語句。2. 執行該語句 。3. 執行觸發器
4) 觸發器的作用
a) 完成比約束更復雜的數據約束
b) 檢查所做的sql是否允許
c) 調用更多的存儲過程
d) 防止數據表結構更改或數據表被刪除
e) 修改其他數據表的數據
f) 發送sql mail
g) 返回自定義的錯誤信息
5) 注意事項
a) 一個表可以有多個觸發器,但一個觸發器只能對應一個表,但可以引用數據庫以外的對象
b) 同一個數據表中,對每個操作而言,可以建立多個after觸發器,但instead of 觸發器只能創建一個
c) 對某個操作,既建了after觸發器,又設置了instead of觸發器,instead of觸發器一定會激活,after觸發器不一定會被激活
46. 數據庫中的約束
1) 實體完整性:主鍵完整性的約束條件,要求主鍵不能為空(NULL)且不可以重復。
約束類型:主鍵約束(primary key)、唯一約束(unique)、自增長(auto_increment)
Sqlserver(identity)、oracle(sequence)
|
||||
|
||||
或者使用: alter table student add primary key(id)
alter table add constraint pk_stuid primary key(id)
刪除主鍵約束:alter table 表名 drop primary key
2) 參照完整性:參照完整性是相對於外鍵而言的,在數據庫中,外鍵常用來關聯兩個表,它的值要么為NULL,要么就是它參照的那個表的主鍵值。
|
|
||||
或:
alter table score1 add constraint fk_stu_score foreign key(sid) references stu(id);
3) 用戶自定義完整性:在CREATE TABLE中定義屬性時,可以根據應用程序的要求在屬性上添加約束條件(屬性限制),包括:列值非空(NOT NULL)、列值唯一(UNIQUE)、check約束(mysql不支持)check(sex =’男’or ‘女’)、默認值約束(default)
例如定義的時候可以寫:sex varchar(10) default’男’
47. 數據庫中關於刪除的幾個關鍵詞
當你不再需要該表時, 用 drop;
當你仍要保留該表,但要刪除所有記錄時, 用 truncate;
當你要刪除部分記錄時(always with a WHERE clause), 用 delete.
48. SQL 語句中修改表結構的命令是(ALTER TABLE)
修改表結構包括:增加字段、刪除字段、增加約束、刪除約束、修改缺省值、修改字段數據類型、重命名字段、重命名表等。這些操作都是用 alter table 命令來完成。常用用法如下:
1、增加字段:ALTER TABLE 表名 ADD 字段名 字段類型;
2、刪除字段:ALTER TABLE 表名 DROP COLUMN 字段列名;
3、增加約束:ALTER TABLE 表名 ADD CHECK(字段名<>'')或者 ALTER TABLE 表名 ADD CONSTRAINT 約束名 UNIQUE(字段名);
4、刪除約束:ALTER TABLE 表名 DROP CONSTRAINT 約束名;
5、修改字段缺省值:ALTER TABLE 表名 ALTER COLUMN 字段名 SET DEFAULT 默認值;
6、 修改字段數據類型:ALTER TABLE 表名 ALTER COLUMN 字段名TYPE l類型;
7、重命名字段:ALTER TABLE 表名 RENAME COLUMN 舊字段名TO 新字段名;
8、重命名表:ALTER TABLE 表名 RENAME TO 新表名。
49. 六、多表查詢(重要)
多表查詢有如下幾種:
l 合並結果集;UNION 、 UNION ALL
l 連接查詢
Ø 內連接 [INNER] JOIN ON
Ø 外連接 OUTER JOIN ON
² 左外連接 LEFT [OUTER] JOIN
² 右外連接 RIGHT [OUTER] JOIN
² 全外連接(MySQL不支持)FULL JOIN
Ø 自然連接 NATURAL JOIN
l 子查詢
1 合並結果集
1. 作用:合並結果集就是把兩個select語句的查詢結果合並到一起!
2. 合並結果集有兩種方式:
l UNION:去除重復記錄,例如:SELECT * FROM t1 UNION SELECT * FROM t2;
l UNION ALL:不去除重復記錄,例如:SELECT * FROM t1 UNION ALL SELECT * FROM t2。
3. 要求:被合並的兩個結果:列數、列類型必須相同。
2 連接查詢(非常重要)
連接查詢就是求出多個表的乘積,例如t1連接t2,那么查詢出的結果就是t1*t2。
連接查詢會產生笛卡爾積,假設集合A={a,b},集合B={0,1,2},則兩個集合的笛卡爾積為{(a,0),(a,1),(a,2),(b,0),(b,1),(b,2)}。可以擴展到多個集合的情況。
那么多表查詢產生這樣的結果並不是我們想要的,那么怎么去除重復的,不想要的記錄呢,當然是通過條件過濾。通常要查詢的多個表之間都存在關聯關系,那么就通過關聯關系去除笛卡爾積。
你能想像到emp和dept表連接查詢的結果么?emp一共14行記錄,dept表一共4行記錄,那么連接后查詢出的結果是56行記錄。
也就你只是想在查詢emp表的同時,把每個員工的所在部門信息顯示出來,那么就需要使用主外鍵來去除無用信息了。
使用主外鍵關系做為條件來去除無用信息
SELECT * FROM emp,dept WHERE emp.deptno=dept.deptno; |
在多表查詢中,在使用列時必須指定列所從屬的表,例如emp.deptno表示emp表的deptno列。
上面查詢結果會把兩張表的所有列都查詢出來,也許你不需要那么多列,這時就可以指定要查詢的列了。
SELECT emp.ename,emp.sal,emp.comm,dept.dname FROM emp,dept WHERE emp.deptno=dept.deptno; |
還可以為表指定別名,然后在引用列時使用別名即可。
SELECT e.ename,e.sal,e.comm,d.dname FROM emp AS e,dept AS d WHERE e.deptno=d.deptno;其中AS是可以省略的 |
多表連接查詢運行機制:多表查詢的過程可以理解為一個嵌套循環的過程。
for t in teacher //依次遍歷teacher表中的每一條記錄
{
for s in student //依次遍歷student表中的每一條記錄
{
if(s.java_teacher=t.teacher_id) //當滿足連接條件的時候輸出連個表連接后的結果
Output s+t
}
}
2.1 內連接
上面的連接語句就是內連接,但它不是SQL標准中的查詢方式,可以理解為方言!SQL標准的內連接為:
SELECT * FROM emp e INNER JOIN dept d ON e.deptno=d.deptno; |
INNER可以省略,MySQL默認的連接方式就是內連接
不使用WHERE,而是使用ON
內連接的特點:查詢結果必須滿足條件。例如我們向emp表中插入一條記錄:
其中deptno為50,而在dept表中只有10、20、30、40部門,那么上面的查詢結果中就不會出現“張三”這條記錄,因為它不能滿足e.deptno=d.deptno這個條件。
On子句:將連接的條件放在on子句中,而且每個on子句只能指定一個連接條件。如果需要連接N個表,則需要有N-1個join-on對。
2.2 外連接(左連接、右連接)
外連接的特點:查詢出的結果存在不滿足條件的可能。
左連接:
SELECT * FROM emp e LEFT OUTER JOIN dept d ON e.deptno=d.deptno; |
OUTER可以省略
左連接是先查詢出左表(即以左表為主),然后查詢右表,右表中滿足條件的顯示出來,不滿足條件的顯示NULL。
這么說你可能不太明白,我們還是用上面的例子來說明。其中emp表中“張三”這條記錄中,部門編號為50,而dept表中不存在部門編號為50的記錄,所以“張三”這條記錄,不能滿足e.deptno=d.deptno這條件。但在左連接中,因為emp表是左表,所以左表中的記錄都會查詢出來,即“張三”這條記錄也會查出,但相應的右表部分顯示NULL。
2.3 右連接
右連接就是先把右表中所有記錄都查詢出來,然后左表滿足條件的顯示,不滿足顯示NULL。例如在dept表中的40部門並不存在員工,但在右連接中,如果dept表為右表,那么還是會查出40部門,但相應的員工信息為NULL。
SELECT * FROM emp e RIGHT OUTER JOIN dept d ON e.deptno=d.deptno; |
連接查詢心得:
連接不限與兩張表,連接查詢也可以是三張、四張,甚至N張表的連接查詢。通常連接查詢不可能需要整個笛卡爾積,而只是需要其中一部分,那么這時就需要使用條件來去除不需要的記錄。這個條件大多數情況下都是使用主外鍵關系去除。
兩張表的連接查詢一定有一個主外鍵關系,三張表的連接查詢就一定有兩個主外鍵關系,所以在大家不是很熟悉連接查詢時,首先要學會去除無用笛卡爾積,那么就是用主外鍵關系作為條件來處理。如果兩張表的查詢,那么至少有一個主外鍵條件,三張表連接至少有兩個主外鍵條件。
3 自然連接
大家也都知道,連接查詢會產生無用笛卡爾積,我們通常使用主外鍵關系等式來去除它。而自然連接無需你去給出主外鍵等式,它會自動找到這一等式:
l 兩張連接的表中名稱和類型完全一致的列作為條件,例如emp和dept表都存在deptno列,並且類型一致,所以會被自然連接找到!
當然自然連接還有其他的查找條件的方式,但其他方式都可能存在問題!
SELECT * FROM emp NATURAL JOIN dept;內連接 SELECT * FROM emp NATURAL LEFT JOIN dept;左連接 SELECT * FROM emp NATURAL RIGHT JOIN dept;右連接 |
Using子句:用於顯示指定兩個表中的同名列,並將其作為連接條件。假設兩個表中有查過一列的同名列,如果使用自然連接(natural join),則會把所有的同名列當成連接條件,使用using子句,就可以顯示指定那些同名列作為連接條件。
4 子查詢(非常重要)
一個select語句中包含另一個完整的select語句。
子查詢就是嵌套查詢,即SELECT中包含SELECT,如果一條語句中存在兩個,或兩個以上SELECT,那么就是子查詢語句了。
l 子查詢出現的位置:
Ø where后,作為條為被查詢的一條件的一部分;
Ø from后,作表;
l 當子查詢出現在where后作為條件時,還可以使用如下關鍵字:
Ø any
Ø all
l 子查詢結果集的形式:
Ø 單行單列(用於條件)
Ø 單行多列(用於條件)
Ø 多行單列(用於條件)
Ø 多行多列(用於表)
練習:
1. 工資高於JONES的員工。
分析:
查詢條件:工資>JONES工資,其中JONES工資需要一條子查詢。
第一步:查詢JONES的工資
SELECT sal FROM emp WHERE ename='JONES' |
第二步:查詢高於甘寧工資的員工
SELECT * FROM emp WHERE sal > (${第一步}) |
結果:
SELECT * FROM emp WHERE sal > (SELECT sal FROM emp WHERE ename='JONES') |
2、查詢與SCOTT同一個部門的員工。
l 子查詢作為條件
l 子查詢形式為單行單列
3、工資高於30號部門所有人的員工信息
分析:
SELECT * FROM emp WHERE sal>(
SELECT MAX(sal) FROM emp WHERE deptno=30);
查詢條件:工資高於30部門所有人工資,其中30部門所有人工資是子查詢。高於所有需要使用all關鍵字。
第一步:查詢30部門所有人工資
SELECT sal FROM emp WHERE deptno=30; |
第二步:查詢高於30部門所有人工資的員工信息
SELECT * FROM emp WHERE sal > ALL (${第一步}) |
結果:
SELECT * FROM emp WHERE sal > ALL (SELECT sal FROM emp WHERE deptno=30) 大於所有 |
l 子查詢作為條件
l 子查詢形式為多行單列(當子查詢結果集形式為多行單列時可以使用ALL或ANY關鍵字)
4、查詢工作和工資與MARTIN(馬丁)完全相同的員工信息
分析:
查詢條件:工作和工資與MARTIN完全相同,這是子查詢
第一步:查詢出MARTIN的工作和工資
SELECT job,sal FROM emp WHERE ename='MARTIN' |
第二步:查詢出與MARTIN工作和工資相同的人
SELECT * FROM emp WHERE (job,sal) IN (${第一步}) |
結果:
SELECT * FROM emp WHERE (job,sal) IN (SELECT job,sal FROM emp WHERE ename='MARTIN') |
5、有2個以上直接下屬的員工信息
SELECT * FROM emp WHERE empno IN(
SELECT mgr FROM emp GROUP BY mgr HAVING COUNT(mgr)>=2);
l 子查詢作為條件
l 子查詢形式為單行多列
5、查詢員工編號為7788的員工名稱、員工工資、部門名稱、部門地址
分析:(無需子查詢)
查詢列:員工名稱、員工工資、部門名稱、部門地址
查詢表:emp和dept,分析得出,不需要外連接(外連接的特性:某一行(或某些行)記錄上會出現一半有值,一半為NULL值)
條件:員工編號為7788
第一步:去除多表,只查一張表,這里去除部門表,只查員工表
SELECT ename, sal FROM emp e WHERE empno=7788 |
第二步:讓第一步與dept做內連接查詢,添加主外鍵條件去除無用笛卡爾積
SELECT e.ename, e.sal, d.dname, d.loc FROM emp e, dept d WHERE e.deptno=d.deptno AND empno=7788 |
第二步中的dept表表示所有行所有列的一張完整的表,這里可以把dept替換成所有行,但只有dname和loc列的表,這需要子查詢。
第三步:查詢dept表中dname和loc兩列,因為deptno會被作為條件,用來去除無用笛卡爾積,所以需要查詢它。
SELECT dname,loc,deptno FROM dept; |
第四步:替換第二步中的dept
SELECT e.ename, e.sal, d.dname, d.loc FROM emp e, (SELECT dname,loc,deptno FROM dept) d WHERE e.deptno=d.deptno AND e.empno=7788 |
l 子查詢作為表
l 子查詢形式為多行多列
有一種子查詢可以返回多行多列,此時where子句中應當有對應的數據列,並使用圓括號將多列數據括起來。
Select *
From Student
Where (Student_id,Student_name) in (
Select teacher_id,teacher_name
From teacher
);
6、自連接:自己連接自己,起別名
求7369員工編號、姓名、經理編號和經理姓名
SELECT e1.empno , e1.ename,e2.mgr,e2.ename
FROM emp e1, emp e2
WHERE e1.mgr = e2.empno AND e1.empno = 7369;
練習:
求各個部門薪水最高的員工所有信息
select e.* from emp e,
--部門最高工資
(select max(sal) maxsal,deptno from emp
group by deptno) a
where e.deptno = a.deptno
and e.sal =a.maxsal