1

MS Access 2013で、「長いテキスト」タイプの列(以前はメモと呼ばれていました)を1つだけ含むテーブルを作成し、それをテーブルの主キーにしました。255 文字以上の長い文字列を保存してから、最初の 255 文字が以前に保存された文字列と同じである別の文字列を保存しようとしましたが、最初の 255 文字以降の他のすべての文字が異なり、MS Access で「重複データ」エラーが発生しました。新しい文字列で、255 番目以降の文字をさまざまな組み合わせの文字を使用して変更したところ、すべてエラーが発生しました。しかし、255 番目の位置より前の文字を変更しても、エラーは発生しません。したがって、MS Access は、その列の重複をチェックするために、「長いテキスト」データ型の最初の 255 文字のみをチェックすると結論付けました。そうですか?他に何が理由でしょうか?

文字列 256 文字で保存: Lorem Ipsums は、印刷および植字業界の単なるダミー テキストです。

文字列がエラーを出しました: Lorem Ipsumissimplydummytextoftheprinting and typesetting industryLorem Ipsum has been the standard dummy textevers because of an unknown printer tookagalleyoftypeandscrambledit to make typespecimenbookI has been the 5世紀だけでなく、leapin toelect1

文字列がエラーを出しました: Lorem Ipsumissimplydummytextoftheprinting and typesetting industryLorem Ipsum has been the standard dummy textevers because of an unknown printer tookagalleyoftypeandscrambledit to make typespecimen bookIt has been the 5世紀だけでなくリーピントゥエレクト2

文字列エラー: Lorem Ipsumissimplydummytextoftheprinting and typesetting industryLorem Ipsum has been the standard dummy textevers because of an unknown printer tookagalleyoftypeandscrambledit to make typespecimenbookI has been the 5世紀だけでなくリーピン・トゥ・エレクト123

エラーを出さない: Lorem Ipsums は、印刷および植字業界の単なるダミーテキストです。

エラーを出さない: Lorem Ipsums は単に印刷および植字業界のダミーテキストである Lorem Ipsum は 1500 年代以来業界標準のダミーテキストであった

エラーを出さない: Lorem Ipsums は印刷および植字業界のダミーテキストを意味する

上記のサンプルの最後の数文字の違いに注意してください。最初に格納された文字列は 256 文字です。列が主キーでない場合でも、その列のテーブル設計で「インデックス: はい (重複なし) を許可」の値が true に設定されている場合、問題は同じままです。

4

1 に答える 1

5

@HansUp がコメントで述べたように、Access (具体的には Jet/ACE db エンジン) はメモ/ロング テキスト フィールドの最初の 255 文字のみを使用してインデックスを作成します。したがって、最初の 255 文字のみを使用して、重複なしを強制します。

長い文字列と全文検索をより適切にサポートする別の db エンジンを使用するという @HansUp のアドバイスは、おそらく最良のアプローチですが、Access での問題の解決を制限する可能性のある他の考慮事項があることを理解しています。

そのため、問題を解決するためのアクセスのみのアプローチを次に示します。これは、コメントに記載されている要件が有効であることを前提としています。つまり、400 ~ 1000 文字の一意の文字列を格納する必要があります。


代替案 1

  1. 最初のメモ/長いテキスト フィールドを保持します: メモ
  2. 最大 250 文字の 4 つのテキスト フィールド (メモ/ロング テキストではない) を作成します: Notes1、Notes2、Notes3、Notes4
  3. 4 つのテキスト フィールドをすべて設定します: Required -> True および Allow Zero Length -> True (これは、751 文字未満の文字列に一意のインデックスが適用されるようにするために必要です)
  4. 一意のインデックスを作成し、4 つのテキスト フィールドすべてをそのインデックスに追加します
  5. インデックスの null を無視しないでください
  6. 値を保存するときは、それらを Notes フィールドに保存し、文字列を 4 つの小さな NotesX フィールドに分割する必要があります。

代替案 2:

現在の設定を維持し、コード レベルで一意性を適用します。メモを更新または挿入するたびに、最初の 255 文字に一致するすべてのメモを検索し、値を読み取り、コードで比較を実行します。


代替案 3 (コメントでこれを提案してくれた @HansUp に感謝):

  1. 最初のメモ/長いテキスト フィールドを保持します: メモ
  2. 16 文字または 32 文字のテキスト フィールドを作成して、長いテキストの 256 ビットまたは 512 ビットのハッシュを保存します: NotesHash
  3. NotesHash フィールドに一意のインデックスを追加する
  4. メモ フィールドが変更されるたびに、ハッシュ値を再計算し、テーブルに格納しようとします。

この方法の注意事項:

  • の巣の原理が簡単に証明するように、2 つの異なる文字列が同じハッシュを生成する (衝突) 可能性があります。ただし、適切なハッシュ アルゴリズムを使用すると、実際の確率はゼロに近づきます。
  • このサイトでは、さまざまなハッシュ アルゴリズムの VB6/VBA/VBScript 実装をいくつか提供しています。私は彼らの正しさを保証することはできませんが、彼らは私の目のテストに合格しました. 自己責任で使用してください。ただし、少なくとも良い出発点です。
  • 実際には、任意の大きな入力を指定して 255 文字以下の文字列を返す任意の決定論的関数を使用できます。安っぽいハッシュ アルゴリズムと優れたハッシュ アルゴリズムの違いは、衝突をどれだけ最小限に抑えるかです。そのため、一般的な規格に基づいたものを使用することをお勧めします。

はい、@HansUpのソリューションを使用して、別のdbエンジンを使用することを強くお勧めします。

于 2013-08-29T20:40:48.400 に答える