【MongoDB 最佳實踐規範】❶ Data Modeling 篇: 資料的儲存該如何設計

  1. MongoDB 和一般關聯式資料庫 (RDBMS) 的差異
  2. MongoDB Best Practices 最佳實踐規範
  3. Data Modeling
    1. 1. 會一起被使用的數據就放在一起
    2. 2. 避免儲存較大的陣列
    3. 3. 某些情況下,建議將數據放在不同文件
    4. 4. 跨文件存放相同的數據可以提高效能
  4. 參考資料

MongoDB 和一般關聯式資料庫 (RDBMS) 的差異

MongoDB 屬於一種非關聯式資料庫,與關聯式資料庫的差異其實網路上已經有非常多的資料,個人覺得主要是 Schema 的彈性不同:MongoDB 可以不用事先定義資料欄位和型態,但像是 MySQL 就得先 Create Table 並定義固定的 schema,若後續有想要更改或是新增欄位就會比較麻煩。

所以如果你的資料隨時間變動的可能性較大、具有較高不確定性的話,MongoDB 就會是很好的選擇!

關於差異也可以參考 AWS 所做的表格

MongoDBMySQL
資料模型將資料儲存在 JSON 文件中
然後將其組織到集合中
將資料儲存在資料欄和資料列中
資料儲存採用表格式和關聯式方式
可擴展性使用複寫和碎片化來水平擴展使用垂直擴展和僅供讀取複本來大規模提升效能
查詢語言使用 MongoDB 查詢語言使用 SQL
效能擅長 INSERT 或 UPDATE 大量記錄SELECT 大量記錄時,MySQL 的速度更快
靈活性沒有結構描述,這點提供更多靈活性
使其能處理非結構化、半結構化和結構化資料
具有剛性結構描述,能有效處理結構化資料
安全性使用 Kerberos、X.509 和 LDAP 憑證來驗證使用者使用內建身分驗證方法
MongoDB vs. MySQL

MongoDB Best Practices 最佳實踐規範

基於以上所述的一些差異,在使用 MongoDB 時的操作就會有很多要注意的地方,這次藉由官方最新發布的 MongoDB Best Practices Guide 來整理一些建議的 Tips。

預計會分成四個主題,包含

  1. Data Modeling
  2. Working With Data
  3. Optimizing Data Access Patterns
  4. Availability and Scaling

Data Modeling

數據建模要考慮的,就是最後將會如何使用這些數據、如何訪問這些數據,來決定怎麼設計資料儲存的形式。

1. 會一起被使用的數據就放在一起

把可能會一起使用的數據放在同一個 document 中,可以大幅提升查詢效能,因為等於直接省去了很多類似關聯式資料庫的 Join。

如下方的 document,user 的 alerts 是直接寫在每個 user 的資料底下,而不是像 MySQL 那樣另外寫一張叫做 alerts 的資料表,這樣在查詢的時候只要查詢 users 這個 collection 就可以直接取得各自的 alerts,完全不需要再另外 Join。

像這樣的 embedded data (subdocuments) 在 MongoDB 是比較建議的做法,因為也可以讓 UPDATE 資料能在單一一個操作中完成。

// db.users
{
     _id: "abc",
     email: "xyz@example.com",
     preferences: {
     alerts:[
         { name: "morning", frequency: "daily", time: { h: 6, m: 0 } }
     ],
     colors: { bg: "#cccccc" }
     }
}

2. 避免儲存較大的陣列

由於 MongoDB 每個 document 的最大儲存上限是 16 MB,所以像是餐廳商店的評論,資料的則數和字數都是未知的,用陣列儲存在同一個餐廳商店資料階層底下,有可能就會占用很大的儲存空間。

因此這類的數據就建議每個評論分成不同的 document,並帶有餐廳商店的 ID 做參照 (如下方範例)

