![](https://img2023.cnblogs.com/blog/3076680/202308/3076680-20230829150945972-2083299480.png) # 1. 精心設計的應用程式通常會在保持實現細節私有的同時公開公有介面,以便未來在不影響最終用戶的情況下修改設計 ...
1. 精心設計的應用程式通常會在保持實現細節私有的同時公開公有介面,以便未來在不影響最終用戶的情況下修改設計
2. 視圖
2.1. 不同於數據表,視圖並不涉及數據存儲,不用擔心視圖會填滿你的磁碟空間
2.2. 一種數據查詢機制
2.3. 從用戶的視角來看,視圖和數據表沒什麼兩樣
3. 為什麼要使用視圖
3.1. 數據安全
3.1.1. 如果你創建了數據表並允許用戶查詢,用戶就可以訪問數據表中的每一行和每一列
3.1.2. 保持數據表的私有性(不授權任何用戶select許可),然後創建一個或多個視圖,忽略或模糊化(比如customer_vw.email列採用的'*'方法)敏感列
3.1.3. 虛擬私有資料庫(virtual private database,VPD)
3.1.3.1. Oracle Database用戶另一種選擇可以保護數據表的行列數據安全
3.1.3.2. VPD允許用戶對數據表施加策略,伺服器據此對用戶的查詢進行修改
3.2. 數據聚合
3.2.1. 生成報表的應用程式通常需要聚合數據
3.2.2. 將數據預先在數據表中聚合而不是使用視圖求和以極大地提高查詢性能
3.3. 隱藏複雜性
3.3.1. 為了使最終用戶免受複雜性的影響
3.4. 連接分區數據
3.4.1. 為了提升性能會將較大的數據表拆分為多個部分
3.4.2. 設計人員可以在無須強制資料庫用戶修改查詢的情況下改動底層數據的結構
4. 可更新視圖
4.1. MySQL、Oracle Database和SQL Server都允許用戶在遵守特定限制的前提下通過視圖修改數據
4.2. MySQL滿足下列條件,視圖就是可更新的
4.2.1. 沒有使用聚合函數(max()、min()、avg()等)
4.2.2. 視圖沒有使用group by或having子句
4.2.3. select或from子句中不存在子查詢,並且where子句中的任何子查詢都不引用from子句中的數據表
4.2.4. 視圖沒有使用union、union all或distinct
4.2.5. from子句至少包括一個數據表或可更新視圖
4.2.6. 如果有不止一個數據表或視圖,from子句只使用內連接
5. 索引
5.1. 查找資源內特定項的一種機制
5.2. 資料庫伺服器也使用索引來定位數據表中的行
5.3. 與普通的數據表不同,索引是一種以特定順序保存的專用數據表
5.4. 索引並不包含實體的所有相關數據,而是只包含那些可用於定位數據表中行的列,以及描述這些行所在的物理位置信息
5.5. 索引的作用就是使檢索數據表中行和列的子集實現便捷化,無須再檢查數據表中的每一行
5.6. MySQL 5.0版也提供了create index,但該命令被映射到alter table命令,仍然必須使用alter table命令創建主鍵索引
5.6.1. mysql-
-> ALTER TABLE customer
-> ADD INDEX idx_email (email);
5.6.2. sql
CREATE INDEX dept_name_idx
ON department (name);
5.7. MySQL也支持drop index命令,不過同樣是被映射到alter table命令
5.7.1. mysql
-> ALTER TABLE customer
-> DROP INDEX idx_email;
5.7.2. sql
DROP INDEX idx_email; (Oracle)
DROP INDEX idx_email ON customer; (SQL Server)
5.8. MySQL用戶可以使用show命令查看特定數據表的所有索引
5.9. 所有的資料庫伺服器都允許查看可用的索引
5.10. 唯一索引
5.10.1. 提供普通索引所能提供的所有便利
5.10.2. 避免索引列出現重覆值
5.10.3. 只要有行插入或是索引列被修改,資料庫伺服器就會檢查唯一索引,以查看該值是否已經在數據表中的其他行存在
5.10.4. SQL Server和Oracle Database用戶只需在創建索引時加入unique關鍵字
5.10.4.1. sql
CREATE UNIQUE INDEX idx_email
ON customer (email);
5.10.5. mysql
-> ALTER TABLE customer
-> ADD UNIQUE idx_email (email);
5.11. 多列索引
5.11.1. 在創建多列索引時,必須仔細考慮哪一列在前,哪一列在後,這樣才能使索引儘可能地發揮作用
5.11.2. 如果需要確保充分的響應時間,完全可以基於不同順序為列的同一集合創建多個索引
5.11.3. mysql
-> ALTER TABLE customer
-> ADD INDEX idx_full_name (last_name, first_name);
5.12. 索引類型
5.12.1. B樹索引
5.12.1.1. 平衡樹索引(balanced-tree index)
5.12.1.1.1. B樹索引(B-tree index)
5.12.1.2. MySQL、Oracle Database和SQL Server均預設採用B樹索引
5.12.1.3. B樹索引擅長處理包含大量不同值的列
5.12.2. 點陣圖索引
5.12.2.1. 對於那些只包含少量值卻占據了大量行的列(所謂的低基數數據)
5.12.2.2. 對於低基數數據而言,點陣圖索引是一種友好且緊湊的索引解決方案
5.12.2.3. 如果列中存儲的值的數量相較於行數攀升得過高(所謂的高基數數據),這種索引策略就不適合了,因為伺服器需要維護太多的點陣圖
5.12.2.4. Oracle Database引入了點陣圖索引(bitmap index),其為存儲在列中的每個值生成一個點陣圖
5.12.2.4.1. CREATE BITMAP INDEX idx_active ON customer (active);
5.12.2.5. 通常用於數據倉庫環境,其中大量數據通常在包含相對較少值的列(例如銷售季度、地理區域、產品、銷售人員)上進行索引
5.12.3. 文本索引
5.12.3.1. MySQL和SQL Server提供的是全文索引(full-text index)
5.12.3.2. Oracle Database提供了一套稱為Oracle Text的強大工具集
5.13. 允許用戶查看查詢優化器是如何處理SQL語句的
5.13.1. SQL Server用戶可以在執行SQL 語句之前通過發出set showplan_text on語句查看該語句的執行計劃
5.13.2. Oracle Database提供了explain plan語句,通過執行該語句可以將執行計劃寫入專用的數據表plan_table
5.14. 索引的不足
5.14.1. 索引並不是越多越好
5.14.1.1. 每個索引其實都是一個數據表(特殊類型的表)
5.14.1.2. 索引越多,伺服器就需要做越多的工作來保持所有模式對象都處於最新狀態,這會使伺服器的運行速度減慢
5.14.2. 索引需要磁碟空間,同時也需要管理員花費精力進行管理,因此對於索引的最佳策略就是僅當有明確需求時才添加索引
5.14.2.1. 如果出於一些特殊目的要用到索引,比如每月的例行維護工作,可以先添加索引,例行維護,然後再刪除索引,下次需要例行維護時再如此重覆
5.14.2.2. 數據被連夜載入到數據倉庫時就會出現問題,常見做法是在數據被載入之前撤銷索引,然後在數據倉庫開放業務之前重新創建索引
5.15. 索引不能太多,也不能太少
5.15.1. 確保所有主鍵列被索引
5.15.2. 對於多列主鍵,可以考慮為主鍵列的子集或是以不同於主鍵約束定義的順序為所有主鍵列創建額外的索引
5.15.3. 為所有被外鍵約束引用的列創建索引
5.15.4. 為被用於頻繁檢索數據的列創建索引
5.15.5. 除了短字元串(2~50個字元)列,大多數日期列也是不錯的候選對象
6. 約束
6.1. 施加於數據表中一列或多列的限制
6.1.1. 如果沒有約束,資料庫的一致性就會存疑
6.2. 主鍵約束
6.2.1. 標識一列或多列,保證其值在數據表中的唯一性
6.3. 外鍵約束
6.3.1. 限制一列或多列只能包含其他數據表的主鍵列中的值
6.3.2. on delete restrict
6.3.2.1. on delete restrict,如果刪除了父表(address或store)中被子表(customer)引用的行,伺服器會引發錯誤
6.3.3. on delete cascade
6.3.4. on delete set null
6.3.5. on update restrict
6.3.6. on update cascade
6.3.6.1. on update cascade,使伺服器將父表(address或store)主鍵值的改動傳播到子表(customer)
6.3.7. on update set null
6.4. 唯一約束
6.4.1. 限制一列或多列的值,保證其在數據表中的唯一性
6.5. 檢查約束
6.5.1. 限制列的可用值範圍
6.6. sql
ALTER TABLE customer
ADD CONSTRAINT fk_customer_address FOREIGN KEY (address_id)
REFERENCES address (address_id) ON DELETE RESTRICT ON UPDATE CASCADE;
ALTER TABLE customer
ADD CONSTRAINT fk_customer_store FOREIGN KEY (store_id)
REFERENCES store (store_id) ON DELETE RESTRICT ON UPDATE CASCADE;