当前位置:  开发笔记 > 编程语言 > 正文

每组值自定义SERIAL/autoincrement

如何解决《每组值自定义SERIAL/autoincrement》经验,为你挑选了2个好方法。

我正在尝试建立一个排序的博客系统,我遇到了一个小问题.

简单地说,我的article表中有3列:

id SERIAL,
category VARCHAR FK,
category_id INT

id column显然是PK,它被用作所有文章的全局标识符.

category 列很好..类别.

category_id用作UNIQUE类别中的ID,因此目前存在UNIQUE(category, category_id)约束.

不过,我也想为category_id自动递增.

我想要它,以便每次我执行像这样的查询

INSERT INTO article(category) VALUES ('stackoverflow');

我希望category_id根据最新category_id的"stackoverflow"类别自动填充列.

在我的逻辑代码中实现这一点非常容易.我只选择最新的num并插入+1,但这涉及两个单独的查询.我正在寻找一个可以在一个查询中完成所有这些的SQL解决方案.



1> Erwin Brands..:

这已被多次询问,并且一般的想法在多用户环境中肯定会失败 - 博客系统听起来就是这样的情况.

所以最好的答案是:不要.考虑一种不同的方法.

将列category_id完全从表中删除- 它不会存储其他两列不会存储的任何信息(id, category).

id是一个serial专栏,并且已经以可靠的方式自动递增.

自动增加SQL函数

如果您需要某种category_id无间隙category,请在运行时生成row_number():

复合键的每组行的序列号



2> Kamil Goscim..:

概念

至少有几种方法可以解决这个问题.我想到的第一个:

category_id通过覆盖INSERT语句中的输入值,为每行执行的触发器内的列分配值.

行动

这是SQL Fiddle看到代码的实际应用


对于一个简单的测试,我正在创建article表格保持类别,并且id每个类别应该是唯一的category.我省略了约束创建 - 这与提出要点无关.

create table article ( id serial, category varchar, category_id int )

使用generate_series()函数为两个不同的类别插入一些值以使其具有自动增量.

insert into article(category, category_id)
  select 'stackoverflow', i from generate_series(1,1) i
  union all
  select 'stackexchange', i from generate_series(1,3) i

创建一个触发器函数,它将选择MAX(category_id)并递增其值,1因为category我们正在插入一行,然后在继续使用实际INSERT到表之前覆盖该值(BEFORE INSERT触发器负责处理).

CREATE OR REPLACE FUNCTION category_increment()
RETURNS trigger
LANGUAGE plpgsql
AS
$$
DECLARE
  v_category_inc int := 0;
BEGIN
  SELECT MAX(category_id) + 1 INTO v_category_inc FROM article WHERE category = NEW.category;
  IF v_category_inc is null THEN
    NEW.category_id := 1;
  ELSE
    NEW.category_id := v_category_inc;
  END IF;
RETURN NEW;
END;
$$ 

使用该功能作为触发器.

CREATE TRIGGER trg_category_increment 
  BEFORE INSERT ON article 
  FOR EACH ROW EXECUTE PROCEDURE category_increment()

为现有类别和不存在的类别插入更多值(后触发设备).

INSERT INTO article(category) VALUES 
  ('stackoverflow'),
  ('stackexchange'),
  ('nonexisting');

用于选择数据的查询:

select category, category_id From article order by 1,2

初始插入的结果:

category    category_id
stackexchange   1
stackexchange   2
stackexchange   3
stackoverflow   1

最终插入后的结果:

category    category_id
nonexisting     1
stackexchange   1
stackexchange   2
stackexchange   3
stackexchange   4
stackoverflow   1
stackoverflow   2

推荐阅读
落单鸟人
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有