在对象关系数据库(Oracle)中映射多对多关系

Posted

技术标签:

【中文标题】在对象关系数据库(Oracle)中映射多对多关系【英文标题】:Map many to many relationship in object relational database (Oracle) 【发布时间】:2019-04-16 04:54:00 【问题描述】:

如果您在书籍和类别之间存在多对多关系,您可以根据How to design many-to-many relationships in an object database? 将其映射到如下所示的面向对象模型

Book 
 Collection<Category> categories


Category 
 Collection<Books> books

要在 ORDBMS 中的表中定义集合,您必须使用嵌套表。 (示例取自oracle网站Sample Application Using Object-Relational Features)

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 */

但是,最好保留引用集合而不是保留对象本身。

根据此答案Nested table primary and foreign key in Oracle ,无法将外键添加到嵌套表中。

1) 那么在对象关系数据库 (Oracle) 中映射多对多关系的最佳方法是什么?

2)如果答案是如上图在两个对象中保持两个集合,不直接作为对象存储,如何存储为引用集合呢?

【问题讨论】:

【参考方案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 列中被引用。

请参阅Sample Application Using Object-Relational Features 了解更多信息。

【讨论】:

以上是关于在对象关系数据库(Oracle)中映射多对多关系的主要内容,如果未能解决你的问题,请参考以下文章

hibernate 多对多关系映射

Hibernate映射关系:一对一对多和多对多

关系/对象映射 多对多关系(@ManyToMany 注释)重新认识

Hibernate多对多关系映射

Hibernate双向多对多对象关系模型映射

Hibernate学习笔记 — 多对多关系映射