我有两个 SQL 表:用户和客户。
users 表中的每一行在clients 表中都有一组clients,由users 表id字段和clients 表user_id字段链接。
用户表有一个username唯一的字段。
客户表有一个user_id字段 ANDclientname字段,它们一起是唯一的(即clientnames可以存在多次,但必须有不同的user_ids)
我的问题是:如何添加强制username用户表中的clientname字段和客户表中的字段之间的唯一性的规则?甚至有可能吗?
即 nousername可以与 a 相同clientname,noclientname可以与 a 相同username。
检查我系统上某些软件使用的相当关键的数据库,我发现其中一个表在列上有一个主键Id,其中Id使用checksum(newid()). 这让我感到不安;在newids的保证是独一无二的,但通过将校验和(一个32位整数,大概是出于性能的原因?),你有一些机会,你在表中得到的碰撞(用1M行,我把那大约 1:4000 的机会,对我来说太多了)。
所以:
checksum(newid())给出一个已经存在的主键,会发生什么?我的桌子会炸吗?插入是否会失败并将其留给应用程序如何处理?我发现自己所处的情况是由于某种原因我将错误的数据输入到数据库中。我想通过UNIQUE INDEX在UFID字段上添加到用户表 a 来保持数据完整性。
自然地,我生成了一个脚本,以非破坏性的方式删除任何重复的记录:
update [user]
set UFID = UFID + '_dup_removal'
where ufid in (
select ufid
from [user]
group by ufid
having count(ufid) > 1
)
Run Code Online (Sandbox Code Playgroud)
然后我发现该字段无法在UNIQUE INDEX.
那么现在获得结果的最佳方法是什么,我有用户表和数据并添加了UNIQUE INDEX.
注意:它应该以允许轻松逆转的方式完成。
这是一个药品目录表。有些有药品品牌,有些是通用的(即他们永远不会有品牌信息)
CREATE TABLE medicine (
id serial PRIMARY KEY,
name text NOT NULL,
brand_id integer
CONSTRAINT brand_fk FOREIGN KEY (brand_id) REFERENCES brand (id)
);
CREATE TABLE brand (
id serial PRIMARY KEY,
name text NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
对于存储仿制药,例如abc& xyz,有两种选择:
使用 NULL 作为外键 brand_id
INSERT INTO medicine (name, brand_id) VALUES ('abc', NULL)
INSERT INTO medicine (name, brand_id) VALUES ('xyz', NULL)
在品牌名称中仅插入 1 个空字符串,并将其用于所有仿制药的 Brand_id
INSERT INTO brand (id, name) VALUES (1, '')
INSERT INTO medicine (name, brand_id) VALUES …
我在 Postgres 数据库中有一个表,其中col1和col2是指同一列的外键。我只想要 的唯一组合(col1, col2),即如果(1,2)输入则(2,1)应该被拒绝。我怎样才能做到这一点?
我的表定义:
CREATE TABLE mytable (
id serial primary key,
col1 int NOT NULL,
col2 int NOT NULL,
unique (col1, col2)
)
Run Code Online (Sandbox Code Playgroud) 我有一个Engagement带有四个字段的 Access 表:
Emp_id, Year, Week, Act_id
Run Code Online (Sandbox Code Playgroud)
它记录员工何时/曾参与某项活动。每个字段都是数字,每个字段都构成复合主键的一部分。应用程序的语义是每个条目(每个Emp_id- Year- Week-Act_id组合)必须是唯一的。也就是说,虽然员工通常会有不同的年周和不同的活动,但员工有时可以在不同的年周从事相同的活动,甚至可以在同一年的周从事不同的活动。不允许有空值。一切正常。
现在我需要扩展/修改语义以允许与任何给定员工活动相关的未知——或更恰当地说,未披露——年-周值。当然,尝试输入带有空的 Year-Week 的行会导致“索引或主键不能包含 Null 值”。所以我需要改变表格设计。
我尝试过的一件事是通过在“索引”窗口中关闭“主”(并保持“唯一”状态)将主键索引转换为非主索引。这正确地防止了年-周值非空的重复记录——但它允许年-周为空的重复记录。
例如,使用上述非主、唯一索引,允许以下数据:
Emp_id Year Week Act_id
7 2014 12 31 } Same activity,
7 2015 22 31 } different dates.
7 2015 33 32
7 2015 40 33 } Same dates,
7 2015 40 34 } different activities.
7 2016 2 36
7 38 } Different activities,
7 39 } undisclosed dates.
Run Code Online (Sandbox Code Playgroud)
随后不允许添加以下任何内容:
Emp_id …Run Code Online (Sandbox Code Playgroud) 我想将 URL 存储在数据库列中,并强制执行值必须唯一的约束。不幸的是,MySQL 对索引键的长度有限制,这意味着只检查 URL 的前 X 个字符的唯一性。因此,我遇到了误报,其中两个不同的 URL 触发了约束集成违规,因为前 X 个字符恰好是相同的。
有没有办法在 VARCHAR 列上强制执行唯一性而对其长度没有任何限制?
例如,是否可以在前 X 个字符上创建非唯一索引,然后在其余字符相同时触发块 INSERT?
SQL Server 有一个带有可选唯一列的怪癖:null一个表中不能有多个。
例如:
create table employees (
id int identity(1,1) primary key,
givenname nvarchar(24) not null,
familyname varchar(24) not null,
tfn char(9) unique -- optional, but unique
);
Run Code Online (Sandbox Code Playgroud)
(在澳大利亚,我们有一个纳税人独有的税号)。
以下是一种解决方法:
create table employees (
id int identity(1,1) primary key,
givenname nvarchar(24) not null,
familyname varchar(24) not null,
tfn char(9)
);
CREATE UNIQUE NONCLUSTERED INDEX uq_employees_tfn ON employees(tfn)
WHERE tfn IS NOT NULL;
Run Code Online (Sandbox Code Playgroud)
是否可以命名一个唯一的约束并给它上述条件是一种类似于第一个示例的方式?也就是说,是否可以在列定义中包含更复杂的约束?
我在 RDS Aurora 上的 PostgreSQL 9.6.3 上看到了一些非常奇怪的行为。
我从某些查询中得到重复的结果:
=> select count(id) from foos where id = 'deadbeef';
count
-------
2
(1 row)
=> select id from foos where id = 'deadbeef';
id
--------------------------
deadbeef
deadbeef
(2 rows)
=> select id, created_at from foos where id = 'deadbeef';
id | created_at
--------------------------+----------------------------
deadbeef | 2018-01-01 10:00:00.000000
(1 row)
Run Code Online (Sandbox Code Playgroud)
(id 值、时间戳和表名已被混淆)
我在这张桌子或任何其他桌子上都没有桌子继承。
这似乎只影响恰好命中foos表上一个索引的查询。
因为这似乎与单个索引隔离,我想运行REINDEX 可能会解决这个问题。
但是,我不知道有多少索引表现出这种行为。
例如,这是通过不同索引对同一记录的类似行为:
=> select bar from foos where bar = 'qux';
bar
----------------------------------------- …Run Code Online (Sandbox Code Playgroud) foo在具有两列(id和)的表中seq,我想为seq具有任意 . 的所有记录添加+1 seq > 4738。计划是在seq=4739所有seq > 4738记录移动+1 后立即插入一条新记录。
这是桌子。
CREATE TABLE foo
(
id uuid NOT NULL,
seq integer NOT NULL,
CONSTRAINT seq_key UNIQUE (seq)
)
CREATE UNIQUE INDEX idx_id
ON foo
USING btree
(id);
CREATE UNIQUE INDEX idx_seq
ON foo
USING btree
(seq);
Run Code Online (Sandbox Code Playgroud)
我尝试通过以下查询实现 +1 转变。请注意,我使用子查询尝试> 4738按降序更新记录(即假设 max seq=10000,则首先更新最后一条记录(10000->10001),然后更新倒数第二条记录(seq=10000此时不存在,seq=9999-> seq=10000(没有违反约束),然后是 9998 -> 9999,...以避免在任何时候发生唯一的约束违反。但是,这假设更新查询是顺序执行的,而这似乎并不是发生的情况。
跑步时
UPDATE foo SET seq=anon_1.new_seq FROM …Run Code Online (Sandbox Code Playgroud) postgresql ×4
sql-server ×3
mysql ×2
null ×2
primary-key ×2
amazon-rds ×1
aurora ×1
constraint ×1
foreign-key ×1
index ×1
innodb ×1
ms-access ×1
subquery ×1
update ×1
varchar ×1