标签: unique-constraint

当表上有两个唯一索引且一个索引中的所有列也在另一个索引中时,是否会造成性能损失?

在我的数据库中,我有一个带有两个索引的表。出于数据完整性原因,a、b 列上有一个唯一索引 #1。我有另一个索引 #2,其中包含 c、a、b 列,用于性能原因。我注意到这个索引#2 也是唯一的。

在我看来,索引#2 的唯一性似乎是多余的,因为索引#2 中不可能有重复值,而索引#1 中也不可能有重复值。我很想更改索引 #2,使其不再唯一,因为我想象数据库引擎可能会对索引 #2 中的 c、a、b 执行第二次检查,以确保每次插入行时这些列的唯一性,从而导致即使永远不会有重复的值,也会影响性能。它是否正确?

有没有办法删除 a、b 上的索引 #1 并保留 c、a、b 上的索引 #2,但仍然只对 a、b 列施加唯一约束,而不维护两个单独的索引?这将允许我只有一个索引包含所有三列,但仍然对 a、b 强制执行数据完整性约束。为了提高性能,我不需要在 a、b 上建立索引,因为我所有的选择查询都在 where 子句中包含 c 列。这是否是唯一约束而不是索引的用例?我认为数据库引擎基本上以相同的方式对待这两个构造(请参阅这篇文章:何时应该使用唯一约束而不是唯一索引?)。

请记住,索引不是冗余的,但索引的“唯一性”是冗余的。看起来让索引 #2 变得不唯一是理所当然的。但这会带来任何实际的性能提升吗?即使索引 #1 中的列完全包含在索引 #2 中,数据库是否检查两个索引的唯一性?

一些答案询问了用于从此表中选择数据的示例查询。以下是最常见的:

Select [some other columns] from table where c=1 and a=2
Select [some other columns] from table where c=1
Select [some other columns] from table where c=1 and a=2 and b=3
Run Code Online (Sandbox Code Playgroud)

这些查询通常包括选择不在任何索引中的许多其他列。

我们通常不会运行这样的查询:

Select [stuff] from table …
Run Code Online (Sandbox Code Playgroud)

sql-server index-tuning unique-constraint

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

大型 VARCHAR 的唯一约束 - PostgreSQL

我有一个列定义如下:

data_url character varying(32768) NOT NULL
Run Code Online (Sandbox Code Playgroud)

和该列的 UNIQUE 约束:

CONSTRAINT unique_data_url UNIQUE (data_url)
Run Code Online (Sandbox Code Playgroud)

当一个大对象被插入到表中时,会出现以下错误信息:

ERROR:  index row requires 32584 bytes, maximum size is 8191
Run Code Online (Sandbox Code Playgroud)

如何设置 PostgreSQL 以便能够索引大于 8191 个字符的对象?空间和速度都不是问题。它是一个很少更改的表,最多有数百行。

环境:PostgreSQL 9.3.6,Fedora 20 x64

postgresql index varchar postgresql-9.3 unique-constraint

8
推荐指数
1
解决办法
4884
查看次数

如何命名表变量函数唯一约束?

我正在重命名一些独特的约束以匹配我们的数据库对象命名约定。奇怪的是,有几个多行表值函数返回的表具有唯一约束,如下所示:

CREATE FUNCTION [dbo].[fn_name] (...)
RETURNS @Result 
TABLE
(
    ID BIGINT PRIMARY KEY,
    ...
    RowNum BIGINT UNIQUE 
)
BEGIN
    ...
    RETURN
END
GO
Run Code Online (Sandbox Code Playgroud)

我尝试这样命名它,但不起作用:

CREATE FUNCTION [dbo].[fn_name] (...)
RETURNS @Result 
TABLE
(
    ID BIGINT PRIMARY KEY,
    ...
    RowNum BIGINT
    ,CONSTRAINT UC_fn_name_RowNum UNIQUE([RowNum])  
)
BEGIN
    ...
    RETURN
END
GO
Run Code Online (Sandbox Code Playgroud)

当它是表变量函数定义的一部分时,是否可以设置唯一约束的名称?

t-sql sql-server-2012 set-returning-functions unique-constraint table-variable

8
推荐指数
1
解决办法
1216
查看次数

如何强制由两个外键组成的复合主键的唯一性到同一个表?

我有两张桌子:一张user桌子和一张friendship桌子。假设friendship表格如下所示:

friendship
------------
user_one_id
user_two_id
other_fields
Run Code Online (Sandbox Code Playgroud)

我需要强制执行和忽略ordering值组合的唯一性,因此:(user_one_id, user_two_id)

user_one_id | user_two_id
------------+------------
          1 |          2
          2 |          1  -- the DBMS should throw a unique constraint error when trying to insert a row like this one.
Run Code Online (Sandbox Code Playgroud)

另外重要的一点是,user_one_id代表发起friendship,并user_two_id代表收件人,所以我不能只是做了两个“小”的ID user_one_id

问题

有没有办法使用约束来做到这一点,还是应该以其他方式实现?

postgresql database-design primary-key unique-constraint

8
推荐指数
1
解决办法
1632
查看次数

尝试获取锁时发现死锁;尝试在 mysql 中重新启动事务

