具有空值的 sqlite3 复合唯一约束
sqlite3 composite unique contraint with null values
如何设置可以正确处理 sqlite 中的空值的复合唯一约束?这可能更好地用例子来表达:
CREATE TABLE people (
id INTEGER PRIMARY KEY,
first_name TEXT NOT NULL,
last_name TEXT NOT NULL,
suffix TEXT,
UNIQUE (first_name, last_name, suffix)
);
当多次输入带有后缀的人时,约束会按预期工作。
-- Last insert is denied
INSERT INTO people (first_name, last_name, suffix)
VALUES
('Joe', 'Dirt', 'Sr'),
('Joe', 'Dirt', 'Jr'),
('Joe', 'Dirt', 'Sr');
但是,当一个没有后缀的人被多次插入时,唯一约束是不适应的。
-- Both are permitted
INSERT INTO people (first_name, last_name)
VALUES
('Chris', 'Farley'),
('Chris', 'Farley');
我知道 sqlite 将 null 值视为相互独立的,但是有没有正确的方法来解决这个问题?
如有任何帮助,我们将不胜感激。谢谢!
只有当后缀为 null 时,您才能为 first_name
和 last_name
创建唯一的 partial index
:
CREATE UNIQUE INDEX idx_people ON people(first_name, last_name)
WHERE suffix IS NULL;
查看简化版 demo.
如果你的 SQLite 版本是 3.31.0+,你可以创建一个生成的列,当 suffix
是 null
时,returns 一个空字符串,并在唯一约束中使用它而不是 suffix
:
CREATE TABLE people (
id INTEGER PRIMARY KEY,
first_name TEXT NOT NULL,
last_name TEXT NOT NULL,
suffix TEXT,
str_suffix GENERATED ALWAYS AS (COALESCE(suffix, '')),
UNIQUE (first_name, last_name, str_suffix)
);
将后缀空字符串设为默认值并将其设置为不为空。这可能会解决您的问题(NULL 与 '' 不同,NULL 是我不知道的,所以对于下面的代码,您说的是中间名是空字符串,而不是 NULL)。
CREATE TABLE people (
id INTEGER PRIMARY KEY,
first_name TEXT NOT NULL,
last_name TEXT NOT NULL,
suffix TEXT DEFAULT '' NOT NULL,
UNIQUE (first_name, last_name, suffix)
);
如何设置可以正确处理 sqlite 中的空值的复合唯一约束?这可能更好地用例子来表达:
CREATE TABLE people (
id INTEGER PRIMARY KEY,
first_name TEXT NOT NULL,
last_name TEXT NOT NULL,
suffix TEXT,
UNIQUE (first_name, last_name, suffix)
);
当多次输入带有后缀的人时,约束会按预期工作。
-- Last insert is denied
INSERT INTO people (first_name, last_name, suffix)
VALUES
('Joe', 'Dirt', 'Sr'),
('Joe', 'Dirt', 'Jr'),
('Joe', 'Dirt', 'Sr');
但是,当一个没有后缀的人被多次插入时,唯一约束是不适应的。
-- Both are permitted
INSERT INTO people (first_name, last_name)
VALUES
('Chris', 'Farley'),
('Chris', 'Farley');
我知道 sqlite 将 null 值视为相互独立的,但是有没有正确的方法来解决这个问题?
如有任何帮助,我们将不胜感激。谢谢!
只有当后缀为 null 时,您才能为 first_name
和 last_name
创建唯一的 partial index
:
CREATE UNIQUE INDEX idx_people ON people(first_name, last_name)
WHERE suffix IS NULL;
查看简化版 demo.
如果你的 SQLite 版本是 3.31.0+,你可以创建一个生成的列,当 suffix
是 null
时,returns 一个空字符串,并在唯一约束中使用它而不是 suffix
:
CREATE TABLE people (
id INTEGER PRIMARY KEY,
first_name TEXT NOT NULL,
last_name TEXT NOT NULL,
suffix TEXT,
str_suffix GENERATED ALWAYS AS (COALESCE(suffix, '')),
UNIQUE (first_name, last_name, str_suffix)
);
将后缀空字符串设为默认值并将其设置为不为空。这可能会解决您的问题(NULL 与 '' 不同,NULL 是我不知道的,所以对于下面的代码,您说的是中间名是空字符串,而不是 NULL)。
CREATE TABLE people (
id INTEGER PRIMARY KEY,
first_name TEXT NOT NULL,
last_name TEXT NOT NULL,
suffix TEXT DEFAULT '' NOT NULL,
UNIQUE (first_name, last_name, suffix)
);