具有复合主键的序列[英] Sequences with composite primary key

本文是小编为大家收集整理的关于具有复合主键的序列的处理方法,想解了具有复合主键的序列的问题怎么解决?具有复合主键的序列问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

使用postgreSQL,如何为以下方案管理序列(自动递增整数ID) -

表命名为"业务",其中有"ID"和更多列.

表命名为"用户",其中包含:

  1. 复合主键,由'business_id'和'id'组成,并且当我插入现在行时,具有"id"重置它对每个'business_id'的计数.

  2. 一个简单的列'name'.

每个业务的单独序列.

示例

当我运行以下查询时:

插入用户(business_id,name)值(1,'a')

插入用户(business_id,name)值(2,'b')

插入用户(business_id,name)值(1,'c')

我想结束以下'用户的表:

business_id,id,name

1,1,'a'

1,2,'c'

2,1,'b'

推荐答案

如果您无法预测有多少(最多)用户将与一个企业相关(即使您可以,则不会使用序列(即使您可以,我不会以这种方式建议使用增量).

如果您使用postgres> = 9,则可以使用
>避免最大查询,通过将计数器作为主表的列(或创建一个包含对Business_ID(PK)的新表,如果您无法更改Businesses表).

添加列next_id:

ALTER TABLE Businesses ADD COLUMN next_id bigint;
//update current rows with default value
ALTER TABLE Businesses ALTER COLUMN next_id SET DEFAULT 0;
ALTER TABLE Businesses ALTER COLUMN next_id SET NOT NULL;
要插入用户,请使用以下单个SQL语句,从而返回新ID.

With X as (
    Update Businesses
    set next_id=next_id+1 
    where id=:param_business_id
    Returning next_id)
Insert into Users (business_id,id,name)
Select :param_business_id, X.next_id ,:param_name
From X
Returning id

这将将第一个ID插入为"1",因为(第一个)返回子句返回更新值. 或者如果您使用包含IDS的单独表,只需将"更新业务"替换为"更新My_id_table". 请注意,此解决方案不是vanilla sql.

其他推荐答案

INSERT INTO [users]
(business_id, id)
FROM
(
SELECT 
ID - (SELECT MIN(ID) FROM [users] WHERE business_ID = B.ID) AS business_id
,(SELECT MAX(ID)+1 FROM [users] WHERE business_ID = B.ID) AS ID
FROM [businesses] B
)

如果将此链接到您添加的新条目,则应提供复合键

新更新:

INSERT INTO [users]
(business_id, id, name)
VALUES
(
3
,ISNULL((SELECT MAX(ID)+1 FROM [users] WHERE business_ID = 3),1) AS ID
,'d'
)

本文地址:https://www.itbaoku.cn/post/1763943.html