Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PostgreSQL循环外键到多个表_Sql_Postgresql_Foreign Keys - Fatal编程技术网

PostgreSQL循环外键到多个表

PostgreSQL循环外键到多个表,sql,postgresql,foreign-keys,Sql,Postgresql,Foreign Keys,我有三张桌子 聊天室 创建桌面聊天室 ( id uuid默认uuid_generate_v4()不为空 约束聊天室 主键 约束fk\u聊天室\u群组\u聊天室 参考组聊天室 关于更新级联关于删除级联 限制fk___聊天室____私人聊天室 参考私人聊天室 更新级联时删除级联时, 名称varchar(255)不为空, 描述varchar(255), 剖面图_pic varchar(128), 使用时区默认值now()在时间戳处创建的_不为空, 在带有时区的时间戳处更新了_ ); 群组聊天室 cr

我有三张桌子

聊天室

创建桌面聊天室
(
id uuid默认uuid_generate_v4()不为空
约束聊天室
主键
约束fk\u聊天室\u群组\u聊天室
参考组聊天室
关于更新级联关于删除级联
限制fk___聊天室____私人聊天室
参考私人聊天室
更新级联时删除级联时,
名称varchar(255)不为空,
描述varchar(255),
剖面图_pic varchar(128),
使用时区默认值now()在时间戳处创建的_不为空,
在带有时区的时间戳处更新了_
);
群组聊天室

create table group\u chat\u room
(
id uuid不为空
约束组\u聊天室\u pk
主键
约束fk\uuuu组\u聊天室\uuuuu聊天室
参考聊天室
更新级联时删除级联时,
pus_代码字符(7)不为空
约束fk\uuuu组\uu聊天室\uuuu puskesmas
参考文献puskesmas
关于更新级联关于删除级联
);
创建唯一索引组\u聊天室\u pus\u代码\u uindex
在群组聊天室(密码);
私人聊天室

create table private\u聊天室
(
id uuid不为空
约束私密\u聊天室\u pk
主键
约束fk\uuuu私人聊天室\uuuu聊天室
参考聊天室
关于更新级联关于删除级联
);
如您所见,
聊天室
具有外键约束,这些外键约束指的是
群组聊天室
私人聊天室
。另外,
group\u chat\u room
private\u chat\u room
都具有引用
chat\u room
的FK约束

当我想
聊天室
中插入一行时,我会使用这个

聊天室为(
在聊天室(id,名称)中插入值('Some id','Some name')
)
在群组聊天室(id、pus代码)中插入值(“某些id”、“某些代码”);
但是,由于这些限制,这将产生错误

[23503]错误:表“chat_room”上的插入或更新违反外键约束“fk_chat_room_private_chat_room”详细信息:键(id)=(cef8c655-d46a-4f63-bdc8-77113b1b74b4)不在表“private_chat_room”中。


如何只插入到
群组聊天室
,而不必将其插入到
私人聊天室

这里的主要问题是创建多个所需的双向外键。你最终可能会解决这个问题。但这使得数据模型更加复杂,代码也更加复杂。而且它是完全没有必要的。只要一张桌子,你就可以完成所有的事情。如果单独需要组聊天室和私人聊天室,则为每个组创建一个视图。此外,作为简单视图,它们是完全可更新的
您可以通过将列“pus_code”移动到聊天室,并添加2个布尔值来指示这是私人聊天室还是团体聊天室,或者两者都是。是的,听起来很奇怪,但你可以得到一个私人的群组聊天室。(注意:在您的设计中没有任何东西阻止它,您得到的错误是因为它是必需的)。如果确实需要,则创建一个检查约束,要求至少有一个布尔列为false

create table chat_room
(
    id  integer generated always as identity
        constraint chat_room_pk
            primary key, 
    name varchar(255) not null,
    description varchar(255),
    profile_pic varchar(128),
    is_private boolean not null default false,
    is_group boolean not null default false,
    pus_code varchar(7) 
        constraint fk__group_chat_room__puskesmas
            references puskesmas
                on update cascade on delete cascade,        
    created_at timestamp with time zone default now() not null,
    updated_at timestamp with time zone,
    constraint not_group_of_pus_code_check
               check (   (not is_group and pus_code is null)
                      or (is_group and pus_code is not null)
                     ) 
);