// businesses
{
     _id: "100",
     name: "Bake and Go",
     addresses: [
         { street: "40 Elm", state: "NY" },
         { street: "101 Main St", state: "VT" }
     ]
}

 // businessReviews
{
     _id: "61e706e2450fac1271c9b27a",
     storeId: "100",
     rating: 5,
     comment: "Best bagels in town, a must try if you are in the area."
}
{
     _id: "61e706e2450fac1271c9c522",
     storeId: "100",
     rating: 5,
     comment: "Yummy desserts and a nice place to sit and eat."
}

3. 某些情況下,建議將數據放在不同文件

其實並非所有的 1:1 或 1:many 關聯都可以直接無腦放在同一個文件中,如果有以下狀況的話,就建議將數據放在不同的文件:

  • 在很常需要讀取的文件中,包含了部分幾乎不會用到的數據
  • 文件中部份數據會隨時間更新和成長,但另外一部分卻相對固定不變
  • 文件大小可能會超過 16 MB 上限 (如同前述的第2點)

下方以一個汽車製造商的資料庫為例,汽車車款 (models) 是陣列的形式,但由於車款的資料通常都是個別顯示 (比較不會有同時需要取用多個車款的情況),所以這樣儲存陣列的話,查詢數據後就會需要進行額外的資料處理。

這是錯誤示範:

// manufacturers
{
     _id: "200",
     name: "Swaab Automotive",
     type: "auto",
     models: [
         { name: "Swaab Model X", year: 2022, sku: "SWA-X-22Z"},
         { name: "Swaab Model Y", year: 2022, sku: "SWA-Y-22Z"},
         //...
     ]
}

因此這種情況下,就比較建議將汽車 models 另外獨立成一個 collection,並且帶有製造商 ID 做參照。

而且通常 models 資料的使用也會較獨立,也可能更新比較頻繁,所以把它們拉出來做為另一個 collection 會比較方便讀取和寫入。

正確示範如下:

// models
{
     _id: "1201",
     name: "Swaab Model X",
     year: 2022,
     sku: "SWA-X-22Z",
     manufacturer_id: "200"
}
{
     _id: "1202",
     name: "Swaab Model Y",
     year: 2022,
     sku: "SWA-Y-22Z",
     manufacturer_id: "200"
}

4. 跨文件存放相同的數據可以提高效能

為了提高效能,就要避免額外的資料 JOIN 操作,所以建議可以在不同的文件中存放相同的數據。

如下方範例,在 users, posts 兩個 collections 中都存放相同的使用者 Email 數據:

// users
{
     _id: "1",
     name: { first: "Jane", last: "Doe" }
     email: "jdoe@example.com"
}

// posts
{
     _id: "1055",
     title: "My First Post",
     text: "Hello World",
     userId: "1",
     userEmail: "jdoe@example.com"
}

雖然資料看起來會比較複雜,但 MongoDB 提供了 change streamstriggers,來確保跨文件的重複存放數據都能保持同步更新和一致性。

參考資料

比較不同的設定檔:ini, YAML 和 TOML(附 Python 讀取設定檔的程式碼)

  1. 前言
  2. 比較
    1. ini
    2. YAML
    3. TOML
  3. 程式碼
    1. Read .ini file
    2. Read .yaml file
    3. Read .toml file
  4. 總比較表
  5. 總結
  6. 參考資料

前言

在寫專案的時候,常會需要一些帳號密碼或是資料庫連線的資訊,而這些資訊通常不建議直接寫在程式碼中,而是放在獨立的檔案中,這種檔案就叫做設定檔 (Configuration Files)。

但設定檔有很多種,像是 .json, .cfg, .ini, .yaml, .toml,撰寫的方式也有些許不同,用 Python 讀取的方式和套件也不同,所以這次整理了我目前工作上曾遇到的三種較常見的設定檔: ini, yamltoml,比較一下它們的優劣,並附上使用 Python 讀取它們的程式碼範例。

閱讀更多»

最新 Airflow 2.6 版本有哪些更新?簡介 Notifiers, Grid View, Trigger, CLI 等多項更新內容(附程式碼)

Airflow 在最近釋出了最新的 2.6 版本,Astronomer 也在第一時間舉辦了一個講座,這篇文章記錄我在講座中看到的各種 Airflow 新功能和新修正,講座影片我放在本文最後面的參考資料,若有興趣的話也可以看看!

