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

Sag*_*age 8 sql postgresql inheritance constraints

我有一个问题,我可以说我有一个由学生表和教师表继承的人员表.如果我执行INSERT INTO学生和INSERT INTO老师并指定人员表(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');
Run Code Online (Sandbox Code Playgroud)

我结束了我的人员表中的两个重复记录(P_Id是我在人员表上的主键),看起来子表正在插入人员表而不考虑该表上的约束.人员表上的主键约束是否应该阻止创建重复记录?

我已经考虑使用触发器解决此问题,该触发器将在人员表上进行插入之前触发,该表将检查已存在的P_Id.但我希望它能阻止我做这些事情,或者我希望它只在子表中智能地创建记录

执行此操作后,如果在学生表中更改LastName并将更改反映到教师表中,则会出现问题吗?

以下是创建语句,上面的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)
Run Code Online (Sandbox Code Playgroud)

Mik*_*ll' 5

我认为这种行为是设计的.来自PostgreSQL文档...

INSERT总是插入到指定的表中.

而且,在页面稍远一点...

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

如果您只选择人,则不会看到任何行.如果您只选择学生,您将看到多行具有相同的people_id.也就是说,您可以向学生插入多个具有相同值的people_id.这充其量是违反直觉的; 文件说它坏了,但有一天可能会被修复.

来自"警告"部分...

继承功能的一个严重限制是索引(包括唯一约束)和外键约束仅适用于单个表,而不适用于其继承子项.在外键约束的引用和引用方面都是如此.

同一节.

这些缺陷可能会在将来的某个版本中修复,但同时需要非常谨慎地决定继承是否对您的应用程序有用.

  • 关键的见解是,实际上主键约束根本没有被违反; select从多个表,人员表,学生表和教师表中返回行.使用`only`关键字来查看是这种情况. (2认同)

Mar*_*ier 5

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

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);
Run Code Online (Sandbox Code Playgroud)

再见.