2012-02-07 4 views
3

私はproperieteryデータベース(実際にはファイルシステムですが、この議論ではこれを単純にしたいと思います)を検証しようとしています。データベースには、次のプロパティがあります。検証可能な乱数を生成する - Java

1つまたは2つの主キーを持つことができ、整数でなければなりません。 列には文字列(ASCII以外の文字列)、整数、ロング、または日時を使用できます。

このデータベースに保存するように要求する値に、多数のレコード(> 500kレコード)が正しく格納されていることを検証します。そこで、後で簡単に検証できるデータを生成するツールを拡張したいと考えています。

だから基本的に、これはサンプル・スキーマであると言う:

pk1 (int - primary key) 
pk2 (int - primary key) 
s1 (string) 
l1 (long) 
i1 (int) 

私はこのツールで500Kレコードを生成します。それから、いつでも、私は与えられたレコードを健全にチェックできるようにしたい。一連の操作(バックアップとデータベースの復元)を実行した後、レコードを「スポットチェック」することがあります。だから私は素早くプライマリキー(pk1 = 100、pk2 = 1)のレコードのエントリが有効であることを検証できるようにしたい。

後で簡単に検証できるように、各列の値を生成する最良の方法は何ですか。値は完全にランダムである必要はありませんが、頻繁に繰り返されるべきではないため、圧縮ロジックのいくつかにもヒットする可能性があります。一例として、

は、「何とか」ツールは、行に次の値生成されたと言う:

pk1 = 1000 
pk2 = 1 
s1 = "foobar" 
l1 = 12345 
i1 = 17 

を今、私はいくつかの操作を実行し、私はこれの最後にそれを検証する、この行があり壊れていない。私はs1、l1、i1の期待値を素早く生成することができなければなりません - pk1 = 1000とpk2 = 1 - これは本当に素早く検証できます。

アイデア?

(私は新しい慣れているので、自分の質問への答えを投稿するので、これを追加すること:) [OK]を、ので、私は私が追求する可能性が可能なアプローチをすることはできません。

アプローチ#1: 使用HASH(tablename)^ HASH(fieldname)^ pk1^pk2をシードとして使用します。このようにして、検証時に各列のシードを簡単に計算できます。反面、多くの行のデータを生成する場合、シードが列ごとに1回計算される必要があるため、これは高価になる可能性があります。したがって、上記のスキーマでは、500kレコードを生成するために500k * 3のシードを使用します。

アプローチ2(提案者:Philipp Wendler): 行ごとに1つのシードを生成し、その行の最初の列にシードを格納します。最初の列がintまたはlongの場合は、そのままの値を格納します。最初の列が文字列の場合、最初のxバイトにシードを格納し、そのシードを使用して生成された文字で必要な文字列長まで入力します。

私はアプローチ#2がより好きです。なぜなら、行ごとに1つのシードしかないため、データの生成をアプローチ#1よりやや早くするからです。たぶん

+0

... 私は、種子をこのように生成した場合: シード= HASH(テーブル名)^ HASH(ColumnNameにする)^ PK1^PK2 今、私は簡単にシードを計算することができますまだColumnNameには同じPK1とPK2の値のテーブル間リピートができ ...テーブル間多少ランダムなものを維持しながら、PK1とPK2与えられた..しかし、機能的に言​​えば、彼らはとにかく同じ値を持っているはずなので、それはOK ..です – walletless

+0

もう1つの選択肢は、Philipp Wendlerが以下に示唆したものを追求することです: 使用されたシードを格納するためにテーブルの最初の列を使用します。これがint型またはlong型の場合は、シードをそのまま格納してください。これが文字列の場合は、最初のnバイトを使用してシードを格納し、そのシードを使用して生成された文字を使用して必要な長さにフィールドを埋め込みます。 – walletless

+0

主キーも生成しますか?はいの場合は、他の列のハッシュを格納するために使用できます。これは、あなたのコースの挿入時にいくつかの衝突を与えることができる(ただし、ランダムにPKを生成する場合、これはまた起こる可能性) – wmz

答えて

0

これは、あなたの質問の唯一の第二部に答えるapache commons could be solution

+0

ありがとうございます。私はすでにこれを見てきました。問題は、 "シード"値を使用するようになっているので、簡単に文字列を生成することができます。 本質的に、この問題は次のようなものです。pk1(1000)とpk2(1);私はいつもs1、l1、そしてi1の同じ値を常に作ることができるように、ランダムジェネレータで使うべき種子は何ですか? – walletless

+0

@walletlessちょうどカラムの1つにシードを格納します(私の解決策で提案されているようなハッシュコードで行うことと同様)。次に、各行に対してランダムなシードを生成し、シードからその行のデータを生成することができます。 –

+0

このメソッドは、検証に使用される乱数生成アルゴリズムが、生成に使用された乱数生成アルゴリズムとまったく同じであるという事実に依存しています。これは今明らかになっているかもしれませんが、そのようなジェネレータの実装者はこれを保証せず、将来(例えば、ライブラリの次のバージョンで)アルゴリズムを少し変更するかもしれません。その後、あなたのデータは突然検証できなくなります。共通のハッシュコードのいずれかのように、よく標準化されたアルゴリズムを使用することによって、これは問題がなくなります。 –

0

から何か - どのような他のすべてのフィールドのハッシュを格納L1を作るでしょうか?そして、あなたはすぐに何が

+0

スキーマが常に長くなっていればそれは機能します。与えられた表の列のセットには、長い列がある場合とない場合があります。また、長い列も複数ある場合があります。既存のスキーマを変更することは、スキーマに依存するアプリケーションが特定のフォームにあるために選択できません。変更すると、生成されたデータの上で発生する機能テストが無効になります。 – walletless

1

を破損している場合は、単に、任意のランダムなデータを生成することがありました(それは暗号的に安全である必要はありませんので、例えばMD5)ハッシュコードを計算し、あなたのデータをハッシュコードを保存するかどうかを確認できます。ハッシュコード用に別の列を持つこともできますし、たとえば、任意の文字列に追加することもできます。ハッシュコードを再計算すると平等のためにそれらを比較し、その行の残りのデータから格納されたハッシュコードを分離する、検証のため

。一致しない場合は、データが変更されました。

これはあなただけ(ない、悪意のある攻撃者からの)不慮の変更からあなたのデータを保護することを想定しています。だから私はより創造的な解決策を考えています

+0

残念ながら、スキーマの変更はオプションではありません。 私は、アプリケーションへの入力として固定されたシードから始め、xorまたはpk1とpk2を使ってそれを開始することを考えました。それをランダムにシードとして使用します。 例えば、入力シードを12345として使用しているとします(これは何でもかまいませんが、たとえばシステムチック)。したがって、私のランダム関数の種は12345^1000^1になります。そして、そのランダムをApacheコモンで使うと、私は各列を生成することができます。 このアプローチの問題は、いくつかの行に対して同じ値が得られることです。 – walletless

+0

あなたの弦は任意の長さですか?あなたは常に文字列を持っていますか?その場合は、最初の文字列(たとえば)のデータの最後にハッシュコードを追加します。それ以外の場合は、1つまたは複数の数値列を選択することができます(ハッシュコードのビット数のうちのいくつか、たとえば64ビットを格納するだけで十分です)。 –

+0

この方法を使用すると、検証ツールは開始入力(この場合は12345)を知るだけでよく、pk1とpk2の値が与えられた行を簡単に検証できます。しかし、問題はこれが多数の二倍値を引き起こすことである。データは100個のテーブルに対して生成されるので、避けることができれば、各行のシードを別々に保存する必要はありません。 – walletless