MySQL で e コマース Web アプリケーションを設計しようとしていますが、ユーザー テーブルの正しい主キーの選択に問題があります。与えられた例は、説明のための単なるサンプル例です。
ユーザーテーブルには次の定義があります
CREATE TABLE IF NOT EXISTS `mydb`.`user` (
`id` INT NOT NULL ,
`username` VARCHAR(25) NOT NULL ,
`email` VARCHAR(25) NOT NULL ,
`external_customer_id` INT NOT NULL ,
`subscription_end_date` DATETIME NULL ,
`column_1` VARCHAR(45) NULL ,
`column_2` VARCHAR(45) NULL ,
`colum_3` VARCHAR(45) NULL ,
PRIMARY KEY (`id`) ,
UNIQUE INDEX `username_UNIQUE` (`username` ASC) ,
UNIQUE INDEX `email_UNIQUE` (`email` ASC) ,
UNIQUE INDEX `customer_id_UNIQUE` (`external_customer_id` ASC) )
ENGINE = InnoDB
主キー候補列で次の問題に直面しています。
ID列
長所
- ビジネス上の意味なし (安定した主キー)
- テーブル結合の高速化
- コンパクターインデックス
短所
- 「自然な」キーではない
- すべての属性テーブルは「マスター」ユーザー テーブルと結合する必要があるため、非結合の直接クエリは実行できません
- 「自然な」SQL クエリが少なくなる
- 情報漏えい: 開始値が 0 の場合、ユーザーは登録済みユーザーの数を知ることができます (開始値を変更すると、これが整理されます) ii) ユーザーは、プロファイルを time_X に user_A として登録し、しばらくしてから time_Y に user_B として登録できます。期間中の登録ユーザー数を計算する ((user_B の ID) - (user_A の ID)/(time_Y - time_X))
メール欄
長所
- なし
短所
- ユーザーは電子メール アドレスを変更できる必要があります。主キーには適していません
ユーザー名列
長所
- 「自然な」主キー
- テーブル結合が少ない
- よりシンプルで「自然な」クエリ
短所
- テーブルを結合するときに varchar 列が遅くなる
- varchar 列のインデックスは、int 列のインデックスよりコンパクトではありません
- 外部キーは値に依存するため、ユーザー名を変更するのは非常に困難です。解決策: アプリケーションのすべての外部キーを「同期」するか、ユーザーがユーザー名を変更できないようにします。たとえば、ユーザーはプロファイルを削除して新規登録する必要があります。
external_customer 列
長所
顧客の外部参照として使用でき、情報を保持しません (代わりに、編集不可能なユーザー名を使用できますか?)
短所
自動増分の場合、情報が漏洩する可能性があります (可能であれば)
- MySQL innodb エンジンは同じテーブルに複数の auto_increment カラムを持たないため、自動インクリメンタル サロゲート ID がすでに使用されている場合、一意の値を生成するのに問題があります。
スケーラブルな e コマース Web アプリケーションのユーザー テーブルの主キーを選択する際の一般的な方法は何ですか? すべてのフィードバックに感謝