這次 Airflow 2.6 版本的更新包含了:

  • 35+ 個新功能
  • 50+ 個功能改進
  • 27 個 Bug 修正

以下是本篇文章的大綱:

  1. Notifiers:更方便的 Pipeline 示警功能
    1. 內建 Slack notifier
  2. Continuous Timetable:可以讓 Sensor 持續運作的功能
    1. Continuous 使用範例
  3. 可用 CLI 來測試 Connections 和查看 DAG 詳細資訊
  4. 新增部分 Async 非同步設定,釋放你的 Airflow 壓力
  5. 修正 Task 卡在 Queue 狀態的問題
  6. UI 介面的更新
    1. Grid View 更新:與 Graph View 有了更佳的整合
    2. 更新 Trigger DAG with Parameters 功能:可直接帶入歷史參數設定
  7. Pandas Serializer for XCOM:讓 Task 可以直接回傳 Pandas DataFrame
  8. 其他更新
  9. 總結
  10. 參考資料

Notifiers:更方便的 Pipeline 示警功能

這次多了內建的 Notifier 可以用
主要是搭配 DAG/Task 的 on_success_callback 或是 on_failure_callback 來使用

我覺得把通知直接整合進 Airflow 是一個很重要的功能
因為如果 Pipeline 壞掉卻沒有收到通知,那個後果真的非常可怕
尤其是常常 Pipeline 之間會有相依性
一個壞掉若沒有提早修復,就會造成很恐怖的連鎖反應
(例如:Data Engineer 修到瘋掉)

內建 Slack notifier

目前只有 Slack 是可以直接內建使用的,後續版本應該是還會再新增
設定的程式碼可以參考以下:

https://github.com/astronomer/2-6-example-dags/blob/main/dags/notifier_slack.py

如果想要用其他的通知,就需要另外自定義
自定義的方式也可以參考他們寫的程式碼: 2-6-example-dags/dags/notifier_file_toy.py


閱讀更多»

推薦 6 個可以幫你提升工作效率的 VS Code 擴充套件(附使用教學)

  1. 前言
  2. Tabnine: 宛如讀心術般的程式碼自動補齊工具
    1. 功能
    2. 個人點評
    3. 使用方法
  3. Material Icon Theme: 美化檔案圖示、清楚顯示不同檔案類型
    1. 功能
    2. 個人點評
    3. 使用方法
  4. Rainbow CSV: 以顏色區分結構化資料的不同欄位,方便快速探索資料
    1. 功能
    2. 個人點評
    3. 使用方法
    4. 小建議
  5. GitLens: 顯示程式碼 Git 紀錄,提升程式碼協作效率
    1. 功能
    2. 個人點評
    3. 使用方法
  6. file-tree-generator: 一鍵產出資料夾結構,方便撰寫技術文件
    1. 功能
    2. 個人點評
    3. 使用方法
  7. autoDocstring: 一鍵產出註解結構,讓同事更快看懂你的 code
    1. 功能
    2. 個人點評
    3. 使用方法
    4. 小建議
  8. 總結

前言

過去曾試過不同的幾個 IDE 來寫程式,而在用過 Visual Studio Code (簡稱 VS Code) 之後就定居下來了,因為 VS Code 不僅介面乾淨直覺,還有很多好用的擴充套件可以安裝!

因此在這篇文章中,我想來分享一下在我做為資料工程師的這幾年,我覺得在工作實務上有幫助我提升效率的 6 個 VS Code 擴充套件,希望這些套件也能幫助到來看這篇文章的你們!


Tabnine: 宛如讀心術般的程式碼自動補齊工具

功能

  • 可以即時提供程式碼建議,並且讓我們可以一鍵自動補齊

個人點評

  • 會偵測當下文件,推薦合理的程式碼
  • 按下 Tab 即可完成一整段程式碼
  • 免費版就已經很好用,而且比另一款 Kite 更省記憶體
  • 有時候真的覺得他會讀心術,完全知道我想要打什麼

