无论列如何,都是唯一的行。

huangapple go评论56阅读模式
英文:

Unique row no matter the column

问题

可以通过创建一个唯一索引或约束来确保整行的唯一性,而不管列中的值是什么。

例如,在SQL中,你可以使用以下代码来创建一个唯一约束:

ALTER TABLE your_table_name
ADD CONSTRAINT unique_row_constraint UNIQUE (a, b);

这将确保在列 a 和列 b 中的组合值是唯一的,如果尝试插入重复的组合值,将会引发错误。

英文:

Is there a way to make an entire row unique no matter what value the column is in?

So, if 1 is in col a, and 2 is in col b, then if you were to insert 2 into col a and 1 into col b an error would be thrown.

+---+---+
| a | b |
+---+---+
| 1 | 2 |
| 2 | 1 | <- Would throw error on insert since this already exists above
+---+---+

答案1

得分: 3

在表格中定义两个虚拟生成列,一个存储最小值,另一个存储最大值,并对它们设置唯一约束:

CREATE TABLE tablename (
  a INT NOT NULL, 
  b INT NOT NULL,
  x INT GENERATED ALWAYS AS (LEAST(a, b)),
  y INT GENERATED ALWAYS AS (GREATEST(a, b)),
  UNIQUE (x, y)
);

针对 MySQL 8.0+,可以使用以下方式:

CREATE TABLE tablename (
  a INT NOT NULL, 
  b INT NOT NULL,
  UNIQUE ((LEAST(a, b)), (GREATEST(a, b))) -- 不要忘记括号
);

示例演示链接:
示例演示链接1
示例演示链接2

英文:

Define 2 virtual generated columns with the least and the greatest of the 2 values and set a unique constraint on them:

CREATE TABLE tablename (
  a INT NOT NULL, 
  b INT NOT NULL,
  x INT GENERATED ALWAYS AS (LEAST(a, b)),
  y INT GENERATED ALWAYS AS (GREATEST(a, b)),
  UNIQUE (x, y)
);

See the demo.<br/>

Or, for MySql 8.0+:

CREATE TABLE tablename (
  a INT NOT NULL, 
  b INT NOT NULL,
  UNIQUE ((LEAST(a, b)), (GREATEST(a, b))) -- don&#39;t miss the parentheses 
);

See the demo.<br/>

答案2

得分: 2

你可以使用触发器来实现这一点。但我想不出如何使用UNIQUE KEY约束来很好地完成这个任务。

如果你改变存储值的方式,使它们位于单独表的多行中,会更容易实现唯一性的强制执行。


如果你想表示相关的项目:

CREATE TABLE item_group (
  group_id INT AUTO_INCREMENT PRIMARY KEY
);

CREATE TABLE item_group_members (
  group_id INT NOT NULL,
  member_id INT NOT NULL,
  PRIMARY KEY (group_id, member_id)
);

INSERT INTO item_group_members VALUES (1, 1), (1, 2);

如果你需要每个成员只出现在一个组中:

ALTER TABLE item_group_members ADD UNIQUE KEY (member_id);
英文:

You could enforce it with a trigger. But I can't think of a good way to do this with a UNIQUE KEY constraint.

It would be easier if you change the way you store values, so they are in a single column, on multiple rows of an additional table. Then you could easy use UNIQUE KEY to enforce uniqueness.


If you're trying to represent related items:

CREATE TABLE item_group (
  group_id INT AUTO_INCREMENT PRIMARY KEY
);

CREATE TABLE item_group_members (
  group_id INT NOT NULL,
  member_id INT NOT NULL,
  PRIMARY KEY (group_id, member_id)
);

INSERT INTO item_group_members VALUES (1, 1), (1, 2);

If you need each member to appear in only one group:

ALTER TABLE item_group_members ADD UNIQUE KEY (member_id);

答案3

得分: 2

在第三列中添加 hash VARCHAR NOT NULL UNIQUE,在这里放置排序后的哈希值。对其进行排序,以确保无论值的顺序如何,都能获得相同的哈希值:1, 2, 2, 3 将与 3, 2, 1, 2 具有相同的哈希值。

例如,在PHP中:

sort($columns);
$hash = md5(implode('|', $columns));

$columns['hash'] = $hash;

$sql = "INSERT INTO my_tbl VALUES (?, ?, ?)";
$stmt = $pdo->prepare($sql);
$stmt->execute($columns);
英文:

Have third column hash VARCHAR NOT NULL UNIQUE, where you would place sorted hash.
Sort it to always get same hash for values, no matter of their order: 1, 2, 2, 3 will have same hash as 3, 2, 1, 2

E.g. in PHP:

sort($columns);
$hash = md5(implode(&#39;|&#39;, $columns));

$columns[&#39;hash&#39;] = $hash;

$sql = &quot;INSERT INTO my_tbl VALUES (?, ?, ?)&quot;;
$stmt = $pdo-&gt;prepare($sql);
$stmt-&gt;execute($columns);

答案4

得分: 1

以下是翻译的内容:

在插入数据时,使用类似以下的 before-insert 触发器来检查重复项:

if (exists(
  select 1
  from t
  where (least(a, b), greatest(a, b)) = (least(new.a, new.b), greatest(new.a, new.b))
)) then
  signal sqlstate value '45000' set message_text = '不能插入重复的数据对';
end if;

一个更简单的解决方案是在表上添加 CHECK 约束以及 UNIQUE 约束:

alter table t add constraint unique (a, b)
alter table t add constraint check (a < b)

现在,必须存储数据以满足 a < b。如果尝试插入 2, 1,检查将失败。如果插入 1, 2,唯一约束将失败。

英文:

When inserting data check for duplicates using before-insert trigger like so:

if (exists(
  select 1
  from t
  where (least(a, b), greatest(a, b)) = (least(new.a, new.b), greatest(new.a, new.b))
)) then
  signal sqlstate value &#39;45000&#39; set message_text = &#39;cannot insert duplicate pair&#39;;
end if;

A simpler solution is to add CHECK constraint along with UNIQUE on your table:

alter table t add constraint unique (a, b)
alter table t add constraint check (a &lt; b)

Now, you must store data so that a &lt; b. If you try to insert 2, 1 the check fails. If you insert 1, 2 the unique constraint fails.

DB<>Fiddle

huangapple
  • 本文由 发表于 2023年5月29日 21:31:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76357821.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定