【问题标题】:set id unique to username设置用户名唯一的 id
【发布时间】:2021-05-10 04:00:25
【问题描述】:

我在 postgres 中有一个 POSTS 表,其架构如下所示

create table posts(postid int ,postname VARCHAR(255) NOT NULL,
 createdby VARCHAR(255) NOT NULL, PRIMARY KEY (postname),
 CONSTRAINT fk_user FOREIGN KEY(createdby) REFERENCES users(username) on DELETE CASCADE);

也许是一个菜鸟问题,但我不希望 postid 总是由用户设置,我希望它对用户来说是增量的。 例如,我有 2 个用户,每个用户都添加 2 个帖子,

所以我想将它存储在数据库中

postid.    postname.    createdby
1           hi           user1
2           second       user1
1           hi           user2
2           second       user2

postid 是否可以自动递增而无需我以这种方式插入?

即 postid 和 name 可以与不同的用户相似

【问题讨论】:

  • 这能回答你的问题吗? PostgreSQL Autoincrement
  • autoincrement 不断增加 postid,我希望它是每个用户的自动增量 @maio290
  • 您希望将其发布到数据库中的方式是一种奇怪的方法,对我来说没有多大意义。您已将 postname 定义为主键,但在您的示例中这些值甚至不是唯一的。最常见的方法是自动增加 postid 并将其设置为主键。或者您使用 createdBy 和 postname (?!?) 的组合键及其约束。

标签: postgresql auto-increment


【解决方案1】:
create table posts(
    postid int,
    postname VARCHAR(255) NOT NULL,
    createdby VARCHAR(255) NOT NULL,
    PRIMARY KEY (postname));

create function tgf_posts_bi() returns trigger language plpgsql
as $$
declare
    seq_name text;
begin
    seq_name := format('seq_posts_%s', new.createdby);
    execute format('create sequence if not exists %I start with 1', seq_name);
    new.postid := nextval((quote_ident(seq_name))::regclass);
    return new;
end $$;

create trigger tg_posts_bi
before insert on posts
for each row execute procedure tgf_posts_bi();

insert into posts(postname, createdby) values
    ('foo', 'John'),
    ('bar', 'Jack Daniel'),
    ('baz', 'Jack Daniel'),
    ('win', 'John'),
    ('amp', 'John'),
    ('M$ media mplayer', 'Mary');

table posts;

postid | postname         | createdby  
-----: | :--------------- | :----------
     1 | foo              | John       
     1 | bar              | Jack Daniel
     2 | baz              | Jack Daniel
     2 | win              | John       
     3 | amp              | John       
     1 | M$ media mplayer | Mary       

demo

【讨论】:

  • 但是当我为不同的createby添加相同的postname时,它仍然会抛出一个错误insert into posts (postname,createdby) values('foo','test');错误:重复的键值违反了唯一约束“posts_pkey”详细信息:键(postname)=(foo)已经存在。
  • @sai 是因为PRIMARY KEY (postname) 您需要为问题中提供的数据选择另一个主键。
【解决方案2】:

我不能 100% 确定您的问题,这可能过于简单化了,但据我了解,您只希望每个帖子/用户有一条记录。如果是这种情况,您的主键应该是 postnamecreatedby 字段,这将保证每个用户/帖子只有一条记录:

create table posts (
  postid int,
  postname VARCHAR(255) NOT NULL,
  createdby VARCHAR(255) NOT NULL,
  constraint posts_pk PRIMARY KEY (postname, createdby),
  CONSTRAINT fk_user FOREIGN KEY(createdby) REFERENCES users(username) on DELETE CASCADE
);

然后,当您插入而不是普通插入时,您想要执行 upsert。这表示如果记录不存在则插入该记录;否则更新它:

insert into posts (postid, postname, createdby)
values (1, 'hi', 'user1')
on conflict on constraint posts_pk
do
  update
  set
    postid = posts.postid + 1

我不禁觉得问题陈述中缺少一些东西,但据我所知,我希望这会有所帮助。

【讨论】:

  • 您可能应该补充一点,这意味着同一用户不能再次发布帖子 (?)。这对我来说听起来有点奇怪(因此我的评论)。
  • @maio290 - 用例对我来说非常不清楚,所以我承认我正在抓住这个稻草
  • 刚刚编辑了问题,所以不同用户的帖子可以相同
  • @sai - 我还是不明白。也许如果您可以添加当前语句、当前行为,然后具体说明所需的行为……这应该是一个很好的起点。它现在做什么与我想要它做什么(以及为什么)
猜你喜欢
  • 2017-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-07
  • 2021-09-29
相关资源
最近更新 更多