什么是數據庫?
數據庫是一個以某種有組織的方式存儲的數據集合。也就是:保存有組織數據的容器(一個文件或一組文件)
為什么我們需要數據庫?
毫無疑問,數據庫是用來存儲數據的。我們對excel肯定不會陌生,excel也是用來存儲數據。那既然有excel這樣非常好用的軟件了,為什么需要數據庫呢??
- excel存儲的數據量太少了。由於我們網絡發展,excel的存儲量遠遠不能支撐我們的需求。
- excel數據無法多人共享。excel只是一個單一的文件,只能是當前的用戶使用並修改。
- 數據安全性。對excle數據的修改是很隨意的。
數據庫就解決了上面的問題,並且數據庫以特殊的機制管理數據文件,對數據有極高的讀寫速度,大大超過了操作系統對常規文件的讀寫速度。
數據庫系統的組成
數據庫系統由三個層次組成:
- 數據庫(dataBase)
- 存放數據的倉庫,按照一定的格式(有組織的方式)進行儲存
- 數據庫管理系統(dataBase Manager System)
- 建立、管理、維護數據庫的系統軟件
- 數據庫應用系統(dataBase Application System)
- 使用到數據庫技術的應用軟件
數據描述與數據模型
理解數據描述
我們在現實生活中描述一個事物是非常簡單的,看到“一棵樹”,就說是“一棵樹”。
但怎么把“一棵樹“在計算機描述起來呢??計算機只識別0和1,”一棵樹“是不能直接存儲到計算機上的!
於是乎,我們就把”一棵樹“抽象出來,形成信息世界的概念模型。然后將概念模型的形式化成是DBMS支持的數據模型,存儲在計算機中。
簡單來說:數據描述就是將現實世界中的實物抽象出來,形成概念模型。把概念模型的形式轉換成是DBMS支持的類型,然后存儲到計算機中!
理解數據模型
數據模型主要用來描述數據!上邊已經說了,當我們想在計算機上存儲現實事物的數據時,需要先抽象成概念模型。將概念模型轉換成DBMS支持的數據模型,就可以把事物存儲到計算機中!
數據模型一般由三個部分組成:
- 數據結構(對象與對象之間的關系)
- 數據操作(增刪改查)
- 完整性約束(限定數據是有一定規則的,比如:年齡不能為負數)
數據模型也經歷了一個發展階段:
①:層次模型,是一種樹型(層次)結構來組織數據的數據模型。
優點:
- 結構清晰,容易理解
- 節點之間聯系可以通過指針來實現,查詢效率高
缺點:
- 對於非層次結構的數據,表示起來非常麻煩,不直觀!
②:網狀模型, 是用有向圖結構來組織數據的數據模型
優點:
- 非常靈活,更能直接地描述現實世界的事物
缺點:
- 結構復雜,非常難維護
③:關系模型,是一種用二維表格結構表示數據及數據之間聯系的數據模型。
關系模型是我們現在用得最多的數據模型。
優點:
- 數據結構簡單、清晰。無論實體還是實體集,都用相對應的二維表來表示!
- 有嚴格的數學理論根據。各種關系運算(后面會講到)
缺點:
- 查詢效率比非關系模型查,尤其是多表查詢的時候!
術語(基本概念)
我們對照着課程關系表來講解吧:
實體(Entity)
客觀存在並可相互區別的事物稱之為實體。可以看成是Java類
例子:(課程關系表)就是一個實體。
屬性(Attribute)
實體所具有的某一特性稱之為屬性。可以看成是Java類的成員變量。屬性在數據庫中又稱為字段(或者是列)
例子:(課程名),(課程號)、(學時)就是屬性名。
元組
除含有屬性名所在的行之外的其他行稱之為元組。
下面的每一行數據都稱之為元組
(C401001 數據結構 70)
(C401002 操作系統 80)
(C402001 計算機原理 60)
碼(Key)
碼也被稱作是關鍵字。它可以唯一標識一個實體。
候選碼和主碼:
- 候選碼:如果一組屬性集能唯一地標識一個關系中的元組而又不含有多余的屬性,則稱該屬性集為該關系的候選碼 。(候選碼可能不止有一個)
- 主碼:用戶選定的那個候選鍵稱為主鍵
例子:郵寄地址(城市名,街道名,郵政編碼,單位名,收件人)
它有兩個候選鍵:{城市名,街道名} 和 {街道名,郵政編碼}
如果我選取{城市名,街道名}作為唯一標識實體的屬性,那么{城市名,街道名} 就是主碼
關系模式
關系名和其屬性集合的組合稱之為關系模式。
關系模式例子:課程關系表(課程號,課程名,學時)
提示:關系模型就是關系模式組成的集合
域
關系模型要求元組的每一個分量都是原子性的,也就是說,它必須屬於某種元素類型,如Integer、String等等,不能是列,集合,記錄,數組!
域就代表着該元組中每個分量的類型,從上面的圖我們可以看出,它的域是這樣的:課程號:string,課程名:string,學時:int
數據庫體系內部結構
數據庫的體系內部結構我們可以分為三層:
- 外模式
- 邏輯模式
- 內模式
三級模式的位置:
三級模式的作用:
邏輯模式
邏輯模式是對數據庫全部數據的整體邏輯結構的描述。
例子:現在我有一個數據庫,操作權限、角色、用戶之間的關系
於是有了以下的關系模式
- 權限關系(權限編號,權限名稱,權限描述)
- 角色關系(角色編號,角色名稱,角色描述)
- 用戶關系(用戶編號,用戶名稱,用戶密碼)
在數據庫中所有關系模式的集合就組成了邏輯模式!
外模式
外模式是對數據庫用戶能看見和使用的局部數據邏輯結構的描述,是與某一應用有關的數據的邏輯表示。
外模式是可以有多個的,外模式是用戶和DBAS的接口,是對局部邏輯結構的描述!
當用戶應用程序只需要顯示用戶名稱和密碼時:
- 用戶關系(用戶名稱,用戶密碼)
在數據庫中操作局部邏輯結構就稱作為外模式!
內模式
內模式是對數據庫表物理存儲結構的描述。它定義了數據的內部記錄類型、記錄尋址技術、索引和文件的組織方式及數據控制方面的內容
DB內部體系結構的兩級映像
兩級映像分別是:
- 外模式和邏輯模式的映像
- 邏輯模式和內模式的映像
提出兩級映射的概念有什么用呢?為什么需要有這兩級映像呢??
- 當數據庫的邏輯模式結構因某種原因修改時,只要沒有改變邏輯模式中與外模式定義有關的屬性及與其關系模式名的隸屬關系,就可使外模式保持不變,從而不需修改應用程序。
- 當數據庫的內模式由於某種原因要修改時,可通過對邏輯模式與內模式之間的映象的修改,使邏輯模式盡可能地保持不變,實現內模式的改變盡可能地不修改應用程序。
也就說:在改變內部結構的時候,只要不會觸及外部的數據時,外部的數據並不需要做改變。兩級映像概念的提出也就是程序中耦合的問題!
為什么我們要學習數據庫關系運算?
學習和理解關系運算的機理,對於理解關系數據庫中的數據查詢機制有十分重要的意義。
我們可能知道多表查詢的時候要消除重復多余的數據,那重復多余的數據怎么產生的呢??WHERE字句又是怎么篩選數據的呢??這些問題我們在關系運算中可以找到答案的。
學習數據庫的關系運算,會讓我們明白SQL語句是怎么執行的,是通過什么手段讓我們得到想要的結果。
學習大綱
笛卡爾積
什么是笛卡爾積?
笛卡爾積簡單來說就是兩個集合相乘的結果。
為什么查詢數據庫會出現笛卡爾積
前面的博文已經說了,關系模型是關系模式的集合。
數據庫中的兩張表就相當於兩個集合,當我們使用SELECT語句查詢數據的時候,DBMS內部就是以集合相乘的運算得出結果
笛卡爾積的產生過程
我們發現:笛卡爾積的基數是每個集合的元組相乘!
得出來的數據內容是難以符合現實中的實際情況的
為了更好地看見效果,我都會以實際的SQL語句來看效果,然后說明問題的。
emp表的記錄有14條:
dept表有4條記錄:
我們來看看SMITH,在emp表中,他只在20部門。
但在兩張表查詢后,10、20、30、40部門他都在了!!我們再觀察56條數據,發現每個人都有4個部門,這樣的數據是不合理的!!
再回到初衷,我們查詢兩張表的目的是什么??在查詢員工信息的同時,也能知道員工的部門名稱是什么!!!所以,我們查詢的記錄數是不應該有56條這么多的。。我們查詢的記錄數應該是員工表的記錄數,也就是14條而已!
我們再來分析:emp表中有deptno字段,dept表中也有deptno字段!而且發現,emp表中的deptno字段的取值范圍是由dept表中deptno字段來決定的!!!
所以,我們可以使用等值連接(emp.deptno=dept.deptno)來消除笛卡爾積,這樣就達到我們的目的了!
基於傳統集合理論的關系運算
在Oracle上,操作集合的語法提供了4個關鍵字:
- UNION(並集,重復的元組不顯示)
- UNION ALL(並集,重復的元組也會顯示)
- MINUS(差集)
- INTERSECT(交集)
並
顯示查詢結果的全部信息,消除重復的元組
查詢所有辦事員和經理的信息
SELECT *
FROM emp
WHERE job = 'MANAGER'
UNION
SELECT *
FROM emp
WHERE job = 'CLERK';
注意:使用UNION並操作,比使用關鍵字OR的性能要好!
交
返回查詢結果相同的部分
查詢10部門的信息
SELECT *
FROM dept
INTERSECT
SELECT *
FROM dept
WHERE deptno = 10;
(全部部門和部門10只有部門10是相同的,所以最后返回的是部門10的結果)
差
返回的查詢結果是
SELECT *
FROM dept
MINUS
SELECT *
FROM dept
WHERE deptno = 10;
關系代數特有的關系運算
投影
投影的運算過程:
首先按照j1,j2,…,jk的順序,從關系R 中取出列序號為j1,j2,…,jk(或屬性名序列為Aj1,Aj2,…,Ajk )的k 列,然后除去結果中的重復元組,構成一個以Aj1,Aj2,…,Ajk為屬性順序的k 目關系。
簡單來說:取出一個查詢結果中某某列,並消除重復的數據,這就是投影!
- 投影是從列的角度進行的運算
- 投影的下標可是列序號,也可是列屬性名
查詢出所有部門的編號
SELECT deptno
FROM dept;
查詢時的過程:先查詢得出dept表的所有結果,再通過投影運算只提取"deptno"的列數據,如果 SELECT 后邊跟的是"*",那么就是投影全部數據!
選擇
使用比較運算符、邏輯運算符,挑出滿足條件的元組,運算出結果!
查詢出工資大於2000的員工的姓名
SELECT ename
FROM emp
WHERE sal > 2000;
過程:首先查詢出emp表的所有結果,使用選擇運算篩選得出工資大於2000的結果,最后使用投影運算得出工資大於2000員工的名字!
除運算
除運算的實際應用我還沒想明白~~~如果有朋友知道除運算能夠用在數據庫的哪處,請告訴我一聲哈。。
我們也了解一下除運算的過程吧:關系R有ABCD,關系S有CD,首先投影出AB(因為S有CD),再用投影出來AB的結果和關系S做笛卡爾積運算。如果做的笛卡爾積運算記錄在R關系中找到相對應的記錄,那么投影的AB就是結果了!
連接運算
連接運算其實就在笛卡爾積運算的基礎上限定了條件(某列大於、小於、等於某列),只匹配和條件相符合的,從而得出結果!
自然連接
自然連接就是一種特殊的連接運算,它限定的條件是【某列等於某列】。自然連接我們經常使用到。消除笛卡爾積其實就是自然連接了!
SELECT *
FROM emp, dept
WHERE dept.deptno = emp.deptno;
設定將dept表的deptno列和emp的deptno列為相同【這就是自然連接】
如果文章有錯的地方歡迎指正,大家互相交流。習慣在微信看技術文章,想要獲取更多的Java資源的同學,可以關注微信公眾號:Java3y