第三章 系統架構與功能
第二節 資料表設計
在第二章文獻探討HAWQ 中提到,HAWQ 資料庫是 Append-only,也就是 說,HAWQ 所有的 SQL 指令,都不支援更新(Update)及刪除(Delete),所以這也 會是設計資料表時該注意的問題,像是如何對已新增的資料進行修改或是刪除。
‧ 國
立 政 治 大 學
‧
N a tio na
l C h engchi U ni ve rs it y
二、 資料表基礎概念設計
基金與ETF 記錄下來的資料大部分都是由數值(Float)表示,但名稱跟日期則 是由字串(String)表示,當查詢條件跟名稱有關或者是以名稱做排序等指令,都 會相對慢於同樣篩選條件但選擇的欄位是以數值表示,因此,本研究將名稱轉換 為數值表示,同時額外建立基金與ETF 的名稱對應表,達到數值與名稱轉換的 目的。基金與ETF 的名稱資料表分別如下:
表 三-1 基金名稱資料表
(資料來源:本研究繪製)
表 三-2 ETF 名稱資料表
(資料來源:本研究繪製)
至於日期的部分,一樣也需轉換成數值表示,但轉換前要先說明本研究日期 的設計。此節一開始有提到,資料表存為矩陣的形式最為合適,但若每天都需重 新運算矩陣的話,矩陣的大小會因天數之差而不統一,這樣對開發者應用來說十
‧ 國
立 政 治 大 學
‧
N a tio na
l C h engchi U ni ve rs it y
分困擾,於是本研究把資料表的日期定在一個固定範圍內,將每20 年存成一個 資料表,而對未來的淨利或收盤價等數值則先補0 代替,只要陣列維持固定,後 續一切都好辦。
基金與ETF 抓取到的有效日期都是工作天,即為一個禮拜中的星期一到星 期五,所以每年大概有261 天工作天。因此,如果資料表一次要紀錄 20 年的話,
換算下來2000 年~2020 年共有 5479 天,於是我們就在資料表上以 0~5478 表示,
假如要改為實際日期的話,只要經由程式碼即可快速轉換。
事先填入未來的資料,會遇到什麼問題呢?還記得HAWQ 上不能執行 Update、Delete 的指令嗎?本研究擬出解決辦法,即是在每筆資料裡新增一個欄 位做為索引( index),如果要更新資料的話即直接新增一筆資料,因為新資料的 索引值必定大於舊資料的索引值,於是在篩選的時候只要選擇索引值較大的那 筆,即可達到更新資料的效果。
稍微總結上述幾點,創建出的資料表有索引(達到更新資料的目的)、名稱(用 數值表示,可由名稱資料表查詢對應名稱)、日期(0~5478,共 5479 天)、價格(基 金:淨值,ETF:開盤、收盤…等)。
‧ 國
立 政 治 大 學
‧
N a tio na
l C h engchi U ni ve rs it y
三、 單一數值型資料表
單一數值型資料表視為整個資料庫裡最主要且基礎的資料表,大多的資料存 取均會使用此資料表,而不同於前面提到的資料表基礎概念設計,這邊新增新的 欄位Check,Check 為布林值,當該天的資料遺漏,將用前一天的資料作為遞補,
用意是如果未來預測的工具在做時間序列(Time Series)時能接受空值的話,保有 此欄位將賦予資料表更大的彈性。下表分別為基金歷史淨值資料表與ETF 數值 資料表:
表 三-3 基金歷史淨值資料表
(資料來源:本研究繪製)
表 三-4 ETF 數值資料表
(資料來源:本研究繪製)
‧ 國
立 政 治 大 學
‧
N a tio na
l C h engchi U ni ve rs it y
資料映射 Data Mapping
資料表轉矩陣,將使用到資料映射(Data Mapping)的概念,當資料表被 SQL 指令Select 選取出一維資料,可透過 Reshape 函式重新轉置為二維資料。橫軸即 為天數,縱軸則為基金數或ETF 數,示意圖如下:
圖 三-6 Data Mapping
(資料來源:本研究繪製)
‧ 國
立 政 治 大 學
‧
N a tio na
l C h engchi U ni ve rs it y
四、 陣列型資料表
單一數值型資料表透過映射從一維矩陣轉為二維矩陣,若資料表裡所存的資 料一開始即是一維矩陣,那透過API 取後的資料便是二維矩陣,不需再經過程 式轉換成二維矩陣,因此,整體效能將會再做提升。此資料表即為陣列型資料表,
如下表所示:
表 三-5 陣列型資料表
(資料來源:本研究繪製)
陣列型資料表的設計有好有壞,從優點看起,由於原先日期的部分轉為陣 列,存在於新欄位中,所以資料表總筆數減少,將會降低系統I/O 次數,增快系 統速度。而缺點則是HAWQ 不能更新資料,如果用先前增加索引方式來新增資 料,由於每筆所佔的空間都不小,在每日覆寫下,整個資料表將會佔據很大的空 間,而大半的資料還都已是過時的資料。
因此,本研究將陣列型資料表定位在當單一數據型資料表已紀錄完所有涵蓋 範圍內的天數後,才會另外生成一個陣列型資料表提供給使用者存取。
‧
JupyterHub 是由 Python 撰寫而成的 module,其安裝方法即參照官網上的教 學,分為Python 原生 pip 以及 Anaconda 環境下的 conda 指令兩種下載形式,雖 然conda 下載較為便利迅速,但當 JupyterHub 要提供多人存取的功能,必須在 root 權限下執行,而 Anaconda 本身並無設置在 root 環境變數底下,因此在執行 多人存取時,環境配置會比較繁瑣,所以本研究選擇使用pip 的下載方式。
JupyterHub 採用輸入帳號密碼的登入形式,基於登入安全性,JupyterHub 在 0.7 版後就限制用戶建立平台時,必須透過 SSL 憑證機制,來確保使用者帳密不 會洩漏的風險。 本研究使用 Let’s Encrypt 網站來申請 SSL 憑證,不過 Let’s Encrypt 本身有時效,需要定期上去更新已申請的憑證序號。
使用者登入後,JupyterHub 會透過 Spawner 產生 Notebook Server 供使用者 使用,以伺服器角度來看,即為一個運行在伺服器上的程序(Proccess),因此,
每個Notebook Server 的環境全都指向同一台伺服器,一旦有使用者不小心更改 到環境或是有惡意使用者想破壞環境,都會連坐影響到其他使用者,將會讓平台 的安全及穩定性大大降低。因此,透過Docker Cotainer 來包裝每個 Notebook Server,資源彼此隔離的概念則因應而生。