我在这里是一个SQL新手,在创建表时我正在玩弄UNIQUE约束.我显然没有理解一些基本的东西,所以请原谅我.

假设我想强制要求用户必须具有唯一的用户名和唯一的邮箱.换句话说,我不希望两个用户拥有相同的用户名,也不希望两个用户拥有相同的邮箱.

我有一个User表的定义如下:

CREATE TABLE User 
(
    id int,
    username nvarchar(20),
    email nvarchar(20),
    PRIMARY KEY (id),
    UNIQUE(username, email)
);

使用上面定义的UNIQUE约束,似乎以下插入将会成功:

INSERT INTO User (id, username, email)
VALUES
    (1, 'aaron', 'aaron-email'),
    (2, 'aaron', 'aaron-email-2'),
    (3, 'bob', 'bob-email'),
    (4, 'bob', 'aaron-email');

它强制用户名和邮箱的组合在中必须是唯一的,才能使约束生效.然而,这显然没有意义,因为现在我们有多个用户使用相同的用户名,多个用户使用相同的邮箱.

我们如何强制用户名和邮箱列必须是唯一的?

推荐答案

语法UNIQUE(username, email)假定列的组合必须是唯一的.

您可以添加多个单独的唯一约束,以对每列强制执行唯一条件.您使用的语法允许使用多个语句:

CREATE TABLE User (
    id int,
    username nvarchar(20),
    email nvarchar(20),
    PRIMARY KEY (id),
    UNIQUE(username),
    UNIQUE(email)
);

INSERT INTO User (id, username, email)
VALUES
    (1, 'aaron', 'aaron-email'),
    (2, 'aaron', 'aaron-email-2'),
    (3, 'bob', 'bob-email'),
    (4, 'bob', 'aaron-email')
;

Duplicate entry 'aaron' for key 'User.username'

示例:https://dbfiddle.uk/07o7fr-C

附注:使用另一种(更简单的)语法也可以获得相同的结果,方法是向列本身添加UNIQUE个限定符,例如:

CREATE TABLE User (
    id int,
    username nvarchar(20) UNIQUE,
    email nvarchar(20) UNIQUE,
    PRIMARY KEY (id)
);

Sql相关问答推荐

SQL—如何根据2列填写缺失的值

在请求结束之前,PostgreSQL不会考虑使用中的删除

为什么在这种情况下我不能使用LAG函数?

SQL:如何取上一年的平均值?

PostgreSQL抽奖查询

属于(日期)范围类型及其交集的总权重​

无法访问级联删除导致的触发器中已删除的外键记录

其中使用表名作为;行值;记录?

在Postgres,什么是;.USSTZ;在';YYYY-MM-DD;T;HH24:MI:SS.USSTZ';?

如何在 SNOSQL 中执行反连接(或 where 子句过滤)以查找字段不包含另一个表中的值的行?

使用 union 的有序结果获取行数

JSON_VALUE 不适用于提取的 json 中的嵌套路径

具有分组条件的不同计数 (DAX)

识别SQL Server中的重复数字

按所选的值将记录分组到不同的列中

REGEXP_SUBSTR使用方法

在 MS Access 中连接相关记录

如何根据另一列对行值进行分组?

为什么这是 AND,OR with NULL 的真值表?

如何刷新在视图之上创建的表