如果我unique对某个字段进行约束,是否还需要在该字段上创建索引以获得可扩展的插入时间?或者这是为我完成的(即使它使用的索引不可公开访问?)
具体来说,我正在使用 Apache Derby 进行原型设计,尽管我可能会在半不久的将来将其移至 MySQL。我也希望 SQL 标准中可能有一些关于这一点的内容。
我永远不需要按这个字段搜索,所以我宁愿不做一个无用的索引。但我宁愿有一个无用的索引,也不愿有一个O(n)插入时间。
让我们以表 peoples 为例,它只有 2 个字段:id 和 data(json)。
SELECT data FROM peoples ;
{"name": "Adam","pos":"DBA","age":22 }
{"name": "Alice","pos":"Security","age":33 }
{"name": "Bob","pos":"Manager","age":42 }
Run Code Online (Sandbox Code Playgroud)
我想为“pos”字段创建约束,它必须是唯一的。我在互联网上搜索了 JSON 约束,但没有结果。
我该如何处理这个问题?
我有一个带有唯一键的表,其中包含一NVARCHAR(50)列(正确与否,但在那里)。因此,当尝试插入?c或C(与插入顺序无关)时,由于整理问题,它会在第二次插入时中断。这是错误:
(受影响的 1 行)消息 2601,级别 14,状态 1,第 16 行无法在具有唯一索引“IX_TestT”的对象“dbo.testT”中插入重复的关键行。重复的键值为 (C)。
选择退货:
数据库默认排序规则是Latin1_General_CI_AS. 花了一些时间寻找如何解决它,而不会对现有结构进行太多更改,但找不到开始工作的方法。尝试了不同的排序规则和组合,一切都失败了。阅读(这里和这里)关于字符扩展等,仍然卡住了。这是我用来复制问题的示例代码,请随时修改并推荐任何有助于解决此问题的内容。
CREATE TABLE testT (
[Default_Collation] [NVARCHAR] (50) COLLATE DATABASE_DEFAULT,
[Latin1_General_CI_AS] [NVARCHAR] (50) COLLATE Latin1_General_CI_AS,
[Latin1_General_CI_AI] [NVARCHAR] (50) COLLATE Latin1_General_CI_AI,
[SQL_Collation] [NVARCHAR] (50) COLLATE SQL_Latin1_General_CP1_CI_AS);
CREATE UNIQUE CLUSTERED INDEX [IX_TestT] ON [dbo].[testT] ([Default_Collation])
ON [PRIMARY]
GO
INSERT INTO testT
SELECT N'?c', --COLLATE Latin1_General_CI_AS
N'?c', --COLLATE Latin1_General_CI_AS
N'?c', --COLLATE Latin1_General_CI_AS
N'?c' --COLLATE Latin1_General_CI_AS
INSERT INTO testT
SELECT …Run Code Online (Sandbox Code Playgroud) sql-server collation t-sql sql-server-2014 unique-constraint
我有几个表,其中的记录可以用几个广泛的业务领域唯一标识。过去,我将这些字段用作 PK,并考虑到以下好处:
但是,我听说过一个创建合成IDENTITY INTPK的案例,而是使用单独的UNIQUE约束来强制执行业务密钥。优点是狭窄的 PK 使得二级索引小得多。
如果一个表有没有比PK其他指标,我看不出有任何理由赞成第二种方法,虽然在一个大表它可能是最好的假设,指数可能在未来是必要的,因此,有利于在狭窄合成PK . 我是否缺少任何考虑?
顺便说一下,我并不是反对在数据仓库中使用合成键,我只是对何时使用单一的宽泛 PK 以及何时使用窄 PK 加上宽泛的 UK 感兴趣。
看看下面的sqlfiddle:http ://sqlfiddle.com/#!2/dacb5/1
CREATE TABLE contacts
(
id int auto_increment primary key,
name varchar(20),
network_id int,
network_contact_id int
);
INSERT INTO contacts
(name, network_id, network_contact_id)
VALUES
('John', 4, 10),
('Alex', 4, 11),
('Bob', 4, 12),
('Jeff', 4, 45),
('Bill', 7, 11),
('Walter', 7, 45),
('Jessie', 7, 360) ;
Run Code Online (Sandbox Code Playgroud)
我有一个基本的联系人表。该network_id和network_contact_id字段包含链接到其他表的ID号码。
我希望能够运行INSERT IGNORE查询,此表,但我想用的组合network_id,并network_contact_id作为唯一键来匹配。
因此,举例来说,如果我试图插入一个接触的是有network_id = 4和network_contact_id = 12中,INSERT IGNORE查询将看到该条目已经存在,而忽略被抛出任何错误。
所以基本上,network_id不是唯一的。network_contact_id不是唯一的。但两者的结合是独一无二的。我该如何设置?我是否必须有一个其他字段作为其他两个字段的串联值?或者有没有办法为此表设置密钥,以便它可以满足我的需要?
我想向我的生产数据库之一中的 DB 字段添加唯一约束。不幸的是,以下语句阻塞了:
ALTER TABLE package ADD CONSTRAINT unique_package_id UNIQUE (package_id);
Run Code Online (Sandbox Code Playgroud)
注意:在需要在不长时间阻塞表更新的情况下添加新约束的情况下,使用现有索引添加约束会很有帮助。为此,请使用 CREATE INDEX CONCURRENTLY 创建索引,然后使用此语法将其安装为官方约束。请参阅下面的示例。
我试过:
CREATE UNIQUE INDEX CONCURRENTLY package_tmp_id_idx ON answer (package_id);
Run Code Online (Sandbox Code Playgroud)
其次是:
prod_db=> ALTER TABLE package ADD CONSTRAINT
unique_package_id UNIQUE (package) USING INDEX package_tmp_id_idx;
Run Code Online (Sandbox Code Playgroud)
哪个失败了:
ERROR: syntax error at or near "package_tmp_id_idx"
LINE 1: ...T unique_package_id UNIQUE (answer_id) USING INDEX package_tmp_id_idx...
^
Run Code Online (Sandbox Code Playgroud)
我试过使用语法,但无法让它工作。
使用现有 UNIQUE 索引创建 UNIQUE 约束的正确语法是什么?
是否可以将多个字段作为范围键?
假设我有一个表,其中每一行都由 <A,B,C>
-------------------------------
A | B | C | D | E |
-------------------------------
Run Code Online (Sandbox Code Playgroud)
A主hash键在哪里
我想B和C作为主range键。
如何在 DynamoDB 中将超过 2 个字段作为主键?
我有两张桌子;一种用于存储thing,一种用于存储relationship两个thing对象之间的。
认为:
AB == BA. 存储两者都是多余的A != B. 一个thing与自身的关系是没有用的AB是昂贵但幂等的CREATE TABLE thing (
id INT PRIMARY KEY
);
CREATE TABLE relationships (
thing_one INT REFERENCES thing(id),
thing_two INT REFERENCES thing(id),
relationship INT NOT NULL,
PRIMARY KEY (thing_one, thing_two),
CHECK (thing_one != thing_two)
);
Run Code Online (Sandbox Code Playgroud)
为了确保我们不会INSERT AB和BA:
CREATE UNIQUE INDEX unique_pair_ix
ON relationships (
least(thing_one, thing_two),
greatest(thing_one, thing_two)
);
Run Code Online (Sandbox Code Playgroud)
是否有比示例更好或更有效的方法来存储/建模此数据? …
我有一张代表电影的表。这些字段是:
id (PK), title, genre, runtime, released_in, tags, origin, downloads。
我的数据库不会被重复的行污染,所以我想强制执行唯一性。问题是不同的电影可能有相同的标题,甚至除了tags和之外的相同字段downloads。如何实现唯一性?
我想到了两种方法:
downloads主键以外的所有字段。downloads因为它是 JSON,所以我一直在外面,它可能会影响性能。id作为主键保留,但为所有其他列添加唯一约束(再次除外downloads)。我读了这个非常相似的问题,但我不太明白我该怎么做。目前该表与任何其他表都没有关系,但将来可能会。
目前我的记录略少于 20,000 条,但我预计这个数字会增长。我不知道这是否与问题有些相关。
编辑:我修改了架构,这里是我将如何创建表:
CREATE TABLE movies (
id serial PRIMARY KEY,
title text NOT NULL,
runtime smallint NOT NULL CHECK (runtime >= 0),
released_in smallint NOT NULL CHECK (released_in > 0),
genres text[] NOT NULL default ARRAY[]::text[],
tags text[] NOT NULL default ARRAY[]::text[],
origin text[] NOT NULL …Run Code Online (Sandbox Code Playgroud) 在我的数据库中,我有一个带有两个索引的表。出于数据完整性原因,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) primary-key ×3
index ×2
index-tuning ×2
mysql ×2
postgresql ×2
sql-server ×2
collation ×1
constraint ×1
derby ×1
dynamodb ×1
insert ×1
json ×1
t-sql ×1