Вы хотите разделить существующую таблицу на две таблицы, одну для хранения авторов, а другую для книг.Чтобы это работало правильно, вам нужно создать уникальный идентификатор для каждого автора.Вот пошаговый подход.
Предполагая следующую унаследованную структуру данных:
create table old_books (
isbn NUMBER(13, 0),
title VARCHAR2(200),
author_name VARCHAR2(200),
author_surname VARCHAR2(200),
author_birthdate DATE
);
И этот пример данных:
ISBN | TITLE | AUTHOR_NAME | AUTHOR_SURNAME | AUTHOR_BIRTHDATE
------------: | :----- | :---------- | :------------- | :---------------
1000000000001 | book 1 | name 1 | surname 1 | 01-MAR-90
1000000000002 | book 2 | name 2 | surname 2 | 01-MAR-95
1000000000003 | book 3 | name 1 | surname 1 | 01-MAR-90
Сначала давайте создадим и передадим новую структуру данных для authors
(обратите внимание, что вы не хотите использовать CREATE TABLE AS SELECT ...
, потому что это не позволяет добавлять ограничения или другие полезные опции).
Чтобы сгенерировать уникальный идентификатор автора, мы используем функцию IDENTITY
(доступна начиная с Oracle 12c - без этой функции нам потребуется создать последовательность и триггер).
В устаревшемДанные, мы предполагаем, что каждый автор уникально идентифицируется по его имени, фамилии и дате рождения:
CREATE TABLE authors (
id NUMBER GENERATED ALWAYS AS IDENTITY,
name VARCHAR2(200),
surname VARCHAR2(200),
birthdate DATE,
PRIMARY KEY (id)
);
INSERT INTO AUTHORS (name, surname, birthdate)
SELECT DISTINCT author_name, author_surname, author_birthdate FROM old_books;
2 rows affected
SELECT * FROM authors;
ID | NAME | SURNAME | BIRTHDATE
-: | :----- | :-------- | :--------
1 | name 1 | surname 1 | 01-MAR-90
2 | name 2 | surname 2 | 01-MAR-95
С этой первой таблицей мы можем теперь создать таблицу books
.Он содержит внешний ключ, который ссылается на первичный ключ таблицы authors
.Чтобы заполнить таблицу, нам нужно объединить устаревшую таблицу с новой таблицей authors
, чтобы восстановить идентификатор каждого автора:
CREATE TABLE books (
isbn NUMBER(13, 0),
title VARCHAR2(200),
author_id NUMBER,
CONSTRAINT book_author FOREIGN KEY(author_id) REFERENCES authors(id),
PRIMARY KEY (isbn)
);
INSERT INTO books(isbn, title, author_id)
SELECT ob.isbn, ob.title, a.id
FROM old_books ob
INNER JOIN authors a
ON a.name = ob.author_name
AND a.surname = ob.author_surname
AND a.birthdate = ob.author_birthdate;
3 rows affected
SELECT * FROM books;
ISBN | TITLE | AUTHOR_ID
------------: | :----- | --------:
1000000000001 | book 1 | 1
1000000000002 | book 2 | 2
1000000000003 | book 3 | 1
Все готово!Данные правильно распределены между двумя таблицами с соответствующими ограничениями.Мы можем объединить обе таблицы с помощью запроса:
SELECT b.isbn, b.title, a.name, a.surname, a.birthdate
FROM authors a
INNER JOIN books b ON a.id = b.author_id;
ISBN | TITLE | NAME | SURNAME | BIRTHDATE
------------: | :----- | :----- | :-------- | :--------
1000000000001 | book 1 | name 1 | surname 1 | 01-MAR-90
1000000000002 | book 2 | name 2 | surname 2 | 01-MAR-95
1000000000003 | book 3 | name 1 | surname 1 | 01-MAR-90