使用方法

安裝後就會直接在我們輸入程式碼的時候開始提供建議,就像下圖紫色方框中,游標後方灰色的字就是 Tabnine 根據當下文件的程式碼所推薦出來的,如果他是你要的程式碼,那就可以放心按下 Tab 鍵,這一行程式碼就瞬間完成囉!

Tabnine 提供程式碼建議

連結:https://www.tabnine.com/


Material Icon Theme: 美化檔案圖示、清楚顯示不同檔案類型

功能

  • 美化 VS Code 側欄的檔案圖示

個人點評

  • 👍 不同檔案類型的差異會非常明顯
  • 👍 讓我們可以快速找到想要的資料夾 or 檔案

使用方法

安裝後就會馬上替換現有的 icon 圖示,如下圖

如果想要停掉的話,可以點擊 VS Code 左下角的齒輪 (或偏好設定 Preferences) -> 主題 (Themes) -> File Icon Theme 去做切換唷!

Material Icon Theme 安裝後,檔案圖示變得漂亮又清楚

連結:https://marketplace.visualstudio.com/items?itemName=PKief.material-icon-theme


Rainbow CSV: 以顏色區分結構化資料的不同欄位,方便快速探索資料

功能

  • 將結構化資料的不同欄位上色、排列

個人點評

  • 👍 非常適合資料工作者,因為幾乎每天都會碰到 CSV 檔
  • 👍 直接在 VS Code 裡面就可以快速探索資料

使用方法

安裝後打開任何 csv (or tsv) 檔,就會看到不同欄位已經有不同顏色,如果想要排列如下圖,要按一下底部 bar 上面的 Align,也可以利用點擊 Query,會顯示表格化的資料,並且下方可以進行 SQL 的查詢(功能按鈕如紫色背景的下下圖)。

小建議

排列後檔案會多出空格,建議關掉時選擇 不要儲存,不然有時候儲存後再用 Pandas 讀取會有不必要的空格字元在資料裡面。

同一份 CSV 檔,安裝 Rainbow CSV 的前後對照
Rainbow CSV 功能按鈕

連結:https://marketplace.visualstudio.com/items?itemName=mechatroner.rainbow-csv


GitLens: 顯示程式碼 Git 紀錄,提升程式碼協作效率

功能

  • 搭配 code 顯示 Git 紀錄,包含作者和上傳時間

個人點評

  • 👍 看同事 code 遇到問題時,可以直接去問當事人比較快
  • 👍 根本就是超好用的 抓戰犯 團隊合作 神器!

使用方法

安裝後就會看到原本程式碼的後方會顯示該行程式碼的作者和 commit 時間,游標移到那排灰字上方,還會顯示更詳細的紀錄

在 VS Code 側欄也會多一個 GitLens 的圖示,點進去可以看到所有的 commits,展開後可以看到該 commit 的詳細內容,並且也有很好分辨的圖示,像是綠色是 Added,藍色是 Modified,橘色是 Renamed,紅色是 deleted,非常清楚。

GitLens 功能展示

連結:https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens


file-tree-generator: 一鍵產出資料夾結構,方便撰寫技術文件

功能

  • 一鍵產出整個專案資料夾的結構

個人點評

  • 👍 非常適合用於寫技術文件,像 README.md 之類的
  • 👍 雖然產出沒有到很漂亮,但已經很完整又方便

使用方法

安裝後打開想要製作 file tree 的專案資料夾,在左側欄空白處點擊右鍵(如下圖 util.py 附近空白處),選擇最底下的選項 Generate to tree 之後就會在右側開啟一個新頁面,上面就會有這個專案的整個資料夾架構囉!之後就可以複製到想要的文件上貼上即可!

file-tree-generator 使用教學

連結:https://marketplace.visualstudio.com/items?itemName=Shinotatwu-DS.file-tree-generator


autoDocstring: 一鍵產出註解結構,讓同事更快看懂你的 code

功能

  • 一鍵產出 Python function 註解結構

