Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.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_Inheritance_Constraints - Fatal编程技术网

SQL表继承导致基表中的记录重复,即使设置了主键约束

SQL表继承导致基表中的记录重复,即使设置了主键约束,sql,postgresql,inheritance,constraints,Sql,Postgresql,Inheritance,Constraints,我有一个问题,假设我有一个由学生表和教师表继承的people表。例如,如果我插入学生和教师,并指定人员表的主键(P_Id) INSERT INTO student(P_Id, LastName, FirstName, StudentNumber) VALUES (1, 'Jones', 'Casey', 'SID0001'); INSERT INTO teacher(P_Id, LastName, FirstName, FacultyNumber) VALUES (1, 'Jones', 'C

我有一个问题,假设我有一个由学生表和教师表继承的people表。例如,如果我插入学生和教师,并指定人员表的主键(P_Id)

INSERT INTO student(P_Id, LastName, FirstName, StudentNumber)
VALUES (1, 'Jones', 'Casey', 'SID0001');

INSERT INTO teacher(P_Id, LastName, FirstName, FacultyNumber)
VALUES (1, 'Jones', 'Casey', 'JONES0001');
我的people表中有两条重复的记录(p_Id是people表上的主键),看起来子表在插入people表时没有考虑该表上的约束。people表上的主键约束不应该阻止创建重复记录吗

我曾经考虑过使用触发器来解决这个问题,该触发器将在对people表进行插入之前触发,该触发器将检查已经存在的p_Id。但是我希望它能阻止我做这样的事情,或者我希望它只在子表中智能地创建一条记录

执行此操作后,是否会出现更改姓氏(例如在学生表中)以及将更改反映到教师表中的问题

以下是create语句上面的Insert语句只是给出一个示例,据我所知,它们不能用于创建的这些表:

CREATE TABLE people
(
people_id integer NOT NULL,
last_name character varying NOT NULL,
first_name character varying NOT NULL,
middle_name character varying,
gender character varying NOT NULL,
date_of_birth date,
ssn character varying,
pref_language character varying,
CONSTRAINT people_pkey PRIMARY KEY (people_id)
)

CREATE TABLE student
(
-- Inherited from table people:  people_id integer NOT NULL,
-- Inherited from table people:  last_name character varying NOT NULL,
-- Inherited from table people:  first_name character varying NOT NULL,
-- Inherited from table people:  middle_name character varying,
-- Inherited from table people:  gender character varying NOT NULL,
-- Inherited from table people:  date_of_birth date,
-- Inherited from table people:  ssn character varying,
-- Inherited from table people:  pref_language character varying,
student_id integer NOT NULL,
race character varying(80),
ethnicity character varying(80),
employer character varying(80),
school character varying(80),
pref_location character varying(80),
CONSTRAINT student_pkey PRIMARY KEY (student_id)
)
INHERITS (people)

CREATE TABLE teacher
(
-- Inherited from table people:  people_id integer NOT NULL,
-- Inherited from table people:  last_name character varying NOT NULL,
-- Inherited from table people:  first_name character varying NOT NULL,
-- Inherited from table people:  middle_name character varying,
-- Inherited from table people:  gender character varying NOT NULL,
-- Inherited from table people:  date_of_birth date,
-- Inherited from table people:  ssn character varying,
-- Inherited from table people:  pref_language character varying,
teacher_id integer NOT NULL,
user_name character varying NOT NULL,
"password" character varying NOT NULL,
title character varying,
CONSTRAINT teacher_pkey PRIMARY KEY (teacher_id)
)
INHERITS (people)

您的主键字段是否设置为标识?要约束唯一性?

您永远不会先插入到子表中!person表是您应该插入的第一个表

我认为这种行为是故意的。从

INSERT始终精确插入指定的表中

再往下一点

父表上的所有检查约束和非空约束都是 由其子代自动继承。其他类型的约束 (唯一、主键和外键约束)不会被继承

如果仅从人员中选择,则不会看到行。如果您仅从学生中选择,您将看到具有相同人员id的多行。也就是说,您可以向学生中插入具有相同人员id值的多行。这最多是违反直觉的;文件上说它坏了,但可能有一天会被修复

从“注意事项”部分

继承特性的一个严重限制是索引 (包括唯一约束)和外键约束仅适用 到单个表,而不是它们的继承子表。这是真的 外键约束的参照侧和参照侧

同一部分

这些缺陷可能会在将来的版本中修复,但是 同时,在决定是否 继承对您的应用程序很有用


约束规则不可继承,因此需要在每个表中定义约束。例如:

CREATE TABLE people (
    id int ,
    name varchar(20),
    CONSTRAINT people_pkey PRIMARY KEY (id)
);

CREATE TABLE individual (
    cpf varchar(11),
    CONSTRAINT individual_pkey PRIMARY KEY (id)
) INHERITS (people);


CREATE TABLE legal_entity (
    cnpj varchar(14),
    CONSTRAINT legal_entity_pkey PRIMARY KEY (id)
) INHERITS (people);

再见。

你能发布你的创建声明吗?我想你需要有
学生id
学生id
不仅是主键,而且是
人的外键。人id
。谢谢你,我会给它一个快照,然后任何
插入
学生
老师
都需要首先,在表
中插入一个people
。我不确定你是否能拥有继承所需的功能。我认为如果要使用继承,你应该先检查插入到
student
(正如你所做的那样),然后更新
teacher
UPDATE teacher SET LastName='Jones',FirstName='Casey',FacultyNumber='JONES0001',其中P_Id=1SERIAL
。但是Catcall的答案和对PG文档的引用是正确的。事实上,我相信你错了,如果你先插入到一个子表中,它会为你将所有继承的列插入到基表中。谢谢你,如果你不相信我,试试看,你就会明白;)关键的洞察是,实际上根本没有违反主键约束;select从多个表、persons表、students表和teachers表返回行。使用
only
关键字查看情况是否如此。@TokenMacGuy:如果仅从人员中选择,则不会看到行。如果您仅从学生中选择,您将看到具有相同人员id的多行。也就是说,您可以向学生中插入具有相同人员id值的多行。这最多是违反直觉的;文件上说它坏了,但可能有一天会被修复。嗯,是的,没错。我同意你的意见。如果能在答案中提供一些信息,而不是依赖外部链接和评论,那就太好了。