数据库(三范式,视图,事务隔离级别,存储过程)
MySQL設計三范式的理解
目前關系數據庫有六種范式:
第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又稱完美范式)。滿足最低要求的范式是第一范式(1NF)。在第一范式的基礎上進一步滿足更多規范要求的稱為第二范式(2NF),其余范式以次類推。一般說來,數據庫只需滿足第三范式(3NF)就行了。所以這里就只記錄三范式相關的知識。
三范式:
1NF:字段不可分(原子性 字段不可再分,否則就不是關系數據庫);
原子性解釋:數據庫表的每一列都是不可分割的原子數據項,而不能是集合,數組,記錄等非原子數據項。如果實體中的某個屬性有多個值時,必須拆分為不同的屬性 。通俗理解即一個字段只存儲一項信息。
2NF:有主鍵,非主鍵字段依賴主鍵(唯一性 一個表只說明一個事物);
即滿足第一范式前提,當存在多個主鍵的時候,才會發生不符合第二范式的情況。
3NF:非主鍵字段不能相互依賴(每列都與主鍵有直接關系,不存在傳遞依賴);
滿足第三范式(3NF)必須先滿足第二范式(2NF)。簡而言之,第三范式(3NF)要求一個數據庫表中不包含已在其它表中已包含的非主鍵字段。就是說,表的信息,如果能夠被推導出來,就不應該單獨的設計一個字段來存放(能盡量外鍵join就用外鍵join)。很多時候,我們為了滿足第三范式往往會把一張表分成多張表。
反三范式
沒有冗余的數據庫未必是最好的數據庫,有時為了提高運行效率,提高讀性能,就必須降低范式標準,適當保留冗余數據。具體做法是: 在概念數據模型設計時遵守第三范式,降低范式標準的工作放到物理數據模型設計時考慮。降低范式就是增加字段,減少了查詢時的關聯,提高查詢效率,因為在數據庫的操作中查詢的比例要遠遠大于DML的比例。但是反范式化一定要適度,并且在原本已滿足三范式的基礎上再做調整的。
MySQL視圖篇
視圖是一種虛擬存在的表,對于使用視圖的用戶來說基本上是透明的。
視圖并不實際存在于數據庫,行和列的數據來自于自定義視圖查詢中使用的表,并且是在使用視圖時動態生成的。
視圖
百度百科定義了什么是視圖,但是對缺乏相關知識的人可能還是難以理解或者只有一個比較抽象的概念,筆者舉個例子來解釋下什么是視圖。
朕想要了解皇宮的國庫的相關情況,想知道酒窖有什么酒,剩多少,窖藏多少年,于是派最信任的高公公去清點,高公公去國庫清點后報給了朕;朕又想知道藏書情況,于是又派高公公去清點并回來報告給朕,又想知道金銀珠寶如何,又派高公公清點。。。過一段時間又想知道藏書情況,高公公還得重新再去清點,皇上問一次,高公公就得跑一次路。
后來皇上覺得高公公不容易,就成立了國庫管理部門,小鄧子負責酒窖,小卓子負責藏書,而小六子負責金庫的清點。。。后來皇上每次想了解國庫就直接問話負責人,負責人就按照職責要求進行匯報。
優勢:
視圖的基本操作
創建
CREATE VIEW <視圖名> AS <SELECT語句>
修改(修改視圖是指修改 MySQL 數據庫中存在的視圖,當基本表的某些字段發生變化時,可以通過修改視圖來保持與基本表的一致性。) 如果對視圖增加或刪除記錄,實際上是對基本表增加或刪除記錄。
ALTER VIEW <視圖名> AS <SELECT語句>
刪除
DROP VIEW <視圖名1> [ , <視圖名2> …]
查看視圖
DESCRIBE 視圖名;
一、事務的基本要素(ACID)
1、A****原子性(Atomicity):事務開始后所有操作,要么全部做完,要么全部不做,不可能停滯在中間環節。事務執行過程中出錯,會回滾到事務開始前的狀態,所有的操作就像沒有發生一樣。也就是說事務是一個不可分割的整體,就像化學中學過的原子,是物質構成的基本單位。
2、C****一致性(Consistency):事務開始前和結束后,數據庫的完整性約束沒有被破壞 。比如A向B轉賬,不可能A扣了錢,B卻沒收到。
3、I****隔離性(Isolation):同一時間,只允許一個事務請求同一數據,不同的事務之間彼此沒有任何干擾。比如A正在從一張銀行卡中取錢,在A取錢的過程結束前,B不能向這張卡轉賬。
4、D****持久性(Durability):事務完成后,事務對數據庫的所有更新將被保存到數據庫,不能回滾。
二、事務的并發問題
1、**臟讀:**事務A讀取了事務B更新的數據,然后B回滾操作,那么A讀取到的數據是臟數據
2、**不可重復讀:**事務 A 多次讀取同一數據,事務 B 在事務A多次讀取的過程中,對數據作了更新并提交,導致事務A多次讀取同一數據時,結果 不一致。
3、**幻讀:**系統管理員A將數據庫中所有學生的成績從具體分數改為ABCDE等級,但是系統管理員B就在這個時候插入了一條具體分數的記錄,當系統管理員A改結束后發現還有一條記錄沒有改過來,就好像發生了幻覺一樣,這就叫幻讀。
小結:不可重復讀的和幻讀很容易混淆,不可重復讀側重于修改,幻讀側重于新增或刪除。解決不可重復讀的問題只需鎖住滿足條件的行,解決幻讀需要鎖表
mysql默認的事務隔離級別為repeatable-read
1、事務隔離級別為讀提交時,寫數據只會鎖住相應的行
2、事務隔離級別為可重復讀時,如果檢索條件有索引(包括主鍵索引)的時候,默認加鎖方式是next-key 鎖;如果檢索條件沒有索引,更新數據時會鎖住整張表。一個間隙被事務加了鎖,其他事務是不能在這個間隙插入記錄的,這樣可以防止幻讀。
3、事務隔離級別為串行化時,讀寫數據都會鎖住整張表
4、隔離級別越高,越能保證數據的完整性和一致性,但是對并發性能的影響也越大。
如何解決臟讀、不可重復讀和幻讀問題
(1) 臟讀:修改時加排他鎖,直到事務提交后才釋放,讀取時加共享鎖,讀取完釋放事務1讀取數據時加上共享鎖后(這樣在事務1讀取數據的過程中,其他事務就不會修改該數據),不允許任何事物操作該數據,只能讀取,之后1如果有更新操作,那么會轉換為排他鎖,其他事務更無權參與進來讀寫,這樣就防止了臟讀問題。
(2)不可重復讀:讀取數據時加共享鎖,寫數據時加排他鎖,都是事務提交才釋放鎖。讀取時候不允許其他事物修改該數據,不管數據在事務過程中讀取多少次,數據都是一致的,避免了不可重復讀問題
(3)幻讀問題:采用Gap Lock模式,鎖定檢索范圍為只讀,這樣就避免了幻讀。
事務隔離級別:
(1)READ_UNCOMMITTED
這是事務最低的隔離級別,它充許另外一個事務可以看到這個事務未提交的數據。
解決第一類丟失更新的問題,但是會出現臟讀、不可重復讀、幻讀、第二類丟失更新的問題。
(2)READ_COMMITTED
保證一個事務修改的數據提交后才能被另外一個事務讀取,即另外一個事務不能讀取該事務未提交的數據。
解決第一類丟失更新和臟讀的問題,但會出現不可重復讀、幻讀、第二類丟失更新的問題
(3)REPEATABLE_READ
保證一個事務相同條件下前后兩次獲取的數據是一致的
解決第一類丟失更新,臟讀、不可重復讀、第二類丟失更新的問題,但會出幻讀。
(4)SERIALIZABLE
事務被處理為順序執行。解決所有問題
**
存儲過程
**
存儲過程是一組為了完成特定功能的 SQL 語句集合。
使用存儲過程的目的是將常用或復雜的工作預先用 SQL 語句寫好并用一個指定名稱存儲起來,這個過程經編譯和優化后存儲在數據庫服務器中,因此稱為存儲過程。
存儲過程通常有如下優點:
存儲過程被創建后,可以在程序中被多次調用,而不必重新編寫該存儲過程的 SQL 語句,并且數據庫專業人員可以隨時對存儲過程進行修改,而不會影響到調用它的應用程序源代碼。
存儲過程可以用流程控制語句編寫,有很強的靈活性,可以完成復雜的判斷和較復雜的運算。
由于存儲過程是在服務器端運行的,且執行速度快,因此當客戶計算機上調用該存儲過程時,網絡中傳送的只是該調用語句,從而可降低網絡負載。
存儲過程執行一次后,產生的二進制代碼就駐留在緩沖區,在以后的調用中,只需要從緩沖區中執行二進制代碼即可,從而提高了系統的效率和性能。
使用存儲過程可以完成所有數據庫操作,并且可以通過編程的方式控制數據庫信息訪問的權限。
存儲過程基本語法
CREATE PROCEDURE <過程名> ( [過程參數[,…] ] ) <過程體>
[過程參數[,…] ] 格式
[ IN | OUT | INOUT ] <參數名> <類型>
刪除存儲過程
DROP { PROCEDURE | FUNCTION } [ IF EXISTS ] <過程名>
整理中,持續更新,學習!!!
總結
以上是生活随笔為你收集整理的数据库(三范式,视图,事务隔离级别,存储过程)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 记我经历的一次公司破产经历,一行代码害死
- 下一篇: 2022爱分析·事务型关系数据库市场厂商