悪いケース: activity_spring_red_packet_sync テーブルの設計プロセスでは、id、user_id、date の 3 つの列が複合主キーとして使用されます。
上記の状況の何が問題なのでしょうか?
1 つの SQL ステートメント
CREATE TABLE `activity_spring_red_packet_sync` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`phone` char(15) NOT NULL COMMENT '用户手机号',
`date` date NOT NULL COMMENT '发送日期',
`remain_send_times` int(11) NOT NULL COMMENT '剩余可发红包次数',
`remain_get_times` int(11) NOT NULL COMMENT '剩余领取红包次数',
`create_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`update_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`,`user_id`,`date`),
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=latin1 COMMENT='春节活动收发红包次数';
2. 問題分析
- 結合インデックスとは何ですか?また、複合インデックスとの違いは何ですか?
- 2 つのデータ テーブルが多対多の関係を形成する場合、2 つのデータ テーブルの主キーを使用して結合主キーを形成し、各データ テーブル内のレコードの 1 つを決定する必要があります。
- データ テーブルでは、レコードを決定するための主キーとして複数のフィールドが使用され、複数のフィールドが複合主キーを形成します。
- 複合主キーのデメリットは?
- 業務変更が頻繁に発生すると、それに応じてノンクラスタードインデックスの主キー情報も変更され、テーブル内のレコードの物理的な移動が発生しやすくなります。
- ビジネス上の意味を持つフィールドは特定のルールに従って生成する必要があり、varchar などの文字列型は避けられないため、挿入やクエリの効率に影響します。
- ビジネスルールの変更は影響を容易に拡大する可能性があります。
3. 問題を解決する
- 必要なのは、ユーザーと日付を一意の識別子として使用することです。
- インデックスUNIQUE KEYを利用する
PRIMARY KEY (`id`),
UNIQUE KEY `SPRING_RED_PACKET_USER_DATE_IDEX` (`date`,`phone`) USING BTREE