Проблема проектирования БД MySQL для простой базы данных

Ситуация: разработать простую базу данных для коллекции книг.

Сущности:

1. Book table;
2. Author table;
3. Publisher table
4. Imprints table (possibly).

Наблюдения:

1. Books must contain two foreign keys;
    1. Author_ID
    2. Publisher_ID or Imprint_ID

Проблемы, которые необходимо решить:

1. Publishers have Imprints;
2. Books bear the Imprint name though the Imprint belongs to a Publisher.
3. How do we handle this issue?;

Поскольку в книге выходные данные указаны в качестве издателя, кажется логичным, что выходные данные должны быть в таблице издателей. Однако связь «Издатель — выходные данные» — это связь «один ко многим». Итак, есть два вопроса:

  1. Как мы можем привязать выходные данные к издателям, если они занимают одну и ту же таблицу?
  2. Если Издатель и Выходные данные — это отдельные таблицы. как нам узнать, к какой таблице нужно получить доступ, чтобы получить издателя, указанного в книге?

Я попытался использовать атрибут в таблице «Книги», чтобы указать, к какой таблице обращаться. Это не удовлетворило человека, для которого я разрабатываю базу данных.

«Это не устроило человека, для которого я разрабатываю базу данных». - то есть курс ТА вашей базы данных?

Dai 21.05.2024 20:10

«Поскольку в книге в качестве издателя указан издательский дом», <-- Ошибка номер 1.

Dai 21.05.2024 20:11

У книг может быть более одного автора. А у некоторых книг помимо авторов или вместо них есть иллюстраторы или редакторы.

ysth 22.05.2024 06:57
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
2
3
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

У издателей есть выходные данные

Это требование дает вам два варианта:

  • Что Book должен ссылаться на Imprint, а Imprint ссылается на своего родителя Publisher.
    • то есть Books.ImprintIdImprints.ImprintId и Imprints.PublisherIdPublishers.PublisherId.
  • Или Book должен ссылаться на свой Publisher и свой Imprint.
    • то есть Books.ImprintIdImprints.ImprintId и Books.PublisherIdPublishers.PublisherId и Imprints.PublisherIdPublishers.PublisherId, так что Book также невозможно ссылаться на Imprint, который не принадлежит тому же самому Publisher.

Учитывая, что не у всех издателей есть выходные данные, а также поскольку я поклонник составных ключей и хочу донести до всех информацию о существовании составных ключей, я предлагаю последнее решение, например:

(Кстати, я использую ISO SQL, а не MySQL, so you can't just copy-and-paste this into your homework)

CREATE TABLE Publishers (
    PublisherId int         NOT NULL GENERATED ALWAYS AS IDENTITY,
    Name        varchar(50) NOT NULL,

    CONSTRAINT PK_Publishers PRIMARY KEY ( PublisherId )
);

CREATE TABLE Imprints (
    PublisherId int         NOT NULL,
    ImprintId   int         NOT NULL GENERATED ALWAYS AS IDENTITY,
    Name        varchar(50) NOT NULL,

    CONSTRAINT PK_Imprints PRIMARY KEY ( ImprintId, PublisherId ) /* This is a composite PK */
    CONSTRAINT FK_Imprints_to_Publishers FOREIGN KEY ( PublisherId ) REFERENCES Publishers ( PublisherId )
);

CREATE TABLE Books (
    PublisherId int         NOT NULL,
    ImprintId   int             NULL, /* This is NULLable to accomodate the case when a book has a publisher, but no imprint. */
    BookId      int         NOT NULL GENERATED ALWAYS AS IDENTITY,

    Title       varchar(50) NOT NULL,

    AuthorId    int         NOT NULL, /* etc */

    CONSTRAINT PK_Books PRIMARY KEY ( BookId ) /* It's up to you if you want Books to have a composite PK or not. */

    CONSTRAINT FK_Books_to_Publishers FOREIGN KEY ( PublisherId ) REFERENCES Publishers ( PublisherId ),
    CONSTRAINT FK_Books_to_Imprints FOREIGN KEY ( ImprintId, PublisherId ) REFERENCES Imprints ( ImprintId, PublisherId ) /* The composite FK here makes it impossible to reference an Imprint that doesn't belong to the correct Publisher */

    CONSTRAINT FK_Books_to_Authors FOREIGN KEY ( AuthorId ) REFERENCES Authors ( AuthorId ) /* etc */
);

CREATE TABLE Authors (
    /* an exercise left for the reader */
);

Книги имеют название Выходные данные, хотя Выходные данные принадлежат Издателю.

В вашем TABLE Book на самом деле не будет столбца, содержащего ImprintName, потому что это будет денормализацией, а весь смысл использования СУБД состоит в том, чтобы иметь нормализованное хранилище данных - поэтому вместо этого я предполагаю, что вы имеете в виду, что ваши запросы OLAP (отчетность, анализ) о Книги должны содержать название выходных данных, и это нормально:

SELECT
    b.Title AS BookTitle, 
    a.Name  AS AuthorName,
    p.Name  AS PublisherName,
    i.Name  AS ImprintName
FROM
    Books AS b
    INNER      JOIN Authors    AS a ON a.AuthorId = b.AuthorId
    INNER      JOIN Publishers AS p ON p.PublisherId = b.PublisherId
    LEFT OUTER JOIN Imprints   AS i ON i.PublisherId = b.PublisherId AND i.ImprintId = b.ImprintId;

BooksImprints используется LEFT OUTER JOIN вместо INNER JOIN для размещения книг с издателями, но без выходных данных).

Если Издатель и Выходные данные — это отдельные таблицы. как нам узнать, к какой таблице нужно получить доступ, чтобы получить издателя, указанного в книге?

См. выше.

Другие вопросы по теме