我有一个如下所示的表结构,这个表有 100 万条记录,并且与两个和三个表有 FK 关系,这些表的记录也以百万计。我需要对这个表进行批量插入,但出现错误Deadlock found when trying to get lock; try restarting transaction,无法找到是什么造成了问题?

CREATE TABLE tags (
 id int(10) unsigned NOT NULL AUTO_INCREMENT,
  tag varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
  created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  updated_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (id),
  UNIQUE KEY hashtag (tag)
 ) ENGINE=InnoDB AUTO_INCREMENT=657163 DEFAULT CHARSET=utf8mb4      COLLATE=utf8mb4_unicode_ci`
Run Code Online (Sandbox Code Playgroud)

我用来做批量插入的查询是

 INSERT INTO tags (tag) VALUES ('jatin'),('test') ON DUPLICATE KEY UPDATE tag = VALUES(tag);`
Run Code Online (Sandbox Code Playgroud)

我运行命令show engine innodb status,结果如下所示 …

mysql innodb foreign-key deadlock unique-constraint

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

选择主键:物种的科学名称或系统分配的数字标识符?

科学名称是公认的物种唯一标识符。但是,科学名称具有特殊字符,例如空格和点。它可以是一个很好的数据库唯一标识符还是应该分配/实现唯一的数字标识符?

如果是后者,是否有全球已知的数字标识符?或者应该为行分配自己的标识符?

database-design primary-key unique-constraint

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

什么时候应该在索引上使用 IGNORE_DUP_KEY 选项?

有人说最好制作您的查询以避免重复的键异常,但我不相信仅设置IGNORE_DUP_KEY = ON索引的性能更高。

我的目标是在尝试更新这些行之前,确保为一个或多个用户存在一行或一组行。我这样做,所以当我尝试使用如下所示的更新语句更新行时,没有行受到影响,这是因为[Count]谓词的部分不满足,而不是根本不存在的行(即[ID]不满足谓词的部分):

UPDATE [Inventory]
SET [Count] = [Count] + 1
WHERE [ID] = 3 
AND ([Count] + 1) <= @MaxInventory
Run Code Online (Sandbox Code Playgroud)

我可以运行EXISTS(SELECT 1 From [Inventory] WHERE [ID] = 3检查该单行,如果该行不存在,则仅插入该行。这只是避免了不必要的插入。如有必要,插入仍需处理并发事务,因此仍可能发生重复键异常。

我很好奇IGNORE_DUP_KEY在这种情况下是否只打开性能更好,而不是允许抛出和捕获错误。具体来说,我很好奇它是否与运行存在检查一样快或什至可能更快,只是尝试插入记录并让它忽略重复的键。

当我一次检查和初始化多个记录时,这变得更加重要。例如,如果我需要确保单个更新语句中存在数千个用户的记录,如果我只是预先运行该插入语句,让它忽略重复的键,那么逻辑会简单得多。避免重复会更复杂,因为我必须首先查询不存在记录的表,然后尝试仅添加这些记录(再次忽略重复键)。即使所有记录都存在,只是插入可能会更快。

我可以在中途遇到它并检查是否有任何记录丢失,例如使用左连接或COUNT比较,但是如果忽略重复键的插入速度更快,为什么还要麻烦呢?

使用IGNORE_DUP_KEY并尝试插入而不是提前检查行是否存在是个好主意吗?如果不是,为什么?

sql-server duplication unique-constraint sql-server-2019

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

从外键表中引用唯一索引有什么问题吗?

从外键表中引用唯一索引有什么问题吗?

使用 SQL Server 2008 R2

foreign-key sql-server-2008-r2 unique-constraint

6
推荐指数
1
解决办法
4455
查看次数

UNIQUE 索引键违规

我有一个带有 PK 和唯一非聚集索引的表,如下所示:

CREATE TABLE Table1
(
    Id INT IDENTITY(1,1) NOT NULL,
    Field1 VARCHAR(25) NOT NULL,
    Field2 VARCHAR(25) NULL,
 CONSTRAINT PK_Table1 PRIMARY KEY CLUSTERED (Id ASC)
)

CREATE UNIQUE NONCLUSTERED INDEX IX_Field1_Field2 ON Table1
(
    Field1 ASC,
    Field2 ASC
)
WITH
    (
        PAD_INDEX = OFF,
        STATISTICS_NORECOMPUTE = OFF,
        SORT_IN_TEMPDB = OFF,
        IGNORE_DUP_KEY = OFF,
        DROP_EXISTING = OFF,
        ONLINE = OFF,
        ALLOW_ROW_LOCKS = ON,
        ALLOW_PAGE_LOCKS = ON
    )
Run Code Online (Sandbox Code Playgroud)

我有 2 个工作,我发现它们的执行时间相互重叠。它们都将相同的内容包含在INSERT此表中,并且最后开始的作业经常失败,因为它尝试将记录插入到Table1具有重复索引键值的中。

INSERT Table1
SELECT Field1, Field2
FROM …
Run Code Online (Sandbox Code Playgroud)

sql-server-2008-r2 locking unique-constraint

6
推荐指数
1
解决办法
2032
查看次数

在插入之前总是检查选择?

如果我INSERT只在主键尚不存在时才想要一行,INSERT直接执行并在重复的情况下忽略错误是否更有效/更简单,还是应该始终先运行SELECT以检查它是否已经存在?

mysql insert unique-constraint

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