Sql 是否对相关表中的值(而不是外键)进行部分索引?
我正在一个学习平台上工作,在这个平台上,学生属于Sql 是否对相关表中的值(而不是外键)进行部分索引?,sql,postgresql,database-design,constraints,postgresql-9.4,Sql,Postgresql,Database Design,Constraints,Postgresql 9.4,我正在一个学习平台上工作,在这个平台上,学生属于团队,每个团队都属于课程: CREATE TABLE teams ( id SERIAL, name string NOT NULL, curriculum_id integer NOT NULL ); CREATE TABLE curricula ( id SERIAL, name string NOT NULL ); CREATE UNIQUE INDEX index_curricula_on_nam
团队
,每个团队都属于课程
:
CREATE TABLE teams (
id SERIAL,
name string NOT NULL,
curriculum_id integer NOT NULL
);
CREATE TABLE curricula (
id SERIAL,
name string NOT NULL
);
CREATE UNIQUE INDEX index_curricula_on_name ON curricula USING btree (name);
课程名称必须是唯一的,虽然大多数课程允许有多个团队与其关联,但一个团队不能。我试图在teams表上添加一个部分(唯一)索引,以便对课程设置进行限制
我知道我可以用…部分地约束课程id本身
CREATE UNIQUE INDEX index_teams_on_curriculum_id ON teams USING btree (curriculum_id)
WHERE curriculum_id = 1;
。。。但这是不可行的,因为课程的ID在不同的环境(开发、登台等)中会有所不同
有没有办法通过
课程名称来约束团队.课程id
列?您可以通过触发器或检查约束中的假不可变函数来实现类似的功能。两者都有弱点
但这也可以通过纯SQL实现-仅使用非空
、检查
、唯一
和FK
约束。没有弱点
CREATE TABLE curriculum (
curriculum_id serial PRIMARY KEY
, curriculum text UNIQUE NOT NULL
, team_unique boolean UNIQUE NOT NULL
, CONSTRAINT curriculum_team_uni UNIQUE (curriculum_id, team_unique) -- for multicolumn FK
);
CREATE TABLE team (
team_id serial PRIMARY KEY
, team text NOT NULL
, curriculum_id integer NOT NULL
, team_unique boolean NOT NULL
-- , CONSTRAINT fk1 FOREIGN KEY (curriculum_id) REFERENCES curriculum
, CONSTRAINT fk2 FOREIGN KEY (curriculum_id, team_unique)
REFERENCES curriculum (curriculum_id, team_unique)
);
CREATE UNIQUE INDEX team_curriculum_uni_idx ON team (team_unique)
WHERE team_unique;
- 在父表和子表中添加一个
boolean NOT NULL
列,并在父表中使其唯一。因此,课程
中只有一行可以标记为唯一-以实现您的限制性要求:
不能
部分唯一索引team\u currency\u uni\u idx
仅强制对其进行一次引用
如果有多个唯一的课程(仅参考一次),我们将删除课程.team\u unique
上的unique
约束,并将team
上的部分唯一索引扩展到(课程id,team\u unique)
- FK(
fk2
)强制继承列的组合
- 这使得添加一个
UNIQUE
约束以强制一个团队执行唯一课程变得非常简单
- Postgres FK约束的默认
MATCH SIMPLE
行为仅强制不带空值的组合。我们可以使用MATCH FULL
或另一个普通FK(fk1
)来强制执行现有的课程id
。我对附加的FK进行了注释,因为在此配置中不需要它(定义的两个FK列均不为NULL
)
相关的:
@erwin感谢您的编辑和更好的标签!这真是不可思议的现象,谢谢你。我还没来得及通读所有这些内容并加以实施,但我想提前向你们表示感谢。@Kevlar:注意我添加的一个小简化。