最大3071文字を保持できるVARCHAR
カラムを含むInnoDBテーブルを作成しようとしています。この列のデータにUNIQUE
制約を適用したいと思います。
MySQLはインデックスを使用して制約を強制しているようです。 InnoDBでは、インデックスサイズは767バイトに制限されているように見えます-データを保持しているVARCHAR(3071)
カラムには十分ではありません。
最大データ長やInnoDBの使用法を犠牲にすることなく、データベースにデータの一意性を強制する方法についての考えはありますか?
巨大な gen_clust_index (内部クラスタ化インデックス)は必要ありません。セカンダリインデックスであっても、そのサイズは信じられないほど巨大です。
事前にキーをチェックするために、トリガーまたはストアドプロシージャを使用する必要がある場合があります。
VARCHAR(3071)
フィールドを使用して SHA1 関数呼び出しを実行することも考えられます。 SHA1 は、40文字のフィールドを返します。このハッシュは、インデックスを作成するために必要なものです。
これがあるとしましょう
CREATE TABLE mytable
(
id int not null auto_increment,
txt VARCHAR(3071),
primary key (id)
) ENGINE=InnODB;
そして、txtにUNIQUE
インデックスを作成したいとします。 SHA1 アプローチを試す
CREATE TABLE mytablenew LIKE mytable;
ALTER TABLE mytable ADD txtsha1 CHAR(40);
ALTER TABLE mytable ADD UNIQUE KEY (txtsha1);
INSERT INTO mytablenew (id,txt,txtsha1)
SELECT id,txt,SHA1(txt) FROM mytable;
次に、それらを数えます
SELECT COUNT(1) FROM mytable;
SELECT COUNT(1) FROM mytablenew;
カウントが同じ場合、おめでとうございます!!!これで、長さが40の一意のインデックスが作成されました。次のように仕上げることができます。
ALTER TABLE mytable RENAME mytableold;
ALTER TABLE mytablenew RENAME mytable;
DROP TABLE mytableold;
以下のコメントで指摘されているように、これはより原子的になる可能性があります:
RENAME TABLE mytable TO mytableold, mytablenew TO mytable;
DROP TABLE mytableold;
この大きな列を使用する予定の任意のテーブルでこれを実行します。 INSERT
のデータとともに、データの SHA1 を追加することを忘れないでください。
重複キーのオッズは2分の1から160乗です(その1.4615016373309029182036848327163e + 48。正確な数値が得られれば、いつか投稿します)。
試してみる !!!