Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.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
Sql 如何确保日志记录表中的值与其他表中的对象匹配?_Sql_Postgresql_Database Design_Foreign Keys - Fatal编程技术网

Sql 如何确保日志记录表中的值与其他表中的对象匹配?

Sql 如何确保日志记录表中的值与其他表中的对象匹配?,sql,postgresql,database-design,foreign-keys,Sql,Postgresql,Database Design,Foreign Keys,我有三张桌子。两个基本表列出了对象,第三个表记录了数据库中的更改。这里有一个例子 create table individual (ind_id integer, age integer, name varchar); create table organisation (org_id integer, city varchar, name varchar); create TABLE log_table (log_id integer, object_id integer, table_nam

我有三张桌子。两个基本表列出了对象,第三个表记录了数据库中的更改。这里有一个例子

create table individual (ind_id integer, age integer, name varchar);
create table organisation (org_id integer, city varchar, name varchar);
create TABLE log_table (log_id integer, object_id integer, table_name varchar, information json, log_date date);
我希望确保log_表中的任何行都对应于单个表或组织表中的现有对象。这意味着插入

insert into log_table (object_id,table_name,information,log_date) values (13,'organisation','{"some":"interesting","information":"on the changes"}','2017-11-09');
仅当表组织包含ID为13的记录时才有效


在PostgreSQL中如何实现这一点?如果这是不可能的,那么我想我必须在log_表中为单个表创建一列,为组织表创建一列。

您需要一个
实体
表:

create table entity (
    entity_id serial primary key,
    entity_type text check (entity_type in ('individual','organization'))
)
create table individual (
    ind_id integer primary key references entity (entity_id), 
    age integer, name varchar
);
create table organisation (
    org_id integer primary key references entity (entity_id), 
    city varchar, name varchar
);
create TABLE log_table (
    log_id integer primary key, 
    entity_id integer references entity (entity_id), 
    information json, log_date date
);

您需要一个
实体
表:

create table entity (
    entity_id serial primary key,
    entity_type text check (entity_type in ('individual','organization'))
)
create table individual (
    ind_id integer primary key references entity (entity_id), 
    age integer, name varchar
);
create table organisation (
    org_id integer primary key references entity (entity_id), 
    city varchar, name varchar
);
create TABLE log_table (
    log_id integer primary key, 
    entity_id integer references entity (entity_id), 
    information json, log_date date
);

您还可以使用触发器来解决此问题。可以在个人和组织表上单独触发,这些表可以在更新前、更新后、插入操作后打开

您可以在日志表中添加一列,该列对应于在基表中执行的操作,即更新或插入

还可以在表名和对象id上添加唯一约束

这最终将导致在不更改应用程序代码的情况下,将每个可能的操作记录到表中


希望这有帮助

您也可以使用触发器来解决此问题。可以在个人和组织表上单独触发,这些表可以在更新前、更新后、插入操作后打开

您可以在日志表中添加一列,该列对应于在基表中执行的操作,即更新或插入

还可以在表名和对象id上添加唯一约束

这最终将导致在不更改应用程序代码的情况下,将每个可能的操作记录到表中


希望这有帮助

从您当前的设计开始,您可以通过向每个实体表添加一个常量检查或计算/虚拟表/类型变量/标记列和一个FK(外键)(id,表)到日志表,以声明方式强制执行您想要的内容


您有两种类型的记录实体。Google sql/数据库子类型/多态性/继承。或(反模式)2/many/multiple FK到2/many/multiple table。

从当前设计开始,您可以通过向每个实体表添加一个常量检查或计算/虚拟表/类型变量/标记列和一个FK(外键)(id,table)到日志表,以声明方式强制执行所需内容


您有两种类型的记录实体。Google sql/数据库子类型/多态性/继承。或者(反模式)2/多个/多个FK到2/多个/多个表。

当前设计的问题是这两个可能会冲突。您可能有相同ID的个人和组织。这就是为什么您需要在验证中考虑表名的原因。当前设计的问题是,这两者可能会冲突。您可能有相同ID的个人和组织。这就是为什么您需要在验证中考虑表名的原因。