iT邦幫忙

0

請問如何以程式的方式解決資料庫過度正規化

  • 分享至 

  • xImage

大大好
想請問是不是有甚麼方式
可以以最不痛的方式解決資料庫過度正規化的問題
因為我們公司的 DBA 非常的....難溝通
而又是不同部門,老闆去跟他們溝通也無效ˊˋ
他們非常的注重正規化到走火入魔的地步
嚴重影響程式的執行效率
比如一個最簡單的目前庫存數量查詢
就要 Join 6 張資料表......
如果再加上查詢條件
那個速度會把使用者逼瘋
程式已經盡可能的做優化了
不過因為有即時性的需求
以及公司的政策
所以不允許我們做一個備份資料庫在本地 (資安是很好的理由...)

請問有相關經驗的大大
有沒有神奇的方法或工具可以消除資料庫過度正規化所帶來的效能損失

以前自己在規劃系統的時候
資料庫架構與正規化是以最大效能下去考量
搭配良好的程式處理邏輯
一天幾十萬筆資料也是秒查的 =口=
有點懷念以前的日子

謝謝大大的指點

看更多先前的討論...收起先前的討論...
weiclin iT邦高手 4 級 ‧ 2019-02-17 14:18:27 檢舉
做好 profiling, 之後任何效能問題, 把鍋都甩給 DBA
資料庫10秒鐘~程式10分鐘~
暐翰 iT邦大師 1 級 ‧ 2019-02-18 09:16:47 檢舉
通常非正規轉成正規化Join查詢,不會慢到這樣地步才對
q00153 iT邦新手 3 級 ‧ 2019-02-18 11:39:55 檢舉
Hi~感謝各位大大的建議
這裡有個譬喻 (PS.非完整現況,只是用來舉例)

如果主管或倉管要看過去一年的庫存數量分析表
需要串接下面六張資料表做查詢
然後做成加總的統計表+圖

倉庫資料 倉庫與儲位資訊
物品資料 材料與成品清單
人員資料 姓名、員工編號等…
倉儲紀錄 哪個時間點有哪些物品的紀錄
作業紀錄 哪個時間點有那些物品進出的作業紀錄
物流單紀錄 申請入庫/提領等的紀錄

比如以上的案例
所以查詢時要 join 很多資料表
依照使用者的關鍵字下去篩選
然後把一年份的資料依照使用者的分類條件做 group
然後依照需求做加總、百分比、計算趨勢等....
最後呈現在網頁上

可以想像使用者每次送出一次搜尋就要整個流程跑一次
是有點...多餘的感覺

以前的做法是先將最小單位的 group 做好統計在一張資料表
比如最小是以日為單位
這樣一年就只需要搜尋 365 筆資料然後呈現在網頁上
不用統計假設一天 500 筆倉儲資料 * 365 天=182500筆資料

