Наследуются ли такие ограничения, как первичный ключ, уникальный и внешний ключ, в Oracle через предложение UNDER?
Наследуются ли в Oracle такие ограничения, как первичный ключ, уникальный и внешний ключ?
Ответы (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
ссылочные ограничения, поскольку они применяются к таблице и не имеют ничего общего с типами объектов или наследованием.
REF
не является ограничением; это указатель на тип объекта, который может существовать в любой таблице.
- person MT0; 04.12.2020