尤 川豪   ·  3月前
Exp. 1,209  ·  152 貼文  ·  114 留言

彈性資料庫架構:存 JSON format 與 EAV model 的優劣比較

直接用 text 存 json 很糟糕(MySQL 5.7 之前)

個人開發經驗,有幾點很糟糕:

  • 以 text 格式存,無法在 database level 做任何格式檢查,很不踏實,也許根本存到 invalid JSON format data
  • 很難 query,基本的 sql WHERE 都無法寫,只能用 text search 之類的硬 query

使用 EAV model 很糟糕

個人開發經驗,有幾點很糟糕:

  • 資料四散,很煩,屬於同一個 entity 的 attribute 會以多個 row 的形式散在 table 內,出現在一起比較好
  • 需要不斷使用 JOIN,寫起來很煩,效能也有問題吧?
$reviews = \Modules\HavaCore\Entities\ReviewCell::findMany(DB::table('review_cells')
    ->select('review_cells.id')
    ->join('entities', 'review_cells.entity_id', '=', 'entities.id')
    ->groupBy('review_cells.entity_id')
    ->groupBy('review_cells.user_id')
    ->where('entities.topic_id', HavaCore::getTopic()->id)
    ->get()->pluck('id')->all())->sortByDesc('created_at');

MySQL 5.7+ 之後終於原生支援 JSON 了,很有幫助

MySQL 5.7+ 之後終於可以支援 JSON,使用 -> operator 就可以下 query 了

在 laravel 的話就是

查詢

$users = DB::table('users')
                ->where('options->language', 'en')
                ->get();

$users = DB::table('users')
    ->where('preferences->dining->meal', 'salad')
    ->get();

甚至是

$users = DB::table('users')
    ->whereJsonContains('options->languages', ['en', 'de'])
    ->get();

更新

DB::table('users')
    ->where('id', 1)
    ->update(['options->enabled' => true]);

效能比較與分析

請看另一篇

https://devs.tw/post/53

  分享   共 286 次點閱
共有 2 則留言
Connor Hsu   ·  2月前
Exp. 62  ·  0 貼文  ·  7 留言

雖然這篇講的是用什麼存 json,我個人還是很排斥存 json,即使 mysql5.7 之後支援 json format 不需要 parse text,還是會把它當作 workaround,用了之後也會把它技術債看待。

原因很簡單:彈性跟穩定性通常都是互斥的,有本老書叫 data modeling essentials 也講到要考慮這個原則(事後才去估狗到的)

某個欄位可以隨意增加 json 裡面的 key,因此開發很快,那就表示其他人要承擔資料不確定性的風險

有些情況下我們會犧牲穩定性,比如內部實驗演算法模型,越快越好,可能最後也不會上線;有些情況下我們會犧牲彈性,因為這個資料庫的服務重要到完全不能出差錯。

像這種 trade-off 通常都會默默地被選了彈性的那一邊,因為老闆想要快,有些工程師也會誤以為自己開發很快,事實上是拿其他team 跟之後維護人員的時間換來的;如果選了彈性的那一邊,那應該要意識到做了這個選擇,在需要產線化之前安排重構、或是用其他方式(文件、註解、額外的檢查等等)來管理這個彈性的 schema,否則就會出現「跟地下錢莊借錢卻還沾沾自喜以為不用還」的情形

(待續)

 
尤 川豪   ·  2月前
Exp. 1,209  ·  152 貼文  ·  114 留言

用 RDBMS 的確應該盡量避免這樣存 幾乎在任何情況下都要避免這樣存

我是因為在使用 PHP/Laravel/MySQL 開發類似 CMS 的系統

無法得知使用者/開發者會需要什麼欄位 所以 schema 定不出來

所以才研究這個主題

 
您的留言
尤 川豪
Exp. 1,209  ·  152 貼文  ·  114 留言

關於作者

Devs.tw 作者,喜歡分享&建造新東西的工程師。

技術部落格:轉個彎日誌

歡迎在 Facebook 追蹤我!

不定期分享有趣技術文章!