Mysql 使用一个特定的主键自动增加一列

Posted

技术标签:

【中文标题】Mysql 使用一个特定的主键自动增加一列【英文标题】:Mysql auto-increment a column with one specific primary key 【发布时间】:2018-02-09 18:02:56 【问题描述】:

假设我有一个具有以下方案的表: (注意邮政编号栏)

-- UserID  -- Post Id  -- Post Number*

-- 4       -- 85       -- 1
-- 4       -- 86       -- 2
....
-- 5       -- 9362     -- 1
-- 4       -- 9363     -- 3

有没有办法独立于所有其他条目自动增加列并且只尊重具有相同主键的那些?如果是这样,有人将如何实现这一点?

非常感谢。

【问题讨论】:

你的意思是自动增加帖子编号? 我猜 OP 想根据 UserId 列增加 Post Number。所以基本上每个 UserId 都会有自己的一组 PostNumber @Paul Karam 是的,这正是我所需要的。 【参考方案1】:

为了实现您的目标,您必须使用triggers。没有其他直接的方法可以完成这项任务(我猜)。

我现在确实尝试了一个快速演示:

Create Table SoQuestion (
  UserId int,
  PostId int,
  PostNumber int null
 );

 CREATE TRIGGER inc_post_num 
 BEFORE INSERT ON SoQuestion
 FOR EACH ROW
 set New.PostNumber = (select num 
                       From (select count(*) as num 
                             from SoQuestion 
                             where UserId = New.UserId) as b) 
                     + 1;


insert into SoQuestion (UserId, PostId) Values (1,1);
insert into SoQuestion (UserId, PostId) Values (1,10);
insert into SoQuestion (UserId, PostId) Values (1,20);
insert into SoQuestion (UserId, PostId) Values (2,1);
insert into SoQuestion (UserId, PostId) Values (2,10);
insert into SoQuestion (UserId, PostId) Values (3,1);
insert into SoQuestion (UserId, PostId) Values (4,1);

select * FROM SoQuestion;

这是我得到的输出:

UserId | PostId | PostNumber |
==============================  
1      | 1      | 1          |
1      | 10     | 2          |
1      | 20     | 3          |
2      | 1      | 1          |
2      | 10     | 2          |
3      | 1      | 1          |
4      | 1      | 1          |

这是demo。


在浏览了Auto_Increment 文档后,我找到了另一种不使用触发器来实现此目的的方法。这个想法是关于创建一个Auto_Increment 列并将其与另一列一起添加为PRIMARY KEY。在我们的例子中,它是UserIdAUTO_INCREMENTPostNumber,它们都构成了主键。方法是这样的:

Create Table SoQuestion (
  UserId int,
  PostId int,
  PostNumber int NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (UserId, PostNumber)
 );

insert into SoQuestion (UserId, PostId) Values (1,1);
insert into SoQuestion (UserId, PostId) Values (1,10);
insert into SoQuestion (UserId, PostId) Values (1,20);
insert into SoQuestion (UserId, PostId) Values (2,1);
insert into SoQuestion (UserId, PostId) Values (2,10);
insert into SoQuestion (UserId, PostId) Values (3,1);
insert into SoQuestion (UserId, PostId) Values (4,1);

select * FROM SoQuestion;

这将为我们提供与第一种方式相同的输出:

UserId | PostId | PostNumber |
==============================  
1      | 1      | 1          |
1      | 10     | 2          |
1      | 20     | 3          |
2      | 1      | 1          |
2      | 10     | 2          |
3      | 1      | 1          |
4      | 1      | 1          |

这是第二种方式的demo。

【讨论】:

你救了我。非常感谢。 Bug... 如果删除一行COUNT(*) 会引起麻烦。而是使用MAX(PostId)。但是,如果还没有条目,它就会变得混乱。【参考方案2】:
SET New.PostId := IFNULL(
      ( SELECT  MAX(PostId)+1
            FROM  SoQuestion
            WHERE  UserId = New.UserId ), 1);

这应该避免DELETECOUNT(*) 混淆的错误。

【讨论】:

以上是关于Mysql 使用一个特定的主键自动增加一列的主要内容,如果未能解决你的问题,请参考以下文章

mysql数据库中自动增长的主键也可以手动插入值吗?如何插入

JPA 自动建表- @Id,@GeneratedValue 与 @GenericGenerator 设置主键生成策略

使用 sqlalchemy 在刷新/提交时自动散列主键并使其持久化

sql server 中 怎么让自动增1的主键列 临时的 让它可以手动插入指定值?

mysql的主键是自动增长的,oracle的主键是起啥作用的

如果我的主键不自动递增,如何使用 PHP 获取最后插入的 ID