【问题标题】:Custom scoped increment SQL column [duplicate]自定义范围增量 SQL 列 [重复]
【发布时间】:2018-10-05 00:40:26
【问题描述】:

我有users 表和posts 表。一个用户有很多帖子。

CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(10));

CREATE TABLE posts (id INT, user_id INT, text TEXT, PRIMARY KEY(id, user_id));

我的问题是,如何创建自动递增机制来递增用户帖子的id,但仅限于用户(user_id)。

例如,

用户1 有2 个帖子,第一个帖子的ID 为1,第二个帖子的ID 为2

用户2有3个帖子,第一个帖子的id是1,第二个帖子的id是2,第三个帖子的id是3

posts 表的行将如下所示。

SELECT * FROM posts; user_id id text 1 1 'Post one from user 1' 2 1 'Post one from user 2' 2 2 'Post two from user 2' 2 3 'Post three from user 2' 1 2 'Post two from user 1'

我知道这可以通过在两次访问数据库的应用程序级别上实现它来完成,例如查询特定用户的最后一个帖子 ID 并基于该 ID 创建帖子。但这会在多用户环境中引入冲突。

【问题讨论】:

    标签: sql postgresql


    【解决方案1】:

    我可能没有正确理解您的问题,但您可以在插入时通过在插入中使用子查询轻松增加帖子的 ID。

    INSERT INTO posts (user_id, id, text) VALUES
    (userIdVar, (SELECT max(id) + 1 FROM posts WHERE user_id = userIdVar), postText);
    

    【讨论】:

    • 谢谢!我认为这应该工作!我不知道这是可能的。我需要将其包装在交易中吗?还是这些已经是原子的了?
    • 暂时未解决,因为我认为这个查询不是原子的。如果两个进程同时访问 post 行,这将产生竞争条件。
    • 用户怎么可能同时发布两条消息?如果您担心比赛,可以使用SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;,尽管这会使您的交易成本更高。
    • @ChristianSakai @ChristianSakai SELECT max(id) + 1 FROM posts WHERE user_id = userIdVar 也不会看到未提交的交易,因此您可能会获得相同的 ID 号。我不确定 SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; 是否会解决此问题。
    • @BShaps 会有几个管理员尝试像用户一样做同样的事情(即创建、编辑、删除等)。抱歉,我最初的问题陈述中并不清楚。
    猜你喜欢
    • 2017-09-13
    • 1970-01-01
    • 1970-01-01
    • 2014-12-05
    • 1970-01-01
    • 2018-09-10
    • 2013-03-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多