Re: [討論] SQL的指令優缺點

作者: sing10407 (阿U)   2016-10-15 19:43:46
※ 引述《ripple0129 (perry tsai)》之銘言:
: 在看過一些複雜的SQL指令後,
: 覺得這是個難以維護的東西。
難以維護這個詞太籠統了,
你的難以維護是很多 join ? (其實對熟 sql 的來說這還非常簡單)
或是很多巢狀迴圈 ? (這也可以用 view 解決)
: 優點自然也是有的,
: 可以少寫不少程式碼。
: 而複雜的SQL指令不外乎Join了好幾個Table,
: Where了好幾種條件。
這樣聽起來很單純很好維護。
: 想請教各位大大對於SQL的應用上,
: 單純做CRUD然後給與對應的entity物件,
: 需要Join時就是Select Table出來,
: 之後再自行用程式碼拼裝。
痾... 你太輕忽 Database indexing 的能力了,
你自己拼裝,多了資料庫 io ,速度也不會比 indexed 後的資料用 sql 撈出來快。
indexing 早就在資訊界做了 N 年的研究,產生了 N 篇演算法的論文,
啥 B-Tree, B+ Tree 等等
: 還是下達花式SQL指令降低程式碼量好?
: 然後哪一種對資料庫有較輕的負擔?
當然是組 SQL 摟,
當你單一 Table 超過十幾萬筆、百萬筆,每次執行單一個 query
就將資料載入到 application 做運算,最後只拿幾十筆來用,你覺得這樣會快嗎?
: 反正規化的查詢速度優勢,
: 犧牲了正規後儲存空間以及降低了資料一致性,
儲存空間很便宜;
一致性要看該 case 重不重要。
最重要會做反正規化不外乎為了:
1. 增加速度
2. 降低資料庫使用的資源
: 且對於程式碼來說也降低維護性,
工程師都有程式或資料的潔癖,
有時候這些「降低維護性」的事可以避免你繞一大圈
增加一點維護性不算什麼
: 在現今環境來說值得嗎?
: 我個人的看法是維護性最高優先權,
一向都是看 case 為何。
像是你只是寫個簡單一兩萬內的小 case,
幫理髮店紀錄所有來過的客人的基本資料、消費紀錄
你是要用最原生的語言(像 php)直接快速寫完,
還是你還要抽介面、資料庫反正規化、用 MVC Framework ?
: 在維護性低的情形下,
: 後面加入的程式碼品質可能每況愈下。
: 程式碼品質不斷降低會造成資料庫的損耗加重。
兩者沒有直接關係
: 最後可能得不償失。
: 想了解我這樣的觀念是錯誤的嗎?
一點小經驗:
資料庫資源有限(license還很貴),不像 application 層可以橫向輕易地擴展,
資料庫是很難做多台機器 load balancing 的,
就算有的話後面還是共用同一顆硬碟。
又或者是只能用 replication 做讀寫分離這種程度而已。
因此的確需要對於資料庫資源使用有更多的考量
相反的 application 層大多可以輕易地橫向複製,
有些運算也真的可以不必在資料庫全部完成
然後資料庫的世界很廣,多去了解一下各種 index 適用於什麼樣的資料,如何精準地對
table 下 index;
資料正規化要如何設計,什麼是 entity、什麼是 relation 要先搞清楚
設計出來的 table schema 才會有彈性
另外整個架構還可以將一些全文檢索改用 elastic search,
一些常用的資料放在 redis cache,都是常見的做法
舉個實例:
以前我也遇過一張報表,是一張學期成績單,
除了要先找出該位學生,還要找出他這學期哪幾門課、教授是誰、學分數、分數、
有沒有 pass、有沒有抵免、有沒有教育學程、班排名、系排名、有沒有被 21
一個 sql 組出來大概超過百行吧(含一大堆子查詢)
但是程式可以怎麼設計呢?
每個學生修的課程、教授、學分數、分數、學期
先反正規化成一個 table(或view、indexed view)
一些單純設定檔的table放到redis cache,像是21規則、status code對應的文字等等
要用時再 application 層去組即可
然後每個學生的班排名、系排名也都反正規化到另外一張 table
最後只要簡單的 sql 就能查到要的資料,我的設計邏輯再留個文件
維護也簡單,只要確定底層的資料沒錯,在最上層只需要注重邏輯對不對就好
但是如果你要資料庫完全走正規化的路,
每次都是即時查詢,資料庫資源吃很重,且很耗時喔
一點心得分享
作者: eva19452002 (^^)   2016-10-15 19:58:00
以前在學校讀書,都要求完全走正規化的路,我不知道這樣會因此讓loading變重
作者: pttworld (批踢踢世界)   2016-10-15 20:07:00
最初的問題在java web就像是batis和hibernate
作者: ripple0129 (perry tsai)   2016-10-15 20:42:00
當然不是整個table select回來拼裝,而是每個table各自下要where的東西回來拼裝,這樣的話對DB的負擔跟join比較的話哪個比較重呢?
作者: issue666 (issue)   2016-10-15 21:14:00
請問太多join可以用什麼方法解決? 謝謝
作者: iFEELing (ing)   2016-10-15 21:22:00
縮小資料集 走索引 進CACHE 降低IO 降低CPU資料面來看的話就是反正規化 增加重覆資料降低串接
作者: pttworld (批踢踢世界)   2016-10-15 23:04:00
實務上開發方蠻難動到DB的,接案全包除外。
作者: bobju (枯藤老樹昏鴉)   2016-10-15 23:43:00
大公司不會輕易給外包商動DB, 更別提寫SP跟view了有的是合約問題, 大公司之前的開發商有維護合約在, 後面接手的包商不能動這塊.
作者: neo5277 (I am an agent of chaos)   2016-10-16 00:58:00
有彈性的正規化感覺只能靠經驗了給推
作者: y3k (激流を制するは静水)   2016-10-16 01:34:00
我覺得SQL要怎麼寫有很大部分是需求問題 被逼的時候就算你不想也得搞一堆複雜的判斷....
作者: jerry771210 (說在多也沒用)   2016-10-16 07:17:00
推,原原po資料庫沒學好吧?當然把邏輯用sql做掉啊,用程式去篩是哪招……有join很正常,自己不懂不等於複雜、維護性低,是自己能力不到,結案。
作者: ripple0129 (perry tsai)   2016-10-16 09:00:00
什麼都要trace到SQL不覺得維護性低嗎?ORM framework根本沒用,會寫code的我覺得要了解SQL語法的不難吧,但真的會想包一層讓它OO些
作者: jerry771210 (說在多也沒用)   2016-10-16 09:30:00
sql維護性低??.......
作者: ripple0129 (perry tsai)   2016-10-16 09:47:00
老實說我個人完全不認同邏輯用SQL做掉,這個出bug直接進data,邏輯能往前送就往前送才能做到多重檢查。除非必要根本不把邏輯做在SQL。
作者: iFEELing (ing)   2016-10-16 13:37:00
ORM 範圍小的時候用起來很爽 範圍大了怎麼死都不曉得包一層起來有的人就連底下怎麼跑的都不曉得了...
作者: xdraculax (首席怪叔叔)   2016-10-16 14:34:00
當你說花式SQL是減少程式碼,就讓人感覺你SQL不太熟...
作者: ripple0129 (perry tsai)   2016-10-16 15:33:00
的確是減少程式碼,少了在程式碼端拼裝的過程
作者: anr2 (???)   2016-10-16 17:42:00
這是一個lambda的概念
作者: onear (萬一)   2016-10-16 20:55:00
讓資料歸資料,OO歸OO吧..
作者: ChungLi5566 (中壢56哥)   2016-10-16 22:39:00
看完回答後 真的建議去修資料庫系統的課程
作者: viper9709 (阿達)   2016-10-18 00:03:00
推這篇~
作者: odbc (odbc)   2016-10-18 17:47:00
這篇正解啊...
作者: tloy1966 (JJspeaking)   2016-10-25 10:30:00
學到了

Links booklink

Contact Us: admin [ a t ] ucptt.com