ラボのアクセスデータをログに記録するためのテーブルがあります。次のようなテーブル構造:
create table accesslog
(
userid int not null,
direction int not null,
accesstime datetime not null
);
このラボには、アクセス制御下にあるゲートが1つだけあります。したがって、ユーザーは「退出」する前に、まずラボに「入室」する必要があります。私の元の設計では、「方向」フィールドを1(ラボに入る場合)または-1(ラボから出る場合)のいずれかのフラグとして設定しました。次のようなクエリを使用できるようにします。
SELECT SUM(direction) FROM accesslog;
ラボ内の合計ユーザー数を取得します。理論的には、それは機能しました。「方向」は、任意のユーザーIDに対して常に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の間にラボに入るそのユーザーのログメッセージを1つ失ったことは明らかです。私がこのデータを照会している間、彼はまだラボにいるので、2013/01/0318:00以降に終了するログはまだありません。それは肯定的です。
私の質問は次のとおりです。SQLコマンドとのこのデータの不整合を「見つける」方法はありますか?私のシステムには合計5000人のユーザーがいて、ラボは24時間稼働しており、ラボがクリアされるような「魔法の時間」はありません。「方向」フィールドの連続性を行ごと、ユーザーごとにチェックするコードを書く必要があるとしたら、恐ろしいことです。
正しいデータでログを「修正」することは不可能であることを私は知っています。「ああ、userid = 1のデータの不整合の問題があります」を知りたいので、マークされた修正データを正しい最終統計に追加できます。
テーブルの構造を変えても大丈夫ですので、アドバイスをいただければ幸いです。
ありがとう。
編集:申し訳ありませんが、詳細については触れませんでした。
現在、混合SQLソリューションを使用しています。上に示した表はMySQLであり、高速ブラウジングの「リアルタイム」ステータスとして24時間以内のログのみが含まれています。
毎日午前03:00に、POSIXでC++で記述された事前にスケジュールされたプロセスが開始されます。このプロセスでは、統計データを計算し、プロプライエタリプロトコルのTCPソケットを介して毎日の統計をOracle DBに追加し、MySQLから古いデータを削除します。
オラクルの部分は私が扱っていないので、私はそれについて何もできません。毎日の最終的な統計が正しいことを確認したいだけです。
データサイズは1日あたり約200,000レコードです。これはおかしなことに聞こえますが、本当です。