資料重構實際案例

許博淳
數據共筆
Published in
Apr 24, 2022
Refactoring meme

我發現搜尋 Refactor meme會找到超多謎因,如果你多數都能看懂,也代表你掌握了重構的知識之外,還踩過很多坑 XD

在開始之前,跟大家分享一下上面這張謎因,重構完之後蜘蛛人還是蜘蛛人,不能變成神力女超人,功能要完全一樣,但程式碼更好理解。

過去的均一在快速推進中成長,先求有在求好絕對是搶占市佔率一大利器,但隨之而來的就是巨大的技術債,以下簡單說明,帶著大家一步步重構。

由於牽涉公司的機密,因此以下程式碼都是用範例。

均一過去產生表格的方法,將每一段 sub-query存成一個 python變數,一層包裹一層,最後傳到 Bigquery執行。

//python
import junyi_tools
bq = junyi_tools.bqfirst_part = """
SELECT
...
FROM
table_name1
WHERE
....
"""%(parameter1)
second_part = """
SELECT
...
FROM
table_name2
WHERE
....
"""%(parameter2)
third_part = """
SELECT
...
FROM
(%s)
LEFT JOIN
(%s)
...
"""%(first_part, second_part)
final_part = """
SELECT
*
FROM
current_table
UNION ALL
SELECT
*
FROM
third_part
"""
bq.query_to_table(final_part)

在重構的過程中有幾個方向

  1. 單一語言:純粹用 SQL來產生表格,因為現在的 Standard SQL已經有許多類似物件導向的功能。
  2. Function化:不論在 Data pipeline或是手動要更新表格,都只需要程式碼相關的 Function,就會執行一樣的流程。
  3. 避免重複寫入:如果表格已經更新到最新,就算重複執行 data pipeline也不應該產生重複資料。
  4. 產生表格或更新最新資料:如果表格不存在,就創建表格;表格已經存在的話就更新未更新的部分

單一語言

原本使用 python變數來儲存 Query,改用 With(Bigquery: 利用 With把巢狀結構function化),有一樣的效果,同時不需要使用 python。

過去會需要用 python是受限於工具只能使用 python,但又需要執行 SQL程式碼,但這個問題隨著均一開始使用 Airflow而消失。

Function化

使用 Stored Procedure的功能去包裝程式碼,需要執行時只要 call procedure即可(Bigquery:利用 Procedure讓程式碼隨時可以呼叫)。

使用 Stored Procedure 還有一個好處,在 Data pipeline相關的工具中可以直接呼叫。

避免重複寫入

  1. 判斷目前資料中最新一筆的 timestamp,只新增該 timestamp以後的資料 (BigQuery:利用 Insert來更新資料表
  2. 同時最後可以對資料做一個 SELECT DISTINCT *來將重複資料完全去除(BigQuery:利用 SELECT DISTINCT來去除重複資料
  3. 往上追資料來源,可能是 GA 或是後端的資料,長期來說會希望後端改善,短期來說可以先建立外部資料與內部資料之間的中間層當做 buffer(文章待補)

產生表格或更新最新資料

  1. 利用 CREATE TABLE IF NOT EXIST,如果表格不存在,就先創造其 Schema(BigQuery:利用 Create or replace table創建表格
  2. 當表格已經存在的情況下,判斷目前資料中最新一筆的 timestamp,只新增該 timestamp以後的資料 (BigQuery:利用 Insert來更新資料表
  3. 如果表格原本不存在,會在步驟1創建表格,那麼 timestamp會是空值,就要設為資料的最早起源時間。

--

--