1. 程式人生 > >四種高效資料庫設計思想——提高查詢效率

四種高效資料庫設計思想——提高查詢效率

【開篇】

設計資料庫表結構時,我們首先要按照資料庫的三大正規化進行建立資料庫。
1. 1NF每列不可拆分
2. 2NF確保每個表只做一件事情
3. 3NF滿足2NF,消除表中的依賴傳遞。
三大正規化的出現是在上世紀70年代,由於記憶體資源比較昂貴,所以嚴格按照三大正規化進行資料庫設計。而如今記憶體變得越來越廉價,在考慮效率和記憶體的基礎上我們可以做出最優選擇以達到最高效率。建立資料庫先按照三大正規化進行建立,如果出現由於業務邏輯查詢而造成效率低的現象,可以違反三大正規化進行修改資料庫。總之,效率第一。

分散計算:

分散計算的優缺點:

缺點:程式碼量太大、維護困難。
優點:提高執行效率、查詢速度快、提高了資料的檢索效率。

什麼情況下使用分散計算:

合同和貨物是一對多的關係,貨物和附件是一對多的關係。如果按照傳統的方式獲得某個合同的總金額:那麼我們需要從查詢合同———>合同下的貨物——>貨物下的附件。從頁面進行計算:合同金額=貨物單價數量+附件單價數量 (每個貨物的總金額計算出來+每個貨物下所有附件的總金額計算出來 然後加到一起構成合同的總金額)這樣頁面上上的資料計算量是非常龐大的,所以就會造成使用者少的時候頁面載入速度還可以,使用者量一旦多起來就會造成頁面載入很慢,使用者不願等待的現象出現。

措施

合同、貨物、附件中分別加入總金額的冗餘欄位:可以在平時新增貨物時,新增附件時,分別計算出貨物總金額,附件總金額,加到資料庫中,在更新購銷合同金額。這樣就相當於將一次更新的工作量分散到平時的多次計算過程中,所以查詢購銷合同總金額的速度就會很快。從資料庫查詢,遠比從頁面計算效率要高N多倍。

打斷設計思想:

當關聯查詢的層級大於4層時,就要考慮打斷設計,這樣可以藉助跳躍查詢實現查詢速度翻倍。
就是在傳統的一對多關係中,都會在多方加入一個一方的主鍵作為外來鍵,但在是在打斷設計思想的指導下,不會這樣實現,它會在一的一方加入一個冗餘欄位,用於儲存多的一方的主鍵,並且指定分隔符進行分隔。雖然多的一方沒有加入一的一方的主鍵做外來鍵,但仍保持了原有的一對多關係。
真正的實現原理:就是通過打段欄位,實現資料的冗餘,從而一樣的可以解決一個報運單下多個購銷合同的問題。

這裡寫圖片描述

1.傳統做法:

出口報運單物件——>加載出購銷合同的集合——>遍歷出每個購銷合同——>通過購銷合同得到貨物——>再通過貨物得到附件。

2.打段設計基礎上的做法:

出口報運單——>得到它的一個欄位(購銷合同id形成的集合)——>直接到貨物表中進行查詢(from ContractProduct cp where cp.contract.id in(購銷合同id形式的集合))

打斷設計+跳躍查詢做法:

按照傳統設計方法:

財務如果想知道這筆款項從哪個貨物/附件是從哪個生產廠家生產的:一個環節套一個環節,不可跳躍。一對一對應關係,通過物件導航得用很多HQL語句才能夠導到廠家資訊。關聯7級才能找到目標物件。載入速度一定很慢!
這裡寫圖片描述

打斷設計+跳躍查詢做法應用:

本模組的資料表:
本模組的資料表

這裡寫圖片描述

裝箱單和報運單:
裝箱單和報運單

跳躍查詢

跳躍查詢的前提:提前採用打斷設計表的優化,而打斷設計思想的關鍵是欄位的冗餘,就是在報運單中加入一個冗餘欄位嗎,放入購銷合同的id集合。

財務人員得到財務報運單ID——>裝箱單(Export_IDS)——>報運單(Export_ID in(Export_IDS))——>跳躍查詢直接查詢貨物(from CONTRACT_PRODUCT WHERE CONTRACT_PRODUCT_ID IN (購銷合同裡面合同編號的集合(正好是用逗號隔開的一堆值即CONTRACT_IDS的值)))——>貨物裡本身就有廠家的廠家名資訊等。操作完成!
三次查詢就可以拿到最終結果

資料搬家:

資料搬家也是資料庫優化的一種:表級別的資料冗餘,再新增一個出口報運單時,就能得到這個報運單所報運的貨物和附件,如何實現報運單下貨物和附件的資料,實現原理就是首先找到購銷合同物件,再得到購銷合同下的貨物和附件,針對貨物和附件分別進行資料拷貝。
應用:
傳統:通過商品明細——貨號——查詢貨物物件——物件導航得到附件
資料搬家:商品明細物件導航——附件資訊
之前查三次,現在查兩次就可以得到報運商品的資訊。
冗餘沒問題,效率第一位。

原理圖:
資料搬家

小結:

以上四種方式均違反了資料庫的三大正規化,採用了資料冗餘方式,小編不是主張大家採用資料冗餘,而是在三大正規化和查詢效率發生衝突的情況下,我們採用違法三大正規化,選擇效率優先原則!這四種方式,是我工作中用到的,效率較高的四中方式,與大家分享!