個人點評

  • 👍 說到文件,一定不能忘記重要的註解!
  • 👍 有了結構,我們可以更專注於撰寫註解內容

使用方法

安裝後就可以在 Python function 的下方輸入三個引號(預設是雙引號來觸發,也可以調整為單引號),按下 enter 或 tab 選擇出現的第一個選項 Generate Docstring,就會產出完整又精美的註解結構啦!

如果 function 上有定義好 input/output 的資料型態 data type,autoDocstring 也會非常聰明地自動幫我們放到註解裡面,真的是寫註解的救星~

小建議

如果輸入三個引號沒有出現 Generate Docstring 的選項,也可以使用快捷鍵 Command + Shift + 2 來快速建立註解唷!

autoDocstring 使用教學

連結:https://marketplace.visualstudio.com/items?itemName=njpwerner.autodocstring


總結

以上就是 6 個我實務上使用覺得有幫助到我的 VS Code 擴充套件啦!

我覺得非常推薦資料科學工作者可以使用 VS Code,除了擴充套件之外,他也有原生的 Jupyter notebook 方便我們做資料探勘或是機器學習 ML!

而且因為是 Open Source 的關係,可用的擴充套件也持續在推陳出新,如果是非常多人在使用的套件,甚至有機會直接變成內建的功能,像是之前超實用的凸顯括弧配對的工具 Bracket Pair Colorizer 就是一個活生生的例子。

如果這篇文章有幫助到你的話,歡迎幫文章按個讚 👍

你也有用過哪些好用的 VS Code 擴充套件嗎?歡迎留言分享~🤗


歡迎追蹤我的 IG 和 Facebook

玩膩了鐵達尼號資料集?來看看最新的太空船版本鐵達尼號吧!

另類的鐵達尼號資料集

最近在研究 Data Quality 相關的工具,需要一個簡單的資料集來測試,剛好在 Kaggle 上看到一個練習資料集,是太空船版本的鐵達尼號,如果有在玩 Kaggle 或學習機器學習的話一定有聽過或用過鐵達尼號這個資料集,但如果你已經玩膩了原版的鐵達尼號,可以來玩玩看這個太空船版鐵達尼號唷!

資料集背景故事

這個資料集背景是設定在未來的西元 2912 年,有一艘太空船載著近 13,000 名乘客,裡面有來自不同星球的人類,正在前往其他星球居住的路上,但途中因為不明的時空異常狀況,導致有幾乎一半的乘客被傳送到平行時空,而我們的目標就是要 預測哪些人可能會被傳送

資料集內容 (Data Details)

  • PassengerId
    • 每個乘客的唯一 ID,每個 ID 都採用以下形式 gggg_pp,其中 gggg 指乘客正在旅行的group,並且 pp 是他們在 group 中的編號。
    • 一個團體中的人通常是家庭成員,但不一定。
  • HomePlanet
    • 乘客離開的星球,通常代表他們原本家鄉的星球。
  • CryoSleep
    • 表明乘客是否選擇在航行期間處於假死狀態。
    • 冷凍睡眠中的乘客被限制在他們的船艙內。
  • Cabin
    • 旅客下榻的艙位號,格式是 deck/num/side
    • side 可以是左舷 P,也可以是右舷 S
  • Destination
    • 乘客將登陸的星球。
  • Age
    • 乘客的年齡。
  • VIP
    • 旅客是否在航程中支付了 VIP 服務費用。
  • RoomService, FoodCourt, ShoppingMall, Spa, VRDeck
    • 乘客在各項豪華設施中所支付的費用。
  • Name
    • 乘客的姓名。
  • Transported
    • 乘客是否被傳送到平行時空。
    • 這欄位是 Label,也就是要預測的目標。

最後我們要提交的格式跟原版的鐵達尼號差不多,就是 乘客 ID 是否被傳送 兩個欄位即可

個人覺得這資料集的背景設定還滿有趣的,如果你跟我一樣也看鐵達尼號看到膩的話,可以使用看看這個資料集,之後如果我有完成這個競賽會再放上來分享給大家!

參考資料


歡迎追蹤我的 IG 和 Facebook