iT邦幫忙

2023 iThome 鐵人賽

DAY 9
0

Food Delivery Platform: refactor ETL & Schema

今天來refactor DB schema以及ETL有關這兩個的review可以看昨天的文章[Day 8] Food Delivery Platform Code review (二)

DB schema refactor

昨天有提到Schema的設計上缺少了foreign key還有正規化與命名一致的問題,在不修改大架構的情況下refactor的方向為:

  • 名稱規範:、使用一致的snake_case命名規範。
  • 正規化:移除PurchaseHistory中的restaurant_id,因為可以透過menu_id獲得。
  • 外鍵設定:在有參照的地方,確定設定了foreign key。
Table restaurant {
  id SERIAL [pk, increment]
  name TEXT [not null]
  cash_balance NUMERIC [not null]
}

Table menu {
  id SERIAL [pk, increment]
  dish_name TEXT [not null]
  price NUMERIC [not null]

  restaurant_id INT [ref: > restaurant.id, not null]
}

Table open_hours {
  id SERIAL [pk, increment]
  week TEXT [not null]
  open TIME [not null]
  close TIME [not null]
  restaurant_id INT [ref: > restaurant.id, not null]
}

Table users {
  id INT [pk]
  name TEXT [not null]
  cash_balance NUMERIC [not null]
}

Table purchase_history {
  id SERIAL [pk, increment]
  menu_id INT [ref: > menu.id, not null]
  transaction_amount NUMERIC [not null]
  transaction_date TIMESTAMP [not null]
  user_id INT [ref: > users.id, not null]
}

https://ithelp.ithome.com.tw/upload/images/20230923/2014035881snf0hFii.png
原本的Schema圖
https://ithelp.ithome.com.tw/upload/images/20230923/20140358mtGAekQecc.png

ETL refactor

ETL 優化的重點為

  • 減少重複的數據庫連接:每次執行寫入操作時都需要開啟和關閉數據庫連接,會減慢效率。使用連接池或至少儘量重用連接來提高效能。
  • 整理解析營業時間的邏輯:init_db_restaurant函數有大量重複的邏輯和嵌套,增加了代碼的複雜性和潛在的錯誤。
  • 使用try-except語句來捕捉和處理數據庫相關的異常:確保在出現問題時可以rollback。
  • 減少全域變數的使用:例如weekend和weekend_list。
# ... [其他不變的部分]

def til_days(first_day, end_day, open_time_open, open_time_close, restaurant_id):
    insert_data = []
    # 這部分邏輯保持不變
    # ...
    return insert_data

def init_db_restaurant(conn, log):
    with open("../data/restaurant_with_menu.json", 'r') as load_f:
        load_dict = json.load(load_f)

    cur = conn.cursor()
    for restaurant in load_dict:
        # ... [其他不變的部分]
        
        # insert openhours table
        open_days = restaurant.get('openingHours').split('/')
        statement = 'INSERT INTO openhours (week, open, close, restaurant_id) VALUES (%s, %s, %s, %s)'
        insert_data = []

        for day in open_days:
            # 使用函數重構的部分邏輯來獲取insert_data
            day_data = parse_day(day, restaurant_id)
            insert_data.extend(day_data)
            
        cur.executemany(statement, insert_data)
    
    conn.commit()
    cur.close()

# ... [其他不變的部分]

def init_db_users(conn, log):
    with open("../data/users_with_purchase_history.json", 'r') as load_f:
        load_dict = json.load(load_f)

    cur = conn.cursor()
    for user in load_dict:
        # ... [其他不變的部分]
        
        cur.executemany(statement, insert_data)

    conn.commit()
    cur.close()

# ... [其他不變的部分]


上一篇
[Day 8] Food Delivery Platform Code review (二)
下一篇
[Day 10] Food Delivery Platform: API review
系列文
從實戰中學習:Take Home Assignment review & refactor30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言