Как структурировать SQL модель данных для поддержания целостности данных - PullRequest
2 голосов
/ 21 апреля 2020

Справочная информация

Я строю службу бронирования личного шеф-повара, где вы можете заказать шеф-повара, чтобы приготовить для вас индивидуальное меню. У меня возникают проблемы при создании схемы SQL db, которая точно представляет домен при сохранении целостности данных.

Требования

  • Клиенты создают Booking, выбрав Chef и Menu и выберите MenuItems, который они хотят для каждого MenuCourse
  • A Chef, определяет набор MenuItem, из которого клиент может выбрать для создания своих Booking
  • A Menu - это коллекция MenuCourses. (например, A Menu под названием «Дегустационное меню» представляет собой обед из 6 блюд, где каждый MenuCourse стоит от 10 до 20 долларов США).
  • A Chef должен иметь возможность связать их MenuItems с несколькими Menus и MenuCourses.
  • Клиент Booking должен содержать Chef клиента, выбранного вдоль с MenuMenuItems), который будет подан. Booking цена определяется выбором Menu и MenuCourse (закуска стоит меньше, чем закуска)

Проблема

В моей текущей модели данных у меня есть следующие проблемы, которые я не уверен, как исправить:

A. Можно создать Booking с Chef "A", но затем иметь BookingMenuItem, который ссылается на MenuItem с Chef "B" (все BookingMenuItem для Booking должны принадлежать то же самое Chef)

B. A Booking ссылается на конкретный Menu (который мне нужен для расчета цены, цена основана на Menu и MenuCourse), однако BookingMenuItem для этого Booking может ссылаться на совершенно другой Menu или MenuCourse

Можно ли изменить дизайн моей схемы БД, чтобы устранить проблемы с целостностью, которые у меня возникают? Или мне просто нужно реализовать эти проверки на уровне приложения. Спасибо!

ERD

1 Ответ

2 голосов
/ 24 апреля 2020

При этом используются имена таблиц из вашей модели, и они следуют за ним настолько близко, насколько я мог. Я переименовал menu_item в dish, чтобы избежать путаницы.


customer {CST}
     KEY {CST}
chef {CHF}
 KEY {CHF}
dish {CHF, DSH_NO}
 KEY {CHF, DSH_NO}

FK {CHF} REFERENCES chef {CHF}
menu {CHF, MNU_NO}
 KEY {CHF, MNU_NO}

FK {CHF} REFERENCES chef {CHF}
menu_course {CHF, MNU_NO, CRS_NO}
        KEY {CHF, MNU_NO, CRS_NO}

  FK {CHF, MNU_NO} REFERENCES
menu {CHF, MNU_NO}
menu_course_item { CHF
                 , MNU_NO
                 , CRS_NO
                 , CRS_ITM_NO
                 , DSH_NO
                 }
KEY {CHF, MNU_NO, CRS_NO, CRS_ITM_NO}

        FK1 {CHF, MNU_NO, CRS_NO} REFERENCES
menu_course {CHF, MNU_NO, CRS_NO}

 FK2 {CHF, DSH_NO} REFERENCES
dish {CHF, DSH_NO}
booking { CST
        , BOOK_NO
        , CHF
        , MNU_NO
        }
    KEY {CST, BOOK_NO}
     SK {CST, BOOK_NO, CHF, MNU_NO}

FK1 {CST} REFERENCES customer {CST}

 FK2 {CHF, MNU_NO} REFERENCES
menu {CHF, MNU_NO}
booking_menu_item { CST
                  , BOOK_NO
                  , CHF
                  , MNU_NO
                  , CRS_NO
                  , CRS_ITM_NO
                  }

KEY {CST, BOOK_NO, CHF, MNU_NO, CRS_NO, CRS_ITM_NO}

    FK1 {CST, BOOK_NO, CHF, MNU_NO} REFERENCES
booking {CST, BOOK_NO, CHF, MNU_NO}

             FK2 {CHF, MNU_NO, CRS_NO, CRS_ITM_NO} REFERENCES
menu_course_item {CHF, MNU_NO, CRS_NO, CRS_ITM_NO}

Я использовал обобщенный c термин KEY для PK or AK. Если по какой-либо причине вам необходимо использовать технические столбцы с одним столбцом (xx_ID), обязательно добавьте их, как описано в в этом примере ; если нет, все эти KEY являются PK.

Примечание:

All attributes (columns) NOT NULL

KEY = PK or AK

PK = Primary Key
AK = Alternate Key   (Unique)
SK = Proper Superkey (Unique)
FK = Foreign Key
...