SQL語言藝術讀書筆記
一、創(chuàng)建
(一) 關系理論的關鍵原理:關系不包含重復數(shù)據,且記錄之間沒有順序
(二)實現(xiàn)3NF的步驟
1. 確保原子性(atomicity)
細節(jié)之中潛藏著危險,過分“精益求精”會使我們精力分散,甚至關注不相干的問題,合理把握處理數(shù)據的層次非常重要。
一般而言,應盡量使用具有實際意義的主鍵,而不是灰色的遞增整數(shù)。
所有屬性都具有了原子性,且確定了鍵,我們的數(shù)據就符合1NF了
2. 檢查對鍵的完全依賴性
在1NF的基礎上,如果去除了只依賴部分鍵的屬性后,表就符合2NF了,如在保存用戶信息時,單位,姓名都設置為字段,但同一個單位中的人員不止一個,那么在用戶表中保存的單位字段就不完全依賴用戶表的主鍵,這樣會造成數(shù)據的冗余,可以把單位分離出來。
3. 檢查屬性的獨立性
通常,滿足2NF的數(shù)據集也滿足3NF。我們可以這樣思考:屬性A的值確定之后,屬性B的值是否就確定了呢?
4. 空值對程序邏輯是危險的,必須使用空值的話,一定要清楚它在特定情況下的影響
5. 子類型。
- 表過“寬”的另一個原因是對數(shù)據之間的關系了解不夠深入。可以使用子類型。
- 給子類型表指定完全獨立于父表主鍵的主鍵,是極其錯誤的,如果子類型主鍵不是父表主鍵的子集的話,在很多方面都會導致性能降低。
- 所有子類型表中的主鍵的交集必須為空,所有子類型表中的主鍵的并集是父表中的主鍵的集合。 這樣是正確的方法。
- 開發(fā)者不應忘記數(shù)據庫恢復后要進行所有功能性的檢查,整個設計越復雜,開發(fā)者就越應記住操作數(shù)據時的諸多約束。
- 如果需要對字段使用函數(shù),就意味著表中原子性的數(shù)據不符合業(yè)務需求。
二、查詢
- 查詢臨時表的語句效率比永久表差。
- 將一次“大批量數(shù)據處理”分隔成多次“小塊處理”是個壞主意。如一次批量導入和多次循環(huán)逐條導入。
- 盡可能多地把事情交給數(shù)據庫優(yōu)化器來處理,也就是說,要盡可能使用SQL解決問題,并盡可能利用每次數(shù)據庫訪問完成盡量多的工作。
- 不要把OO方法與關系數(shù)據庫處理混為一談,混淆關系和面向對象的概念以及將表等同于類、字段等同于屬性、都是致命的錯誤。
- 沒有必要編程實現(xiàn)那些數(shù)據庫隱含實現(xiàn)的功能。
三、索引
- 對于通用目的或事務處理型數(shù)據庫而言,大部分表不需要加索引,因為許多表的查找是根據一組非常有限的條件來進行的。
- 正如數(shù)據設計的初衷所規(guī)定的,索引是一種以原子粒度訪問數(shù)據的手段,而不是為了檢索大量數(shù)據的;否則,就嚴重誤解了索引的作用。
- 你一定要非常清楚為哪些字段加索引,以及 為什么為它們加索引。
- 建立索引必須有理由,無論是對外鍵,或是其他字段,都是如此。很多情況下無需為外鍵建立索引。
- 正確使用系統(tǒng)生成鍵大有裨益,但切勿濫用。
- 索引不是萬靈藥,充分理解要處理的數(shù)據,做出合理的判斷,才能獲得高效方案。
四、SQL語句
- 關系理論姿于數(shù)據庫,正如土木工程學之于橋梁。
- 關系操作負責找出我們要操作的數(shù)據集,而“非關系操作層”對有限的數(shù)據集進行“精雕細刻”,從而產生用戶期望的結果。
- 排序,統(tǒng)計等操作屬于非關系操作范疇。
- SQL用來表達“要做什么”,優(yōu)化器來完成“如何來做”。
- 切記,關系理論的數(shù)據基礎為數(shù)據處理提供了非常嚴謹?shù)倪壿嬛С?,因此SQL藝術本應該注重減小“非關系操作層”的厚度,即盡量在“關系操作層”完成大部分處理。
- 如果是若干個小查詢,優(yōu)化器將個個優(yōu)化;如果是一個大的查詢,優(yōu)化器將它作為一個整體優(yōu)化。
- 熟練的開發(fā)者應該努力使響應時間與返回的記錄數(shù)成比例,這符合用戶的預期。
- 當視圖返回不必要的元素時,別把視圖內嵌在查詢中,而是應將視圖分解,將其組成部分加到查詢主體中。
- 高效定義過濾條件的準則是:盡快的減少必須處理的數(shù)據量。
- 在連接中指定過濾條件利于提高性能,如:
join orders o on o.custid = c.custid and a.ordered >= somefunc
- 避免在最高層使用distinct應該是一個基本原則,如要避免下面的方式
select distinct c.custname
from customers c,
orders o,
orderdetail od,
articles a
where c.city = 'dalian'
and c.custid = o.custid
and o.ordid = od.ordid
and od.artid = a.artid
and a.artname = 'aodi'
and o.ordered >= somefunc