Наследуются ли в Oracle такие ограничения, как первичный ключ, уникальный и внешний ключ?

Наследуются ли такие ограничения, как первичный ключ, уникальный и внешний ключ, в Oracle через предложение UNDER?


person chuhui chen    schedule 03.12.2020    source источник


Ответы (1)


Ключевое слово UNDER предназначено для наследования типов. Типы не могут иметь уникальных/реляционных ограничений.

Наследуются ли такие ограничения, как первичный ключ, уникальный и внешний ключ, в Oracle через предложение UNDER?

Нет, потому что у них нет таких ограничений, поэтому они не могут быть унаследованы.


Рассмотрим, если у вас есть типы:

CREATE TYPE type1 IS OBJECT (
  type1_value NUMBER(8,0)
) NOT FINAL;

CREATE TYPE type2 UNDER type1 (
  type2_value NUMBER(8,0)
);

И создайте таблицы объектов:

CREATE TABLE table1a OF type1 (
  CONSTRAINT table1a__type1_value__pk PRIMARY KEY ( type1_value )
);

CREATE TABLE table1b OF type1 (
  CONSTRAINT table1b__type1_value__pk PRIMARY KEY ( type1_value )
);

CREATE TABLE table2a OF type2;

CREATE TABLE table2b OF type2 (
  CONSTRAINT table2b__type2_value__pk PRIMARY KEY ( type2_value )
);

Наследование ограничений не происходит, но гипотетически, если бы они наследуют ограничения, какое ограничение должны наследовать table2a и table2b? База данных не может определить, должно ли ограничение быть унаследовано от table1a или table1b, поэтому этого не происходит.

Наследовать ограничения не имеет смысла, так как ограничения на таблицу, а не на тип, и вы наследуетесь от типа, а не от таблицы.

Чтобы продемонстрировать отсутствие наследования ограничений, вы можете вставить несколько примеров данных:

INSERT INTO table1a ( type1_value ) VALUES ( 1 );
INSERT INTO table1a ( type1_value ) VALUES ( 2 );
INSERT INTO table1a ( type1_value ) VALUES ( 3 );

Мы можем вставить те же данные в table1b, демонстрируя, что таблицы одного типа не имеют общих ограничений (иначе они также использовали бы один и тот же уникальный индекс и не допускали бы повторяющихся значений):

INSERT INTO table1b ( type1_value ) VALUES ( 1 );
INSERT INTO table1b ( type1_value ) VALUES ( 2 );
INSERT INTO table1b ( type1_value ) VALUES ( 3 );

Мы можем вставить те же значения в table2a, который является подтипом:

INSERT INTO table2a ( type1_value, type2_value ) VALUES ( 1, 1 );
INSERT INTO table2a ( type1_value, type2_value ) VALUES ( 1, 1 );
INSERT INTO table2a ( type1_value, type2_value ) VALUES ( 2, 1 );

И мы можем, опять же, вставить те же значения в table2b, который также является подтипом и имеет свой собственный независимый первичный ключ:

INSERT INTO table2b ( type1_value, type2_value ) VALUES ( 1, 1 );
INSERT INTO table2b ( type1_value, type2_value ) VALUES ( 1, 2 );
INSERT INTO table2b ( type1_value, type2_value ) VALUES ( 2, 3 );

В объектных таблицах нет наследования ограничений.

db‹›fiddle здесь


Обновлять

Из комментариев:

но разве нет ссылочного типа? что-то вроде:

create type Person(
  ID varchar(20) primary key,
  name varchar(20),
  address varchar(20)
) ref from(ID);

Похоже, вы путаете две вещи, поскольку не можете включить ограничение PRIMARY KEY в тип, а синтаксис неверен, но вы можете включить REF в другой объект; однако это не ссылочное ограничение для конкретной таблицы, а (из Документация Oracle):

REF принимает в качестве аргумента корреляционную переменную (псевдоним таблицы), связанную со строкой таблицы объектов или представлением объекта.

Таким образом, это скорее тип данных указателя, чем ссылочное ограничение.

Например, если у вас есть таблица:

CREATE TABLE ref_table (
  value REF type1
);

Затем вы можете вставить данные из любой/всех четырех таблиц выше:

INSERT INTO ref_table ( value )
  SELECT REF(t) FROM table1a t WHERE type1_value = 1 UNION ALL
  SELECT REF(t) FROM table1b t WHERE type1_value = 1 UNION ALL
  SELECT REF(t) FROM table2a t WHERE type1_value = 2 UNION ALL
  SELECT REF(t) FROM table2b t WHERE type1_value = 2;

Нет ссылочного ограничения на конкретную таблицу; просто указатели на объекты типа type1 или его подтипа.

Если хотите, вы могли бы (вместо этого) добавить реляционное ограничение для типа данных REF:

ALTER TABLE ref_table ADD CONSTRAINT ref_table__value__fk
  FOREIGN KEY ( value ) REFERENCES table1a;

Затем:

INSERT INTO ref_table ( value )
  SELECT REF(t) FROM table1a t WHERE type1_value = 1;

Будет работать, но вставка ссылок из других таблиц не удастся.

db‹›fiddle здесь

Вы можете наследовать REF типов данных, когда они являются частью типа объекта, но они не обеспечивают ссылочную целостность, поскольку объект, на который они указывают, может находиться в любой таблице или столбце, содержащем тип данных, на который вы указываете. Однако вы не можете наследовать FOREIGN KEY ссылочные ограничения, поскольку они применяются к таблице и не имеют ничего общего с типами объектов или наследованием.

person MT0    schedule 03.12.2020
comment
но разве нет ссылочного типа? что-то вроде: создать тип Person (первичный ключ ID varchar (20), имя varchar (20), адрес varchar (20)) ref from (ID); - person chuhui chen; 04.12.2020
comment
Этот синтаксис неверен, и тип данных REF не является ограничением; это указатель на тип объекта, который может существовать в любой таблице. - person MT0; 04.12.2020