※ 引述《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 就能查到要的資料,我的設計邏輯再留個文件
維護也簡單,只要確定底層的資料沒錯,在最上層只需要注重邏輯對不對就好
但是如果你要資料庫完全走正規化的路,
每次都是即時查詢,資料庫資源吃很重,且很耗時喔
一點心得分享