Сопоставление отношений "многие ко многим" в объектно-реляционной базе данных (Oracle)

Если у вас много отношений между книгой и категорией, вы можете сопоставить ее с объектно-ориентированной моделью, как показано ниже, на основе Как создать отношения" многие-ко-многим "в объектной базе данных?

Book {
 Collection<Category> categories
}

Category {
 Collection<Books> books
}

Чтобы определить коллекцию в таблице в ORDBMS, вы должны использовать вложенную таблицу. (Пример взят с веб-сайта Oracle Пример приложения, использующего объектно-реляционные функции < / а>)

CREATE TABLE PurchaseOrder_objtab OF PurchaseOrder_objtyp (  /* Line 1 */
   PRIMARY KEY (PONo),                                       /* Line 2 */
   FOREIGN KEY (Cust_ref) REFERENCES Customer_objtab)        /* Line 3 */
   OBJECT IDENTIFIER IS PRIMARY KEY                          /* Line 4 */
   NESTED TABLE LineItemList_ntab STORE AS PoLine_ntab (     /* Line 5 */
     (PRIMARY KEY(NESTED_TABLE_ID, LineItemNo))              /* Line 6 */
     ORGANIZATION INDEX COMPRESS)                            /* Line 7 */
   RETURN AS LOCATOR                                         /* Line 8 */

Однако лучше сохранить коллекцию ссылок, а не сами объекты.

Согласно этому ответу Первичный и внешний ключ вложенной таблицы в Oracle невозможно добавить внешний ключ во вложенную таблицу.

1) Итак, как лучше всего сопоставить отношения "многие ко многим" в объектно-реляционной базе данных (Oracle)?

2) Если ответ заключается в хранении двух коллекций в двух объектах, как показано выше, как сохранить их как эталонную коллекцию, не сохраняя напрямую как объект?


person Lakshin Karunaratne    schedule 16.04.2019    source источник


Ответы (1)


Вот как я решил проблему. Как упоминалось в вопросе, коллекция каждого объекта должна храниться в обоих объектах, когда речь идет о сопоставлении многих ко многим.

      /*-------Creating types-----------*/

     /*Incomplete type of BookCategory nested table- To keep a collection of categories which the book belongs*/
     CREATE TYPE BookCategory_tbltyp;
     /*Incomplete type of CategoryBook nested table - To keep a collection of books which the category contains*/
     CREATE TYPE CategoryBook_tbltyp;

     /*Creating Book type*/
     CREATE TYPE Book_objtyp AS OBJECT(
        Id VARCHAR2(6),
        Name VARCHAR2(30),
        BookCategoryList BookCategory_tbltyp
     );
     /*Creating Category type*/
     CREATE TYPE Category_objtyp AS OBJECT(
        Id VARCHAR2(6),
        Type VARCHAR2(30),
        CategoryBookList CategoryBook_tbltyp
     );

    /*Creating BookCategory object type*/
    CREATE TYPE BookCategory_objtyp AS OBJECT(
      CategoryId VARCHAR2(6),
      Category_ref REF Category_obj
    );

    /*Creating CategoryBook object type*/
    CREATE TYPE CategoryBook_objtyp AS OBJECT(
      BookId VARCHAR2(6),
      Book_ref REF Book_obj
    );

    /*Completing incomplete BookCategory and CategoryBook nested table types*/
    CREATE OR REPLACE TYPE BookCategory_tbltyp AS TABLE OF BookCategory_objtyp;

    CREATE OR REPLACE TYPE CategoryBook_tbltyp AS TABLE OF CategoryBook_objtyp;

    /*-------Creating tables-----------*/

     /*Creating book table with the nested collection table*/
     CREATE TABLE Book_objtab OF Book_objtyp(
        PRIMARY KEY (Id)
     )
     OBJECT IDENTIFIER IS PRIMARY KEY
     NESTED TABLE BookCategoryList STORE AS BookCategoryList_tab(
          PRIMARY KEY(NESTED_TABLE_ID, CategoryId)
        )
        ORGANIZATION INDEX COMPRESS)
     RETURN AS VALUE;

    /*Creating category table with the nested collection table*/
     CREATE TABLE Category_objtab OF Category_objtyp(
        PRIMARY KEY (Id)
     )
     OBJECT IDENTIFIER IS PRIMARY KEY
     NESTED TABLE CategoryBookList STORE AS CategoryBookList_tab(
          PRIMARY KEY(NESTED_TABLE_ID, BookId)
        )
        ORGANIZATION INDEX COMPRESS)
     RETURN AS VALUE;

    /*Foreign keys are not supported in nested tables. So the solution is to use SCOPE. 
According to oracle documentation SCOPE cannot be used in CREATE TABLE statement. 
So we have to use ALTER TABLE*/
    ALTER TABLE BookCategoryList_tab
        ADD (SCOPE FOR (Category_ref) IS Category_objtab);

    ALTER TABLE CategoryBookList_tab
        ADD (SCOPE FOR (Book_ref) IS Book_objtab);

Ограничение SCOPE отличается от ссылочного ограничения тем, что ограничение SCOPE не зависит от ссылочного объекта. Пример: объект строки в Category_objtab может быть удален, даже если он указан в столбце Category_ref вложенной таблицы.

Подробнее см. Образец приложения, использующего объектно-реляционные функции. Информация.

person Lakshin Karunaratne    schedule 16.04.2019