我在Postgres DB中有两个名为players
&的表matches
,如下所示:
CREATE TABLE players (
name text NOT NULL,
id serial PRIMARY KEY
);
CREATE TABLE matches (
winner int REFERENCES players (id),
loser int REFERENCES players (id),
-- to prevent rematch btw players
CONSTRAINT unique_matches
PRIMARY KEY (winner, loser)
);
如何确保仅将(winner, loser)
或的唯一组合(loser, winner)
用于matches
主键,以便matches
表不允许插入以下内容:
INSERT INTO matches VALUES (2, 1);
如果已经有包含VALUES (1, 2)
like的行:
winner | loser
--------+-------
1 | 2
目的是避免相同玩家之间的比赛进入。
创建一个唯一索引:
CREATE UNIQUE INDEX matches_uni_idx ON matches
(greatest(winner, loser), least(winner, loser));
不能是UNIQUE
或PRIMARY KEY
约束,因为它们仅适用于列,不适用于表达式。
您可以添加一个serial
列作为PK,但是只有两个整数列,原始PK也非常有效(请参阅注释)。它会NOT NULL
自动使两列都变为。(否则,添加NOT NULL
约束。)
您还可以添加CHECK
约束,以排除玩家与自己对战:
CHECK (winner <> loser)
提示:要搜索一对ID(您不知道谁赢了),请在查询中构建相同的表达式,然后使用索引:
SELECT * FROM matches
WHERE greatest(winner, loser) = 3 -- the greater value, obviously
AND least(winner, loser) = 1;
如果您处理未知参数,但您不知道哪个更大,请提前:
WITH input AS (SELECT $id1 AS _id1, $id2 AS _id2) -- input once
SELECT * FROM matches, input
WHERE greatest(winner, loser) = greatest(_id1, _id2)
AND least(winner, loser) = least(_id1, _id2);
CTE包装器只是为了方便,只输入一次参数,在某些情况下是不必要的。
我正在运行Postgres 9.5,并试图基于3个字段创建一个唯一的约束。我遇到的问题是,其中两列可以为NULL,因此这些字段为NULL的行不会违反唯一约束。我的目标是将其作为一个约束,因为我正在尝试更新冲突(UPSERT)。 桌子的结构是这样的 我在这里发现了另一个问题,我可以按照以下方式做一些事情 我不确定在where子句中有两个字段时这是否真的有效,但如何在冲突时调用这个唯一索引呢? 或者我
如何实现数据库中没有两个相同的记录,而这三列的值组合在一起是相同的?
问题内容: 我有三张桌子- 我想确保当它们自然连接时,product_id +文件名是唯一的。到目前为止,我拥有的最佳解决方案是将文件名添加到product_attachment表中,但是我想知道是否有避免这种情况的方法。 问题答案: 如果文件名列不是唯一的,则可以在表上添加自定义约束。请注意,这将在每次插入和更新时执行以下查询,这并不是理想的性能。
我正在制作一个React应用程序,允许你制作一个列表并保存它,但React一直在警告我,我的元素没有唯一的关键道具(元素列表/列表表单)。如何为用户创建的元素创建唯一的关键道具?下面是我的代码 我的超文本标记语言:
问题内容: 这个问题需要一些假设的背景。让我们考虑一个有列的表,,,,使用MySQL作为RDBMS。由于如果给定的某个人的名字和出生日期与另一个人相同,那么根据定义,他们就是同一个人(除非有两个巧合,即我们两个人分别于1809年2月12日出生,他们叫亚伯拉罕·林肯),所以我们将上的唯一键,这意味着“不要将同一个人存储两次”。现在考虑以下数据: 如果现在尝试运行以下语句,则该语句应该并且将失败: 如
我有一个JPA实体的类层次结构,基类是定义了一个ID的MappedSuperclass。我试图在子类中使用复合键,但这似乎不起作用