我有一个这种布局的表:
CREATE TABLE Favorites
(
FavoriteId uuid NOT NULL PRIMARY KEY,
UserId uuid NOT NULL,
RecipeId uuid NOT NULL,
MenuId uuid
)
Run Code Online (Sandbox Code Playgroud)
我想创建一个类似于此的唯一约束:
ALTER TABLE Favorites
ADD CONSTRAINT Favorites_UniqueFavorite UNIQUE(UserId, MenuId, RecipeId);
Run Code Online (Sandbox Code Playgroud)
但是,这将允许多行具有相同的(UserId, RecipeId)if MenuId IS NULL.我想允许NULL在MenuId存储不具有关联菜单中的最爱,但我只希望每个用户/食谱对这些行中最多只有一个.
我到目前为止的想法是:
使用一些硬编码的UUID(例如全零)而不是null.
但是,MenuId每个用户的菜单都有一个FK约束,所以我必须为每个用户创建一个特殊的"空"菜单,这是一个麻烦.
使用触发器检查是否存在空条目.
我认为这是一个麻烦,我喜欢尽可能避免触发器.另外,我不相信他们能保证我的数据永远不会处于不良状态.
只需忘记它并检查中间件或插入函数中是否存在空条目,并且没有此约束.
我正在使用Postgres 9.0.
我有什么方法可以忽略吗?
以下代码创建表而不引发任何错误:
CREATE TABLE test(
ID INTEGER NULL,
CONSTRAINT PK_test PRIMARY KEY(ID)
)
Run Code Online (Sandbox Code Playgroud)
请注意,我无法按预期插入NULL:
INSERT INTO test
VALUES(1),(NULL)
ERROR: null value in column "id" violates not-null constraint
DETAIL: Failing row contains (null).
********** Error **********
ERROR: null value in column "id" violates not-null constraint
SQL state: 23502
Detail: Failing row contains (null).
Run Code Online (Sandbox Code Playgroud)
为什么我可以创建一个具有自相矛盾定义的表格?ID列显式声明为NULLable,并且作为PRIMARY KEY的一部分,它隐式地不可为空.是否有意义?
编辑:如果这个自相矛盾的CREATE TABLE在那里失败了会不会更好?
这是我在Postgres中遇到的一个奇怪的,不需要的行为:当我使用复合主键创建Postgres表时,它会对复合组合的每一列强制执行NOT NULL约束.
例如,
CREATE TABLE distributors (m_id integer, x_id integer, PRIMARY KEY(m_id, x_id));
Run Code Online (Sandbox Code Playgroud)
强制NOT NULL列上的约束m_id和x_id,我不想!MySQL没有这样做.我认为Oracle也不会这样做.
据我所知,PRIMARY KEY强制执行UNIQUE并NOT NULL自动执行但对单列主键有意义.在多列主键表中,唯一性由组合确定.
有没有简单的方法来避免Postgres的这种行为?
如果我执行这个:
CREATE TABLE distributors (m_id integer, x_id integer);
Run Code Online (Sandbox Code Playgroud)
我NOT NULL当然没有任何限制.
如何使用PostgreSQL在单个表中为多列提供主键?
例:
Create table "Test"
(
"SlNo" int not null primary key,
"EmpID" int not null, /* Want to become primary key */
"Empname" varchar(50) null,
"EmpAddress" varchar(50) null
);
Run Code Online (Sandbox Code Playgroud)
注意:我也想制作"EmpID"一个主键.
postgresql ddl database-design primary-key composite-primary-key