2

TCG カードのデータベースがあり、主キーを決定しようとしています。最初は代理キーで解決しましたが、プロモーション カードなど、追加し忘れているカードがあることに気付きました。代理キーは最新の自動インクリメントでデータベースに追加され、挿入された順序に ID を依存させたくなかったため、これは問題です。カードの機能の一部をハッシュして、代わりにそれを主キーとして使用できるのではないかと考えていました。

たとえば、次の擬似コードを見てください。

// set code, date released, collector number, name
$crc = crc32(implode(',', ['A', '1993-08-03', '232a', 'black lotus']));
echo $crc; // 4199975187

カードの可能な量は、現在約 25k で推移しており、6 か月ごとに約 100 ~ 300 増加しています。

  1. このままじゃ衝突しないよね?
  2. これは良い習慣ですか?他に良い代替手段はありますか?

に変換することでハッシュを短くできることはわかっていますが、これらをユーザーのインベントリ テーブルに結合するので、これらを維持することが最善の選択肢になるbase 62と思います。int

4

2 に答える 2

3

私はこれを例外とします:

代理キーは最新の自動インクリメントでデータベースに追加され、挿入された順序に ID を依存させたくなかったため、これは問題です。

ID (正しくは、頭字語ではなく略語であるため、「Id」) は「Identity」の略で、各要素に対して一意であるという単一のプロパティを持っています。つまり、各要素を識別するために使用されます。それに他の意味合いを付けないでください。したがって、挿入順序で単調に増加するという事実は無関係であり、生成された ID 列によるデータの並べ替えは無意味です (ID によるルックアップに使用されるインデックス内にない限り)。その場合、ID を不透明なハンドルと見なす必要があります。

確かに、ダイジェスト (CRC-32 など) を使用する場合、Id の並べ替え順序は無意味ですが、実際には、単調に増加する ID を持つよりも実用性が低くなります。

ハッシュ衝突のリスクを正しく識別しました。CRC-32 の範囲空間はわずか 32 ビットであり、25,000 枚のカードがある場合、誕生日問題は、そのような小さな範囲空間でのハッシュ衝突の可能性が重要ではないことを示しています。 .

自動生成された Id 値を使用するだけです。:)

計算されたハッシュを識別子/キーとして使用することには有用性があります-これがハッシュテーブルの仕組みであり、実際にすべてのテーブルを検索することなく、値によって何かをすばやく見つけることができます(たとえば、ブラックロータスカードを見つけるには、あなたがするようにそのプロパティのハッシュ、次に ID 列で計算されたハッシュを検索しますSELECT ... WHERE code = 'A' AND ... AND name = 'black lotus'. .

ハッシュを主キーとして使用する際の主な問題は次のとおりです。

  1. 主キーは不変 (「不変」) である必要があります
  2. キーはデータに依存するようになりました
  3. データが変更された場合 (たとえば、「blcak lotus」が「Black Lotus」になる)、キーは無効であり、再作成する必要がありますが、キーは不変であるため、それを行うことはできません...以前に計算された Id が無効になります。

QED :)

于 2015-03-25T04:07:49.223 に答える