資料庫的設計總結
首先對資料庫的整體結構進行圖形化的設計,然後在依據圖形對資料庫結構進行建立。簡單來說,資料庫設計就是根據業務系統的具體需要,結合我們所選用的DBMS(資料庫管理系統),為這個業務系統構造出最優的資料儲存模型,並建立好資料庫中的表結構及表與表之間的關聯關係的過程。使之能有效的對應用系統中的資料進行儲存,並可以高效的對已經儲存的資料進行訪問。 應用系統中的資料可以有多種儲存方式,可以把所有資料儲存在一張表中,但是這樣就不能達到高效訪問的目的。
為什麼要進行資料庫設計?
好的設計:減少資料多餘,避免資料維護異常,節約儲存空間,高效的訪問 壞的設計:存在大量資料多餘,存在資料插入、更新、刪除異常,浪費大量儲存空間,訪問資料低效。 如果資料庫已經在生產環境運行了一段時間之後,在想對資料庫進行調整,就會影響業務的正常執行,所以在最初就要設計出簡潔、高效的資料結構。
設計步驟:
1.需求分析:資料是什麼,資料有哪些屬性,資料和屬性各自的特點有哪些; 2.使用ER圖對資料庫進行邏輯建模(跟我們所選的具體的資料庫管理系統是沒有關係的),大部分的表關係也是在這一步完成的 3.物理設計:根據資料庫自身的的特點把邏輯設計轉換為物理設計; 4.維護優化:新的需求進行建表,索引優化,大表拆分。隨著應用程式上線的時間越來越久,需求越來越多,資料結構也會越來越複雜,所以在維護優化的時候也要遵循以上幾步,完了之後再進行頁面的操作,這樣保證資料結構永遠是最優的。
需求分析:
瞭解系統中所要儲存的資料 瞭解資料的儲存特點,比如有的有時效性,可以採用過期清理的方式儲存,有的沒有 瞭解資料的生命週期,可以採用分庫分表的方式儲存 小問題:
以上選擇原則主要從兩個角度考慮: 1. 在對資料庫進行比較(查詢條件、JOIN條件及排序)操作時,同樣的資料,字元處理往往比數字處理慢。 2.在資料庫中,資料處理以頁為單位,列的長度越小,利於效能提升。如,SQLServer是8K位元組一頁,MYSQL在Innodb中預設16K位元組一頁,列的長度越小,一頁所能儲存的資料量就越多,在載入相同資料量的時候,如果列越小,頁數越少,IO的效能就會提高,資料庫最大的瓶頸不是CPU,而是磁碟的IO瓶頸。 Char與Varchar的選擇 1. 如果列中要儲存的資料長度差不多是一致的,則應該考慮用char,否則應考慮用Varchar 2. 如果列中的最大資料長度小於50Byte,則一般也考慮用Char,當然,如果這個列很少用,則基於節省空間和減少IO的考慮,還是可以用Varchar 3. 一般不宜定義大於50Byte的Char型別列 不同的字元型別它的位元組長度是不一樣的,如UTF-8,每個字元佔3個位元組。 Decimal和float的選擇 1. decimal用於儲存精確資料,而Float只能用於儲存非精確資料。 2. 由於Float的儲存空間開銷一般比Decimal小(精確到7位小數只需要4個位元組,而精確到15位小數只需要8位元組)。因此,精確資料只能選擇Decimal型別,而非精確資料優先選擇Float型別。 時間型別 1. 使用Int儲存時間欄位的優缺點 優點:欄位長度比datetime小 缺點:使用不方便,要進行函式轉換 限制:只能儲存到2038-1-19 11:14:07即2^32為2147483648 2. 需要儲存的時間粒度 年月日時分秒周 如何選擇主鍵 1. 區分業務主鍵和資料庫主鍵 a) 業務主鍵用於表示業務資料,進行表與表之間的關聯 b) 資料庫主鍵為了優化資料儲存(Innodb會生成6個位元組的隱含主鍵) 2. 根據資料庫的型別,考慮主鍵是否要順序增長 有些資料庫是按主鍵的順序邏輯儲存的 3. 主鍵的欄位型別所佔空間要儘可能的小 對於使用聚集索引方式儲存的表,每個索引後都會附加主鍵資訊 避免使用外來鍵約束 外來鍵是用於保持資料完整性的一種方式,但是在高併發的網際網路中,如果我們使用外來鍵,會帶來負面影響,首先,對資料的匯入操作,如果使用外來鍵,每寫一條資料都要查是否符合外來鍵約束,是非常耗時的,尤其在高併發的時候。索引是為提高查詢效率而建立的。1.降低資料匯入的效率2增加維護成本3雖然不建議使用外來鍵約束,但是相關聯的列上一定要建立索引 避免使用觸發器 我們經常會使用觸發器來減少程式上的邏輯處理,比如在操作某張表的時候同時要記錄日誌,通常會使用觸發器的方式向一張日誌表中插入資料。對於MySQL來說,使用Innldb,雖然支援觸發器,但是每一種觸發器只支援一個,before/after……一共就需要6種觸發器,如果建立觸發器之後,在使用一些其他的工具,就會出現不能建立觸發器的情況,給維護帶來影響。如果大量使用觸發器來保證業務邏輯,業務邏輯出現變更,其他人不知道的情況下,可能會影響業務規則。1.降低資料匯入的效率2可能會出現意想不到的資料異常3使業務邏輯變得複雜。 關於預留欄位 1. 無法準確的知道預留欄位的型別 2. 無法準確地知道預留欄位中所儲存的內容 3. 後期維護預留欄位所要的成本,同增加一個欄位所需要的成本是相同的 4. 嚴禁使用預留欄位 反正規化化 反正規化化是針對正規化化而言的,是為了效能和讀取效率的考慮而適當的對第三正規化的要求進行違反,而允許存在少量的資料多餘,即用空間來換時間。 好處:1減少表的關聯數量 2.增加資料的讀取效率 3.反正規化化一定要適度 資料庫維護和優化 維護資料字典 1. 使用第三方工具對資料字典進行維護 2. 利用資料庫本身的備註欄位來維護資料字典 3匯出資料字典 維護索引 如何選擇合適的列建立索引 1出現在Where從句,Group By從句,ORDer By從句中的列 2可選擇性高的列要放到索引的前面 3索引中不要包括太長的資料型別 注意:索引並不是越多越好,過多的索引不但會降低寫效率,而且會降低讀的效率;定期維護索引碎片;在SQL語句 中不要使用強制索引關鍵字 維護表結構 1使用線上變更表結構的工具2同時對資料字典進行維護3控制表的寬度和大小 資料庫中適合的操作 1批量操作VS逐條操作:批量適合在資料庫中完成,逐條適合在程式中完成 2禁止使用Select*這樣的查詢:IO的浪費,程式可能會出錯 3控制使用使用者自定義函式:雖然函式很方便,但大量使用會對索引造成影響,使用函式,列中的索引就會不起作用 4不要使用資料庫中的全文索引:需要另外建立索引檔案對索引維護,對中文的支援不太好,如果需要,最好使用專業的搜尋引擎完成 在適當的時候對錶進行水平拆分和垂直拆分 為了控制表的寬度可以進行表的垂直拆分:當列非常多的的時候,每頁的行數就會減少,儲存的資料就少了,IO 的效率就會減小,這時可以把一張大表拆分成幾張小表,拆分原則:1經常一起查詢的列放在一起2text/blob等大欄位拆分出到附加表中,可以優化IO,同時減少SQL的複雜程度,不需要關聯操作了 表的水平拆分 為了控制表的大小可以進行表的水平拆分 每張表都有主鍵,可以利用主鍵的Hash值進行拆分