复合主键的弊端

bad case:在activity_spring_red_packet_sync表的设计过程中,将id,user_id,date三列作为了一个复合主键。
上述情况有哪些不妥的地方?

一、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='春节活动收发红包次数';

二、问题分析

  • 什么是联合索引,和复合索引有什么区别?
  1. 当两个数据表形成的是多对多的关系,那么需要通过两个数据表的主键来组成联合主键,就可以确定每个数据表的其中一条记录了
  2. 在一个数据表中通过多个字段作为主键来确定一条记录,那么,多个字段组成的就是复合主键
  • 复合主键的弊端?
  1. 如果有频繁的业务修改,会导致非聚集索引中的主键信息相应修改,而且容易造成表中记录的物理移动。
  2. 生成有业务含义的字段需要按照一定的规则生成,不可避免使用varchar等字符串类型,影响插入和查询效率。
  3. 业务规则发生变化,造成的影响容易扩大。

三、解决问题

  • 需要的是将用户和日期作为一个唯一标识;
  • 利用索引 UNIQUE KEY
PRIMARY KEY (`id`),
UNIQUE KEY `SPRING_RED_PACKET_USER_DATE_IDEX` (`date`,`phone`) USING BTREE

猜你喜欢

转载自blog.csdn.net/CUG_ZG/article/details/87691663