MySQL自增主键和手动生成主键区别

在设计关系型表结构时,设计主键是一个必不可少的步骤。而在实际应用中,经常会使用自增 id 作为主键。接下来分析一下自增主键和手动生成主键的区别。


自增主键

优点

  1. MySQL 推荐使用连续自增的主键 id,官方的推荐是 auto_increment
  2. Innodb 的索引特性使自增 id 做主键是效率最好,而且是增量增长,按顺序存放,对于检索非常有利
  3. 数字型,占用空间小,易排序
  4. 如果通过非系统增加记录时,可以不用指定该字段,不用担心主键重复问题

缺点

  1. 表的自增 id 达到上限后,再申请时它的值就不会改变,进而导致继续插入数据时报主键冲突的错误。
  2. row_id 达到上限后,则会归 0 再重新递增,如果出现相同的 row_id,后写的数据会覆盖之前的数据。
  3. 在手动要插入指定ID的记录时会比较麻烦
  4. 当多个系统需要数据导入时,很难保证原系统的ID不发生主键冲突,特别是在新系统上线时,新旧系统并行存在,并且是异库异构的数据库的情况下,需要双向同步时,自增主键将是个的噩梦。
  5. 若系统是数字型的,在导入时为了区分新老数据,可能想在老数据主键前统一加一个字符标识(例如“o”,old)来表示这是老数据,那么自动增长的数字型又面临一个挑战
  6. 主从复制:1)statement 模式下,由于他是记录的执行语句,所以,为了让这些语句在 slave 端也能正确执行,那么他还必须记录每条语句在执行的时候的一些相关信息,也就是上下文信息,以保证所有语句在 slave 端执行的时候能够得到和在 master 端执行时候相同的结果。在自增主键上面,有可能会出现不一致的情况。2)row 模式下,所有的执行的语句当记录到日志中的时候,都将以每行记录的修改来记录,这样可能会产生大量的日志内容
  7. 主主双向复制时主键自增长一定会出现重复,因为多主都可以对服务器有写权限


手动生成主键

最好保证插入顺序

优点

  1. 解决了自增上线问题
  2. 当异库异构的数据库的情况下,需要双向同步时,解决了自增主键噩梦的问题
  3. 插入数据时不需要再取出产生的 id 值
  4. 主从复制和主主双向复制的情况下可以有效保证重复问题


缺点

  1. 需要额外设计主键生成策略,还需要保证不会发生主键冲突问题
  2. 占用磁盘空间较大
  3. 通过非系统增加记录时,需要指定该字段,需要解决重复问题
  4. 当系统与其他系统集成时,需要数据导入时,很难保证原系统的ID不发生主键冲突
  5. 如果与其他系统主键类型或长度不同时,会导致修改主键数据类型了,这也会导致其他相关表的修改,后果同样很严重,又一个噩梦的开始

结论

  1. 小型系统或者系统架构初期,数据没有超过百万或者千万,可以使用自增主键
  2. 当数据成长到几百万或者超过千万时,并且增量很高时,这时就涉及到分库分表,这时就必须使用手动生成id方案
要设置Java中的主键自增,你需要在数据库表的主键字段上使用自增长属性,并在Java代码中做一些相应的配置。下面是一个示例: 1. 在数据库中设置自增主键 假设你的数据库表为`user`,主键字段名为`id`,你可以使用数据库自增长属性来设置主键自增。具体的语法可能会因数据库类型而有所差异,以下是MySQL和Oracle数据库的示例: - MySQL: ```sql CREATE TABLE user ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50), age INT ); ``` - Oracle: ```sql CREATE TABLE user ( id NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY PRIMARY KEY, name VARCHAR2(50), age NUMBER ); ``` 2. 在Java代码中配置主键自增Java的实体类或数据访问层中,你需要进行一些配置才能实现主键自增。以下是一些示例: - 使用JPA注解(适用于Spring框架): ```java import javax.persistence.*; @Entity @Table(name = "user") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private Long id; // 其他属性和方法 } ``` - 使用MyBatis注解(适用于MyBatis框架): ```java public interface UserMapper { @Insert("INSERT INTO user (name, age) VALUES (#{name}, #{age})") @Options(useGeneratedKeys = true, keyProperty = "id") void insertUser(User user); // 其他方法 } ``` 在上述示例中,使用了JPA注解的`@GeneratedValue(strategy = GenerationType.IDENTITY)`和MyBatis注解的`@Options(useGeneratedKeys = true, keyProperty = "id")`来配置主键自增。这将告诉数据库在插入数据时生成自增主键值,并将其赋值给Java对象的`id`属性。 请根据你使用的框架和数据库类型进行相应的配置。希望以上信息对你有所帮助!如果还有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

旷野历程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值