在我的数据库中,我有一个带有两个索引的表。出于数据完整性原因,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) 我有一个列定义如下:
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)
当一个大对象被插入到表中时,会出现以下错误信息:
Run Code Online (Sandbox Code Playgroud)ERROR: index row requires 32584 bytes, maximum size is 8191
如何设置 PostgreSQL 以便能够索引大于 8191 个字符的对象?空间和速度都不是问题。它是一个很少更改的表,最多有数百行。
环境:PostgreSQL 9.3.6,Fedora 20 x64
我正在重命名一些独特的约束以匹配我们的数据库对象命名约定。奇怪的是,有几个多行表值函数返回的表具有唯一约束,如下所示:
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
我有两张桌子:一张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。
问题
有没有办法使用约束来做到这一点,还是应该以其他方式实现?
我有一个如下所示的表结构,这个表有 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,结果如下所示 …
科学名称是公认的物种唯一标识符。但是,科学名称具有特殊字符,例如空格和点。它可以是一个很好的数据库唯一标识符还是应该分配/实现唯一的数字标识符?
如果是后者,是否有全球已知的数字标识符?或者应该为行分配自己的标识符?
有人说最好制作您的查询以避免重复的键异常,但我不相信仅设置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 2008 R2
我有一个带有 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) 如果我INSERT只在主键尚不存在时才想要一行,INSERT直接执行并在重复的情况下忽略错误是否更有效/更简单,还是应该始终先运行SELECT以检查它是否已经存在?
foreign-key ×2
mysql ×2
postgresql ×2
primary-key ×2
sql-server ×2
deadlock ×1
duplication ×1
index ×1
index-tuning ×1
innodb ×1
insert ×1
locking ×1
t-sql ×1
varchar ×1