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

看板Soft_Job作者時間7年前 (2016/10/15 19:43), 7年前編輯推噓11(11026)
留言37則, 16人參與, 最新討論串3/5 (看更多)
※ 引述《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 就能查到要的資料,我的設計邏輯再留個文件 維護也簡單,只要確定底層的資料沒錯,在最上層只需要注重邏輯對不對就好 但是如果你要資料庫完全走正規化的路, 每次都是即時查詢,資料庫資源吃很重,且很耗時喔 一點心得分享 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 118.232.153.216 ※ 文章網址: https://www.ptt.cc/bbs/Soft_Job/M.1476531830.A.BC1.html ※ 編輯: sing10407 (118.232.153.216), 10/15/2016 19:45:16

10/15 19:58, , 1F
以前在學校讀書,都要求完全走正規化的路,我不知道
10/15 19:58, 1F

10/15 19:58, , 2F
這樣會因此讓loading變重
10/15 19:58, 2F

10/15 20:07, , 3F
最初的問題在java web就像是batis和hibernate
10/15 20:07, 3F

10/15 20:42, , 4F
當然不是整個table select回來拼裝,而是每個table各
10/15 20:42, 4F

10/15 20:42, , 5F
自下要where的東西回來拼裝,這樣的話對DB的負擔跟joi
10/15 20:42, 5F

10/15 20:42, , 6F
n比較的話哪個比較重呢?
10/15 20:42, 6F
A(join): 1. Application 只需存取 db 一次 2. indexing 有做好就不太會吃太多資源 B(Application層做join): 1. N 張 table 代表要對 db 做 N 次 io 2. Application 要多寫一次 join 程式,且有淺在的效能問題 3. 好像也沒比較好維護 (後人要搞懂你邏輯,不如重寫下 sql join 快) ※ 編輯: sing10407 (118.232.153.216), 10/15/2016 20:55:31

10/15 21:14, , 7F
請問太多join可以用什麼方法解決? 謝謝
10/15 21:14, 7F
太多 join 不是問題,會慢的話就去檢查 index 有沒有設好; 若有子查詢就建議做成 view 如果 join 多到邏輯複雜、難以 debug, 就可以著手將一些 join 改成 view,這樣就可以做到主 sql 的精簡化,增加可維護性

10/15 21:22, , 8F
縮小資料集 走索引 進CACHE 降低IO 降低CPU
10/15 21:22, 8F

10/15 21:24, , 9F
資料面來看的話就是反正規化 增加重覆資料降低串接
10/15 21:24, 9F
正解 ※ 編輯: sing10407 (118.232.153.216), 10/15/2016 21:33:12 ※ 編輯: sing10407 (118.232.153.216), 10/15/2016 21:35:29

10/15 23:04, , 10F
實務上開發方蠻難動到DB的,接案全包除外。
10/15 23:04, 10F

10/15 23:43, , 11F
大公司不會輕易給外包商動DB, 更別提寫SP跟view了
10/15 23:43, 11F

10/15 23:46, , 12F
有的是合約問題, 大公司之前的開發商有維護合約在, 後面接
10/15 23:46, 12F

10/15 23:46, , 13F
手的包商不能動這塊.
10/15 23:46, 13F

10/16 00:58, , 14F
有彈性的正規化感覺只能靠經驗了
10/16 00:58, 14F

10/16 00:58, , 15F
給推
10/16 00:58, 15F

10/16 01:34, , 16F
我覺得SQL要怎麼寫有很大部分是需求問題 被逼的時候就算你不
10/16 01:34, 16F

10/16 01:34, , 17F
想也得搞一堆複雜的判斷....
10/16 01:34, 17F

10/16 07:17, , 18F
推,原原po資料庫沒學好吧?當然把邏輯用sql做掉啊
10/16 07:17, 18F

10/16 07:17, , 19F
,用程式去篩是哪招……有join很正常,自己不懂不
10/16 07:17, 19F

10/16 07:17, , 20F
等於複雜、維護性低,是自己能力不到,結案。
10/16 07:17, 20F

10/16 09:00, , 21F
什麼都要trace到SQL不覺得維護性低嗎?ORM framework
10/16 09:00, 21F

10/16 09:00, , 22F
根本沒用,會寫code的我覺得要了解SQL語法的不難吧,
10/16 09:00, 22F

10/16 09:00, , 23F
但真的會想包一層讓它OO些
10/16 09:00, 23F

10/16 09:30, , 24F
sql維護性低??.......
10/16 09:30, 24F

10/16 09:47, , 25F
老實說我個人完全不認同邏輯用SQL做掉,這個出bug直
10/16 09:47, 25F

10/16 09:47, , 26F
接進data,邏輯能往前送就往前送才能做到多重檢查。
10/16 09:47, 26F

10/16 09:47, , 27F
除非必要根本不把邏輯做在SQL。
10/16 09:47, 27F

10/16 13:37, , 28F
ORM 範圍小的時候用起來很爽 範圍大了怎麼死都不曉得
10/16 13:37, 28F

10/16 13:40, , 29F
包一層起來有的人就連底下怎麼跑的都不曉得了...
10/16 13:40, 29F

10/16 14:34, , 30F
當你說花式SQL是減少程式碼,就讓人感覺你SQL不太熟...
10/16 14:34, 30F

10/16 15:33, , 31F
的確是減少程式碼,少了在程式碼端拼裝的過程
10/16 15:33, 31F

10/16 17:42, , 32F
這是一個lambda的概念
10/16 17:42, 32F

10/16 20:55, , 33F
讓資料歸資料,OO歸OO吧..
10/16 20:55, 33F

10/16 22:39, , 34F
看完回答後 真的建議去修資料庫系統的課程
10/16 22:39, 34F

10/18 00:03, , 35F
推這篇~
10/18 00:03, 35F

10/18 17:47, , 36F
這篇正解啊...
10/18 17:47, 36F

10/25 10:30, , 37F
學到了
10/25 10:30, 37F
文章代碼(AID): #1O0XPsl1 (Soft_Job)
文章代碼(AID): #1O0XPsl1 (Soft_Job)