-- create unique partial index
create unique index group_chat_room_pus_code_uindex on chat_room(pus_code)
    where is_group;

-- group_chat_room
create view group_chat_room 
       ( id   
       , name  
       , description 
       , profile_pic  
       , is_private  
       , pus_code 
       , created_at  
       , updated_at
       ) as 
  select id             
       , name           
       , description    
       , profile_pic    
       , is_private   
       , pus_code       
       , created_at     
       , updated_at 
   from chat_room
  where is_group;

-- private_chat_room
create view private_chat_room                    
       ( id                                     
       , name                                   
       , description                            
       , profile_pic                            
       , is_group                             
       , pus_code                               
       , created_at                             
       , updated_at                             
       ) as                                     
  select id                                     
       , name                                   
       , description                            
       , profile_pic                           
       , is_group                            
       , pus_code                                  
       , created_at                            
       , updated_at       
   from chat_room
  where is_private;

有关完整示例和一些测试,请参见。注意:fiddle在generate_uuid_v4()上有一个问题(不存在),所以对于demo我改为identity。它在操作环境中会很好。

这里的主要问题是创建多个所需的双向外键。你最终可能会解决这个问题。但这使得数据模型更加复杂,代码也更加复杂。而且它是完全没有必要的。只要一张桌子,你就可以完成所有的事情。如果单独需要组聊天室和私人聊天室,则为每个组创建一个视图。此外,作为简单视图,它们是完全可更新的
您可以通过将列“pus_code”移动到聊天室,并添加2个布尔值来指示这是私人聊天室还是团体聊天室,或者两者都是。是的,听起来很奇怪,但你可以得到一个私人的群组聊天室。(注意:在您的设计中没有任何东西阻止它,您得到的错误是因为它是必需的)。如果确实需要,则创建一个检查约束,要求至少有一个布尔列为false

create table chat_room
(
    id  integer generated always as identity
        constraint chat_room_pk
            primary key, 
    name varchar(255) not null,
    description varchar(255),
    profile_pic varchar(128),
    is_private boolean not null default false,
    is_group boolean not null default false,
    pus_code varchar(7) 
        constraint fk__group_chat_room__puskesmas
            references puskesmas
                on update cascade on delete cascade,        
    created_at timestamp with time zone default now() not null,
    updated_at timestamp with time zone,
    constraint not_group_of_pus_code_check
               check (   (not is_group and pus_code is null)
                      or (is_group and pus_code is not null)
                     ) 
);

-- create unique partial index
create unique index group_chat_room_pus_code_uindex on chat_room(pus_code)
    where is_group;

-- group_chat_room
create view group_chat_room 
       ( id   
       , name  
       , description 
       , profile_pic  
       , is_private  
       , pus_code 
       , created_at  
       , updated_at
       ) as 
  select id             
       , name           
       , description    
       , profile_pic    
       , is_private   
       , pus_code       
       , created_at     
       , updated_at 
   from chat_room
  where is_group;

-- private_chat_room
create view private_chat_room                    
       ( id                                     
       , name                                   
       , description                            
       , profile_pic                            
       , is_group                             
       , pus_code                               
       , created_at                             
       , updated_at                             
       ) as                                     
  select id                                     
       , name                                   
       , description                            
       , profile_pic                           
       , is_group                            
       , pus_code                                  
       , created_at                            
       , updated_at       
   from chat_room
  where is_private;

有关完整示例和一些测试,请参见。注意:fiddle在generate_uuid_v4()上有一个问题(不存在),所以对于demo我改为identity。在操作环境下,它可以正常工作。

根据私人聊天根目录删除FK约束。真的不应该有一个双向的FK。如果出于某些奇怪的原因需要双向FK(此处不明显),请参阅。并非所有数据库都支持这些代码。此代码在PostgreSQL中无法正常工作。您需要先创建表,然后添加外键约束。另外,确保外键约束标记为
可延迟初始延迟
,以便在这些对称表中插入。根据私人聊天根删除FK约束。真的不应该有一个双向的FK。如果出于某些奇怪的原因需要双向FK(此处不明显),请参阅。并非所有数据库都支持这些代码。此代码在PostgreSQL中无法正常工作。您需要先创建表,然后添加外键约束。另外,确保外键约束标记为
可延迟初始延迟
,以便在这些对称表中插入。