2セットのスケジュールが同一であるかどうかをすばやく判断し、これらの一意のスケジュールを参照できるキーを生成しようとしています。私はもともとHASHBYTESを使おうとしましたが、ハッシュできるのは8000文字のみであり、連結すると8000より長い日時がかなりの数あることにすぐに気付きました。
そこで、ChecksumとChecksum_Aggはこの種のもののために設計されているように見えるので、それらを使用しようとしました。チェックサムは、一意でない値を生成する可能性が高いことを認識しています。しかし、これらを相互に比較する必要がある私の範囲/コンテキストは非常に狭いので、私はそれを回避できると思いました。
残念ながら、ほんの少しのテストの結果、わずか4行の日時データでチェックサムの「衝突」を見つけることができることがわかりました。これは少し変だと思い、衝突のパターンを発見しました。
以下は、問題を示すサンプルスクリプトです。
@RowsTABLEを宣言します (( [GroupId] INT、 [StartDate] DATETIME、 [終了日]DATETIME )。 --グループ1 INSERT INTO @Rows VALUES(1、 '2013-01-20 01:00:00.000'、 '2013-01-20 01:20:00.000') INSERT INTO @Rows VALUES(1、 '2013-01-20 01:20:00.000'、 '2013-01-20 01:40:00.000') --INSERT INTO @Rows VALUES(1、 '2013-01-20 01:40:00.000'、 '2013-01-20 02:00:00.000') --INSERT INTO @Rows VALUES(1、 '2013-01-20 02:00:00.000'、 '2013-01-20 02:20:00.000') --INSERT INTO @Rows VALUES(1、 '2013-01-20 02:20:00.000'、 '2013-01-20 02:40:00.000') --INSERT INTO @Rows VALUES(1、 '2013-01-20 02:40:00.000'、 '2013-01-20 03:00:00.000') --グループ2 INSERT INTO @Rows VALUES(2、 '2013-01-21 01:00:00.000'、 '2013-01-21 01:20:00.000') INSERT INTO @Rows VALUES(2、 '2013-01-21 01:20:00.000'、 '2013-01-21 01:40:00.000') --INSERT INTO @Rows VALUES(2、 '2013-01-21 01:40:00.000'、 '2013-01-21 02:00:00.000') --INSERT INTO @Rows VALUES(2、 '2013-01-21 02:00:00.000'、 '2013-01-21 02:20:00.000') --INSERT INTO @Rows VALUES(2、 '2013-01-21 02:20:00.000'、 '2013-01-21 02:40:00.000') --INSERT INTO @Rows VALUES(2、 '2013-01-21 02:40:00.000'、 '2013-01-21 03:00:00.000') SELECT [ChecksumAgg1] = CHECKSUM_AGG([CheckSum]) から (( SELECT [CheckSum] = CHECKSUM([StartDate]、[EndDate]) FROM @Rows WHERE GroupId = 1 )G1 SELECT [ChecksumAgg2] = CHECKSUM_AGG([CheckSum]) から (( SELECT [CheckSum] = CHECKSUM([StartDate]、[EndDate]) FROM @Rows WHERE GroupId = 2 )G2
結果は次のとおりです。
ChecksumAgg1:5681728
ChecksumAgg2:5681728
2つの一連の日付の唯一の違いは、1日離れていることです。しかし、それらは同じチェックサムを生成します!ただし、行数が偶数の場合のみ。グループ1のINSERTとグループ2のINSERTのコメントを解除すると、2つの異なるチェックサムが得られます。ただし、さらに別のペアのコメントを解除すると、別の一致が得られます。
最後に、2つの質問があります。これがどのように機能するのか、そしてなぜこのパターンがかなり予測可能なチェックサム値に影響を与えるように見えるのかについて、もう少し学びたいと思います。さらに重要なことに、非常に大きなデータセットの「フィンガープリント」を本質的に作成するためのより良い方法があるかどうかを知りたいと思います。このハッシュがグローバルに一意であることを保証できないことは理解していますが、チェックサムよりも優れたものが必要なようです。
チェックサム計算をだまし取ることができた1つの方法は、チェックサム関数に事前にフィードする日時にHASHBYTESを実行することでした。このようにして、チェックサムには、見た目が似ている一連の日付よりもはるかにランダムに見える値が供給されます。しかし、それで十分でしょうか?
編集-ここにもう少しコンテキストがあります。
基本的に、私は大量のスケジュールデータを持つ1つのシステムと、特定の時間にこれらのスケジュールに関心を持つ別のシステムを持っています。たとえば、複数のユーザーがこの複雑なスケジュールの一部の特定のバージョンを表示し、メタデータ(承認ステータス、メモなど)を追加したい場合があります。外部ソースが単一の日時に変更を加えた場合、同じスケジュールではなくなったため、このリンクを解除する必要があります。
コアスケジュールデータに変更を加える可能性のあるさまざまなシステムがあります。そのため、この懸念をコードレベルでバブリングして、これを何らかの方法で各スナップショットを表すエンティティに管理および「正規化」するのに苦労しています。変更をリッスンし、スケジュールを指しているものをすべてクリーンアップするために、100万の場所にフックを配置する必要があります。