我有一個用於記錄實驗室訪問數據的表。表結構是這樣的:如何檢查SQL表中的數據完整性?
create table accesslog
(
userid int not null,
direction int not null,
accesstime datetime not null
);
本實驗只有一個門是在訪問控制下。因此用戶必須先「進入」實驗室才能「離開」。在我最初的設計中,我將「方向」字段設置爲1(用於輸入實驗室)或-1(用於離開實驗室)的標誌。所以,我可以使用查詢:
SELECT SUM(direction) FROM accesslog;
拿到實驗室內的用戶總數。理論上,它起作用了;因爲對於任何給定的userid,「方向」總是處於1 => -1 => 1 => -1的模式。
但是很快我發現日誌消息會在從實驗室門到服務器的傳輸路徑中丟失,或者由繁忙的網絡或硬件故障丟失。當然,我可以強制使用序列號,ACK,重傳,硬件冗餘等傳輸路徑,但最終我還是會得到這樣的:
userid direction accesstime
-------------------------------------
1 1 2013/01/03 08:30
1 -1 2013/01/03 09:20
1 1 2013/01/03 10:10
1 -1 2013/01/03 10:50
1 -1 2013/01/03 13:40
1 1 2013/01/03 18:00
這是一個最新的日誌爲用戶「1」 。很顯然,我在10點50分到13點40分之間爲該用戶輸入實驗室失去了一條日誌消息。當我查詢這些數據時,他仍然在實驗室,所以2013/01/03 18:00之後沒有退出日誌;這是肯定的。
我的問題是:有什麼辦法可以用SQL命令「查找」這個數據不一致嗎?我的系統中共有5000名用戶,實驗室24小時運行,實驗室沒有這樣的「魔法時間」。如果我必須編寫代碼逐行檢查「方向」字段的連續性,那麼我會非常可怕。
我知道用正確的數據「修復」日誌是不可能的。我只想知道「哦,我對userid = 1有數據不一致問題」,以便我可以將標記的修正數據添加到正確的最終統計數據中。
任何意見,將不勝感激,即使改變表結構也沒關係。
謝謝。
編輯:對不起,我沒有提到的細節。
當前我正在使用混合SQL解決方案。上面顯示的表格是MySQL,它僅包含24小時內的日誌作爲快速瀏覽的「實時」狀態。
每天早上3點,將會啓動一個用C++在POSIX上編寫的預定進程。此過程將計算統計數據,並通過專有協議TCP套接字將日常統計信息添加到Oracle數據庫中,然後它將從MySQL中刪除舊數據。
Oracle部分不是由我處理的,我無能爲力。我只是想確保每天的最終統計數據是正確的。
數據大小約爲每天200,000條記錄 - 我知道這聽起來很瘋狂,但它是真實的。
您正在使用哪種RDBMS? – Bridge
問題在於'消息'沒有傳遞給數據庫服務器。使用保證傳遞的消息代理(MSMQ,如果你進入微軟的話) –
這很難用SQL,但是在代碼中是微不足道的。你的數據量是多少?你用什麼語言來驅動SQL? –