(以上只是舉例,不是真實情況
只是為了說明,對於已經成立的歷史統計資料
個人習慣的做法是先依照使用者的搜尋條件等要求
預先計算好數據,然後儲存在資料庫
這樣效能真的差很多......
說真的,還是要告訴你一些話。因為你的思維跟我公司一位工程師很像。
覺得自已的理解是對的。這樣效能一定會變差。

請先跳拖你的思維。因為資料庫的運做除非你今天非常的了解及明白。但還請先不要用自已的想法來認定,這樣的效能會變差。

為何要分表,為何要join表處理。其中的優點你是否有去研究過,還是你只看其缺點而已?

認真來說,你上面這段對話,我看完只會搖頭。因為你還是在認為這樣效能會很差。用自已的思考來解釋這樣的行為認定自已是對的。

如果認為我說的話很難聽。你可以忽略掉不看。但請不要自已在這邊覺得自已的理解沒問題。這真的看完會搖頭。

麻煩你,去跟dba低頭,多多去了解跟學習。如果一時之間轉不過來。先拋棄掉之前所學的資料庫認知。重新從網站或是線上的各位高手學習。
不要一直還在自已的認知範圍。

ps:我剛有說過我公司有一位工程師也是跟你有同樣理解。認定這樣子的效能是最差。我用了1千萬筆資料,花了4個多小時重新寫程式。將他理解的東西,還有我要跟他說明的東西,一次透給他看。並告知他這樣的寫法會怎麼樣。另外一種寫法會怎麼樣,不要去跟dba衝突。他們有他們的一定知識。要學著去如何理解。

你一開始就說「過度正規化」的口氣。我就非常的反感。

對了,忘了說,我並不是dba。
用CTE 先縮小範圍,再做join之類的查詢試試。經驗是有計算的(COUNT,MAX)之類的查詢語法若寫在WHERE條件裡會很影響效能,也可以先用CTE先做GROUP BY之後再做join或是條件判斷。
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
0

資料庫過度正規化? 沒什麼過度正規化的問題,
join 多資料表並不會慢,6張表算是小case,大公司20張表的都多的是,
問題在join的方式,如果是1對1的表格,可以直接join查詢,
1對多或其他的類型,可以另外再join,或是用程式比對處理,
當然不要傻傻用for loop去直接比對查詢,實際作法還是要看你的資料而定,
一次查詢慢,就分兩或三次,再用程式去組合處理
/images/emoticon/emoticon13.gif

0
註冊單
iT邦新手 4 級 ‧ 2019-02-17 20:39:00

少說話可能會活更久
可能DBA有無法說出的苦衷 DBA真相沒坦白
最終跟你說資安問題
沒什麼特別就繼續SOP下去
免得最後變成HELP
想想有什麼好改變 講講就好算了......

1
fuzzylee1688
iT邦研究生 3 級 ‧ 2019-02-18 11:05:48

請把你常用到的欄位請DBA用view做出來, 以後跑太慢, 把責任推給他, 他自然會想法子優化改善的.

1

基本上,dba的要求是對的。並沒有所謂的過度正規化。
要改變的並不是dba,而是開發人員。

一般正規化的db,在程式上的sql處理會比較不一樣。
如過有許多分表的問題。你可以將其分表完成後。使用view的方式來結合你的程式碼來處理。
這也是正規化的一種方式。

當然,我也並不是替dba說話。或許你們的dba本身的能力跟技術也不足。
他們並無法去處理高載效能及即時多重的情況。
這時你們還是需要與dba他們溝通處理。在其安全性上及效能性上,去取得一個平衡點。

畢竟,如果他們不要求你們。一但你們的程式有發生什麼問題了。
相信開發者會直接怪dba人員。要求dba處理。dba則希望是由開發者處理。
這都是萬年不變定律。所以他們為了省下自已的麻煩。會給你們做這樣的要求其實也是合情合理的。

最重要的點還是在於溝通及公司利益需求的最大的點。

我公司雖然也是有區分dba跟開發者。但因為我本身是屬於兩者都能處理的人員。
所以一般都會透過我來決定誰要做改變。(雖然有時boss一句話就可以翻盤了)

q00153 iT邦新手 3 級 ‧ 2019-02-18 18:21:54 檢舉

Hi~感謝您上面的回覆,
我承認的確是較不擅長資料庫的部份,
技能沒有點很高,
畢竟業務主要也不是面向資料庫,
不過很感謝您的提醒,
讓我注意到了這方面的缺乏,
雖然並不會去跟公司的 DBA 請教,
但是我會去吧以前買的資料庫相關書籍,
重新拿出來研讀,如果不足就購買新書,
或是找相關學習資源,
我的個性不怕別人批評,
更怕自己不夠,
因此非常感謝您給的建議。

以下,
如果認為我說的話不好聽,您可以忽略不要看。

上面那個的確是很糟糕的例子,
我寫完之後也認為不是很能夠反映出面臨的問題,
畢竟實際業務狀況複雜的多,
對於一個專案,
很多業務也要考量進去。

另外說說我的想法,
一般正規化做到第三層就差不多,
太多只會造成系統多餘的開銷,
相對於節省的硬碟空間,
或是日後的維護成本,
甚至為了業務考量,
有的做一,二層正規化就可以了,
有點像買東西的 CP 值,
總是在品質與荷包之間做平衡的,
過度正規化這件事是肯定存在的,
不然怎麼會有反正規化這件事呢。

你的思考點,我並不會否認。我只是希望盡量不要站在自已的思考面上想。其一很容易破壞團隊。其二不容易看到問題所在。

由於最大的重點在於溝通上。就如上面說的。如dba真的很死腦筋。
那你可以轉成view表的方式來應付你的效能問題。

將view表直接交給dba去幫你處理。如果他們真的硬要你分那麼細的話。
因為大多數來說,還是需要依公司需求利益為主要。
他們太過死腦筋的話。就轉換另外一種做法處理。

不過說真的,join 6個表真的不是效能影響的因素。這是需要了解其架構跟節構。就我這邊而言。join 6~7的表都是很正常的。而且分表子資料來說。可以更有效的應用才對。

q00153 iT邦新手 3 級 ‧ 2019-02-19 12:41:14 檢舉

喔~可能是因為兩個原因,我這邊的系統並不常用到 6 個表的 join
通常超過 3 個表就會覺得很多了 @@

一個是因為資料量大,
比如產線的生產資料,一個小時幾十萬筆都是一般的,很多都是生產過程中的檢測數據等等,是屬於大量寫入的業務情形,因此搜尋的部分通常是以資料的統計與分析等為主,因此會覺得每次搜尋時都要從底層資料重新統計與計算數據很耗時

另一個原因是伺服器比較老舊....
或者算不上是伺服器=口=? 效能比較接近於工作站的電腦,這部分是歷史問題,估計是當初採購的時候資金或評估的不足,反正現在也不敢動

所以養成了要盡量壓榨出系統效能的習慣,加上 DB 部分不是本質職能,在以前的系統規劃上就使用了並不是正規的方法去設計 (請原諒我的表達能力...

我要發表回答

立即登入回答