相关疑难解决方法(0)

如何原子替换PostgreSQL中的表数据

我想替换一个表的全部内容,而不影响过程中任何传入的SELECT语句。

用例是有一个表,用于存储定期提取的邮箱信息,并且需要存储在 PostgreSQL 表中。有许多客户端使用不断查询同一张表的应用程序。

通常,我会做类似(伪代码传入)...

BEGIN TRANSACTION
TRUNCATE TABLE
INSERT INTO
COMMIT
Run Code Online (Sandbox Code Playgroud)

但不幸的是,在此过程中无法读取该表;由于INSERT INTO完成需要时间。桌子被锁上了。

在 MySQL 中,我会使用他们的原子RENAME TABLE命令来避免这些问题......

CREATE TABLE table_new LIKE table; 
INSERT INTO table_new;
RENAME TABLE table TO table_old, table_new TO table; *atomic operation*
DROP TABLE table_old;
Run Code Online (Sandbox Code Playgroud)

我如何在 PostgreSQL 中实现这一点?

对于这个问题,您可以假设我没有使用外键。

postgresql

18
推荐指数
1
解决办法
2万
查看次数

如何根据行数执行条件插入?

我正在使用 Postgres 9.3,我需要根据表中已有的特定行数来防止插入到表中。这是表:

                                      Table "public.team_joins"
     Column      |           Type           |                            Modifiers                             
-----------------+--------------------------+---------------------------------------------------------
 id              | integer                  | not null default nextval('team_joins_id_seq'::regclass)
 team_id         | integer                  | not null
Indexes:
    "team_joins_pkey" PRIMARY KEY, btree (id)
    "team_joins_team_id" btree (team_id)
Foreign-key constraints:
    "team_id_refs_teams_id" FOREIGN KEY (team_id) REFERENCES teams(id) DEFERRABLE INITIALLY DEFERRED
Run Code Online (Sandbox Code Playgroud)

因此,例如,如果一个 id 为 3 的团队只允许 20 名玩家,并且SELECT COUNT(*) FROM team_joins WHERE team_id = 3等于 20,那么没有玩家应该能够加入团队 3。处理这种情况并避免并发问题的最佳方法是什么?我应该使用SERIALIZABLE事务来插入,还是可以WHERE在插入语句中使用这样的子句?

INSERT INTO team_joins (team_id)
VALUES (3)
WHERE (
  SELECT COUNT(*) FROM team_joins WHERE …
Run Code Online (Sandbox Code Playgroud)

postgresql database-design insert concurrency

9
推荐指数
1
解决办法
2万
查看次数

Postgres 中匹配条件的行数上限

假设我有一个像这样的数据库模式

user_id text
photo_id text
date_created timestamp
Run Code Online (Sandbox Code Playgroud)

我想强制执行“一个用户只能拥有 30 张照片”的约束。实现这一点的一个天真的方法是

SELECT COUNT(*) FROM user_photos WHERE user_id='usr_123'
Run Code Online (Sandbox Code Playgroud)

将结果与 30 进行比较,如果较低,则进行插入。天真,因为如果您可以在短时间内触发多个请求,您就可以赢得一场比赛并最终写入 30 多个记录。

有没有办法在数据库中强制执行此约束?例如创建某种索引“只能插入 30 行”,或者什么?有没有办法让一个count列为每个 userId 单独递增,并且可以将其范围限制为0-29

如果您使用事务,会锁定您读取的行吗?

postgresql index constraint

7
推荐指数
2
解决办法
6005
查看次数