2011-10-24 12 views
16

私は現在、このスキーマを持っている:MySQLのクエリのパフォーマンスのジレンマ:テーブル対列挙

CREATE TABLE `users` (
    `users_id` int(11) NOT NULL AUTO_INCREMENT, 
    `users_name` varchar(50), 
    `users_lastname` varchar(50), 
    `users_dob` date, 
    `users_type` int(11) NOT NULL default 0, 
    `users_access` int(11) NOT NULL default 0, 
    `users_level` int(11) NOT NULL default 0, 
    /* etc...*/ 
    PRIMARY KEY (`users_id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

CREATE TABLE `users_types` (
    `types_id` int(11) NOT NULL AUTO_INCREMENT, 
    `types_name` varchar(50), 
    PRIMARY KEY (`types_id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

/* etc..*/ 

問合せ:

SELECT 
    types_name AS user_type, 
    /* all other fields*/ 
    users.* 
    FROM users 
    INNER JOIN users_types ON (users.users_type=types_id); 
    /* INNER JOIN for all other tables*/ 
/* Rest of query */ 

私の新しいソリューション:

CREATE TABLE `users` (
    `users_id` int(11) NOT NULL AUTO_INCREMENT, 
    `users_name` varchar(50), 
    `users_lastname` varchar(50), 
    `users_dob` date, 
    `users_type` ENUM('type1', 'type2', 'type3'), 
    `users_access` ENUM('access1', 'access2', 'access3'), 
    `users_level` ENUM('level1', 'level2', 'level3'), 
    /* etc...*/ 
    PRIMARY KEY (`users_id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

問合せ:

SELECT 
    * 
    FROM users 

ENUMを使用していることから、ENUMは非常に簡単で実行が非常に簡単です。

  1. 私は正しいですか? LEFT JOINを持つのではなく、MySQLエンジンがENUM型フィールドを処理する方が速いでしょうか?
  2. ENUMを使用していますか? ENUMデータ型をテーブル自体に各レコードの別のテーブルを読み取る(すなわち不要)

    2)はい(Y)をインデックス付けされないよう

おかげ

+1

列挙型リストが変更される場合、テーブルは良好です。これは単純な挿入/更新クエリです。列挙型にはalter tableが必要です。 –

+0

ルックアップタイプの符号付き整数(4バイト)は少し過剰です - 符号なしタイニーイントはどうですか? –

+0

私はunsigned intを使うべきですか?私は200,000人以上のユーザーを持っています – Tech4Wilco

答えて

19

個人的には、intデータ型を使用する必要があり、そのデータのENUM化は別のレイヤーで行う必要があると思います。

表の定義は、列挙型の値域を格納するには不適切です。簡単に手に入りにくく、アプリケーションにテーブル定義を変更する権限を与えることは、セキュリティ上の問題(おそらく)です。

代わりに、INT型を使用して、ソフトウェアで、以下のデータベースと対話してENUMの外観を与えるモデルを作成することをお勧めします。

この設計では、データベースソフトウェアの切り替えは簡単ではありません。プロダクションアプリに「ALTER TABLE」権限を与える必要はなく、列挙型を拡張するのは簡単です。さらに、プログラムがENUM - > integerから変換する必要がある回数を減らしています。これは、すべてのデータベースSQL要求ではなく、コンパイル時に実行できます。

+0

のように、これらのオプションのファイルを別々のファイルに作成し、defineやsomethingなどとして使用します。define( 'USER_ACCESS_ADMIN'、1);? – Tech4Wilco

+0

はい、それは私がやることです。 –

+0

情報ありがとう – Tech4Wilco

1

1)はい、それは、より速くなるであろう他のテーブルでこれらのフィールドを使用しない場合は限ります。複数のテーブルで特定のフィールドを使用するとすぐに、そのフィールドのルックアップテーブルを作成する必要があります。また、フィールドにユーザー定義可能な値を設定したい場合は、フィールドを変更するためにデータベースを直接変更する必要はありません。別のテーブルを使用する必要があります。

+0

列挙型にエントリを追加しても、実際にはテーブルの再構築は強制されませんので、思ったよりも柔軟です。 – Johan

+0

ENUMリストを最新の状態に保つために、information_schema.columnsのエントリを変更する必要がある場合は、それを維持するのはもうちょっと難しいことです。 – Crontab

+0

これは単純な 'alter table change column'ステートメントです。必要なinformation_schemaには何のこともありません。 – Johan

関連する問題