2009-08-16 27 views
4

私は、一意のVARCHAR(512)フィールドを持つテーブルを持っています。私は別のテーブルにこの最初のテーブルへの外部キー参照を保持させたい。どちらのテーブルもInnoDBを使用しています。 2番目のテーブルにVARCHAR(512)キーを追加し、それに外部キー制約を追加すると、512バイトのデータが2回保持されますか?外部キーとしてvarcharのみを持つMySQLテーブル

もしそうなら、varchar自体ではなく、インデックスへの参照のみを保持する方法はありますか?つまり、InnoDBには、長いVARCHARフィールドに外部キーを保持する効率的な方法がありますか?

は、どうもありがとうございまし

Yaniv

答えて

2

あなたが参照しているテーブルの上にVARCHAR(512)列を持っている場合は、[はい、データは二回存在します。

参照テーブルの外部キーを、512バイトのデータではなく、最初のテーブルの整数プライマリキーにすることをお勧めします。これは、正規化のすべてのことです。

+0

しかし、varcharのインデックスが存在するときに整数キーを追加するのは無駄ではありませんか? 私が本当に欲しいのは、インデックスの内容だけを参照する方法です。 – Yaniv

+0

行に「ハンドル」が必要な場合は無駄ではなく、他のオプションは512文字のvarchar列のみです。 「インデックスの内容だけを参照する方法」というこの考え方は、私にとってはナンセンスのようです。索引索引の値以外は参照できません。 – chaos

+0

すべてのデータは実際に512バイトの長さですか?ストレージは、各行のレコードのサイズに制限する必要があります。可能であれば、整数の主キーと外部キーに行く方がよいでしょう。 – Turnkey

2

2つの列とID(int)とデータ(varchar [120])でデータ自体を保持する3つのテーブルを作成し、そのIDを外部キーとして使用する別のテーブルと、外部キーとしてデータを使用して、最後の1:

CREATE TABLE `dados` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `name` varchar(120) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `name` (`name`) USING BTREE, 
    KEY `idx` (`id`,`name`) 
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; 

CREATE TABLE `refINT` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `dado` int(10) unsigned NOT NULL, 
    PRIMARY KEY (`id`), 
    KEY `id` (`dado`), 
    CONSTRAINT `id` FOREIGN KEY (`dado`) REFERENCES `dados` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION 
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; 

CREATE TABLE `refSTR` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `dado` varchar(120) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, 
    PRIMARY KEY (`id`), 
    KEY `nome` (`dado`), 
    CONSTRAINT `nome` FOREIGN KEY (`dado`) REFERENCES `dados` (`name`) ON DELETE NO ACTION 
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; 

が各テーブルに100件のレコードを挿入して、最終的なテーブルのサイズを比較した:

dados: 192.0 KB 
refINT: 32.0 KB 
refSTR: 32.0 KB 

だから私は、データがvarchar型の外部キーに複製されていないと思い、よく、少なくともMySQL 5.1バージョンでは。

0

キーサイズを小さくすることは常に良いです。大量のVARCHARを索引付けするという問題を回避するには、挿入時に生成する追加のチェックサム列を使用することができます。このチェックサムフィールドには、大きな列のハッシュアルゴリズムCRC32()またはMD5()の出力が含まれます。

関連する問題