用了前面的範例,尤其是歷史資料,會發現有可能重複輸入的狀況,或是重複資料輸入不進去。這是我故意的XDD
就是讓這一篇有機會出現,也就是用來說明避免重複輸入的狀況。
本日會修改的程式碼:
因為我們匯入的時候,有時候會把歷史資料匯進來,像是第10天的資料是「每日市場成交資訊」,而資料以當月為一個資料及,例如現在9月,所以會顯示過去9月的交易狀況,完整的提供,像今天是11日,就會收到從9/1~9/11這段時間的交易,如果是30日,就會收到整個月1~30日的所有資料,這時候沒有過濾就會收到很多重複的資料,尤其是每天都執行的話!
而有些則是匯入一些歷史資料的關係,像原先可能只有用一年份來進行檢測,後來發現這樣效果不錯,所以就花時間把所有歷史資料抓下來(有的資料只能一個月一個月抓,不能用年為單位或是整批抓),這時候有可能資料會重複抓取,也是需要過濾。
最常見的方法,就是使用主鍵(Primary key,又稱PK,後續用PK代替),它具有單一性值,不允許重複,當重複的時候就會發生例外事件。
像是發生在第9天的程式碼,目前最新的是在9/9:
2021-09-09 17175.00 17319.00 17123.00 17304.00
由於他每次都會抓一個月份,因此今天為了讓9/10的資料可以匯入資料庫,就直接執行檔案,結果會發生9/1的資料重複:
(1062, "Duplicate entry '2021-09-01' for key 'PRIMARY'")
這時候可以使用MySQL的一個語法IGNORE
,是用在INSERT中,可以忽略重複輸入的狀況,語法如下:
INSERT IGNORE INTO table_name(...)VALUES(...)
重新執行後,我們就可以看到成功資訊,而資料庫也補上9/10的資料(昨天收大紅盤~17475點)
===Finish: 8==
而資料庫也正確的出現這筆資料:
2021-09-10 17270.00 17475.00 17270.00 17475.00
然而我們範例中,像是第6天的程式碼,我們的PK是個ID,而且是隨著輸入增加,因此不會有重複的狀況。這時候就不能過濾PK重複的狀況,要另外設定一組Unique index
的方式,可以讓這組的欄位變成為一值,也就是上述PK的狀況。
語法如下:
ALTER TABLE table_name ADD UNIQUE INDEX(column1, column2...);
所以我們需要變動兩張表(table),分別是第4天和第6天的表(table):
ALTER TABLE LegalDailyFutureOption ADD UNIQUE INDEX(TradeDate, TradeGroup);
ALTER TABLE DailyPrice ADD UNIQUE INDEX(TradeDate, Symbol);
然後再重新跑這兩隻程式,就可以取得資料但不重複囉!如果不這樣改,會一直把資料持續寫入,因為他們的PK並不會重複而產生問題。
他們都是代表唯一值的概念,都可以為單一欄位或是組合的欄位,但是PK
是一定要有值的,Unique
是表示不能重複,但是可以為Null
。這就是他們的差異。
而且PK
,可以在跟Unique index
結合,像是我們有給他們不重複值,但是我們又希望他們某些特徵值不會重複,就是可以組合一起使用,就好像在第4天和第6天的狀況就是如此。不過以這個案例來說,簡單一點,就是要把ID
拿掉,直接用設定的UNIQUE INDEX
就可以解決。