Проблемы со ссылкой на первичный ключ с помощью внешнего ключа

#sql #sql-server #database-design #foreign-keys #ssms

#sql #sql-сервер #проектирование базы данных #внешние ключи #ssms

Вопрос:

Это код для создания начальной базы данных библиотеки книг с помощью Microsoft SQL Server Management Studio.

 CREATE DATABASE BOOK_LIBRARY

CREATE TABLE LIBRARY_USER
(
    usr_id int not null primary key,
    f_name varchar(30) not null,
    m_init char(1),
    l_name varchar(30) not null,
    balance decimal(6,2),
    join_date date,
    addrss_1 varchar(30) not null,
    addrss_2 varchar(30),
    city varchar(30) not null,
    addrss_state char(2) not null,
    zip_code varchar(10) not null,
    email varchar(30)
);

CREATE TABLE LIBRARY_TRANSACTIONS
(
    transaction_id int not null primary key,
    maximum_borrow_duration int not null,
    strt_date date not null,
    actual_return_date date not null,
    borrow_usr_id int not null,
    foreign key (borrow_usr_id) references LIBRARY_USER(usr_id)
);

CREATE TABLE BOOKS
(
    isbn varchar(17) not null primary key,
    title varchar(30) not null,
    number_of_copies int not null,
    Author varchar(30) not null,
    Number_of_pages int not null,
    publish_year int not null,
    book_type varchar(20)
);

CREATE TABLE DIGITAL_BOOKS
(
    digital_id int not null primary key,
    format varchar(30) not null,
    size_mb int not null,
    digital_isbn varchar(17) not null,
    foreign key(digital_isbn) references BOOKS(isbn)
);

CREATE TABLE PHYSICAL_BOOKS
(
    physical_id int not null primary key,
    condition varchar(20) not null,
    physical_isbn varchar(17) not null,
    foreign key(physical_isbn) references BOOKS(isbn)
);

CREATE TABLE BOOK_COPY
(
    digi_id int not null,
    phys_id int not null,
    primary key(digi_id, phys_id),
    foreign key(digi_id) references DIGITAL_BOOKS(digital_id),
    foreign key(phys_id) references PHYSICAL_BOOKS(physical_id)
);

CREATE TABLE CONTNS
(
    trans_id int not null primary key,
    digi_id int not null,
    phys_id int not null,
    foreign key(digi_id) references BOOK_COPY(digi_id),
    foreign key(phys_id) references BOOK_COPY(phys_id)
);
  

Несмотря на то, что я могу смотреть и видеть, что digi_id и phys_id на самом деле являются первичными ключами book_copy таблицы, я продолжаю получать эту ошибку:

Сообщение 1776, уровень 16, состояние 0, строка 66
В таблице ‘BOOK_COPY’, на которую ссылается ссылка, нет первичных или потенциальных ключей, которые соответствуют списку столбцов ссылки во внешнем ключе ‘FK__CONTNS__digi_id__37A5467C’.

Сообщение 1750, уровень 16, состояние 1, строка 66
Не удалось создать ограничение или индекс. Смотрите предыдущие ошибки.

Я упускаю что-то очевидное? Я только начинаю использовать эту программу, поэтому буду признателен за любую помощь.

Комментарии:

1. FK должен ссылаться на весь ключ, то есть на оба столбца PK digi_id, phys_id здесь.

2. Я не уверен, что понимаю, что вы имеете в виду

3. Сделайте жизнь проще для всех. Что означает имя «CONTNS»? Для меня ничего. И зачем вам нужно сокращать, уплотнять или запутывать само имя? Что именно вы экономите, удаляя некоторые гласные и буквы? Что еще более важно, я думаю, что ваша схема логически ошибочна, и это часть вашей борьбы. Кажется, вы пытались реализовать <тип> отношения между книгами и таблицами 2-х подтипов, но запутались и сбились с пути.

4. И я предполагаю, что у вас может быть много очень разных типов «транзакций», которые лучше реализовать отдельно. В настоящее время вы только начали моделировать транзакцию «заимствования», но вы решили использовать очень общие имена. Это форма преждевременной оптимизации, которая может внести свой вклад в вашу путаницу.

5. Я бы посоветовал вам сначала создать таблицы, затем ПЕРВИЧНЫЕ ключи, затем внешние ключи. Это сделает вещи более понятными. Кроме того, всегда называйте ПЕРВИЧНЫЙ КЛЮЧ, ВНЕШНИЙ КЛЮЧ. Не используйте системные имена

Ответ №1:

Здесь:

 CREATE TABLE CONTNS
(
    trans_id int not null primary key,
    digi_id int not null,
    phys_id int not null,
    foreign key(digi_id) references BOOK_COPY(digi_id),
    foreign key(phys_id) references BOOK_COPY(phys_id)
);
  

Вы создаете два внешних ключа для родительской таблицы BOOK_COPY . Но эта таблица имеет составной первичный ключ (т.Е. Первичный ключ с несколькими столбцами)

 CREATE TABLE BOOK_COPY
(
    digi_id int not null,
    phys_id int not null,
    primary key(digi_id, phys_id),  --> here
    ...
)
  

Как следствие, вам нужен составной внешний ключ:

 CREATE TABLE CONTNS
(
    trans_id int not null primary key,
    digi_id int not null,
    phys_id int not null,
    foreign key(digi_id, phys_id) references BOOK_COPY(digi_id, phys_id)
);