search 2013 adfgs

昨天在看Oracle UML对象建模这本书的时候遇到了个问题,由于学习Oracle时间还很短,对于嵌套表,索引组织表等概念还不是特别熟悉,尤其是刚开始用“对象-关系模型”的DDL来描述,就更有些模糊不清了。

为了更清楚的弄懂他,今天一大早就开始仔细看关于嵌套表和索引组织表的相关知识了,最后终于有了一点点心得,甚是开心:)

sample描述:
购物单 PO
购物单的详细购物列表项 PO_Detail
说明:1、购物单记录商店的每一次购物行为,包括编号和描述
2、购物列表单记录一次购物的所购物品详细列表

从上面的要求就可以看出这两个对象是一个组合的关系,子对象(购物购物列表单)是不能独立于父对象(购物单)而存在的,即每一个购物列表单都必须属于一个购物单

为了实现上述关系,我们可以通过嵌套表来实现,以下为“对象-关系模型”模型的DDL
先实现三个对象类型,其中一个是TABLE类型:

CREATE OR REPLACE TYPE po_detail_type AS OBJECT(
item_id NUMBER(10),
qty NUMBER(5)
)
/
CREATE OR REPLACE TYPE po_detail_table_type
AS TABLE OF po_detail_type
/

CREATE OR REPLACE TYPE po_type AS OBJECT(
po_id NUMBER(10),
desc_tx VARCHAR2(50),
customer_id NUMBER(10),
po_detail po_detail_table_type
)
/

然后就是创建实现该关系的表了
CREATE TABLE po OF po_type(
po_id NOT NULL PRIMARY KEY,
desc_tx NOT NULL,
customer_id NOT NULL REFERENCES customer(customer_id)--此处用到了一个关于客户的表,这里可以不去细究
)
NESTED TABLE po_detail STORE AS detail
我们看看上面的表
为了满足父子对象的组合关系,我们通过嵌套表来实现了
在逻辑方面,嵌套表与聚簇是等价的,但是嵌套表只能在“对象关系型”的语法中存在。而且嵌套表在虽然在逻辑上主表和子表是在一起,但是在物理上他们是分开存放的,而聚簇是存放在一起的,这就出现了一个问题,当查询需要同时提取子表和父表中的数据的时候嵌套表的性能就比不上聚簇了。

我们应该怎么来解决这个性能问题呢?
这里就用到了索引组织表(IOT)
在索引组织表中,数据的存放是和表上主码的索引一样方式组织的,也就是说在表中行在主码上是物理聚集的。所以这在像组合这样的父子关系建模中就非常有利。
故上面表的DDL我们可以优化如下:

CREATE TABLE po OF po_type(
po_id NOT NULL PRIMARY KEY,
desc_tx NOT NULL
customer_id NOT NULL REFERENCES customer(customer_id)
)
NESTED TABLE po_detail STORE AS po_detail(
(PRIMARY KEY(nested_table_id,item_id))
ORGANIZATION INDEX COMPRESS
);

这里将嵌套表做成了索引组织表,同时给了一个组合的主码(nested_tb_id,item_id),COMPREES子句说明了根据父表的po_id压缩存储空间,即保证不会在嵌套表的每一行中存储po_id,这样在性能上比前面的会有不少的提高,同时在空间上也有节约。

下面是对该表的一些相关操作
给该表插入一条数据:

INSERT INTO po
(po_id,desc_tx,customer_id,po_detail)
VALUES(1,'laisudyfjb',5231
po_detail_table_type(
po_detail_type(1,3)
po_detail_type(2,1)
)
)

查询特定购货单里面的详细购货项:

SELECT item_id,qty
FROM THE (SELECT po_detail FROM po WHERE po_id = 1)
ORDER BY item_id;

按购物但来统计购物详单:

SELECT COUNT(d.qty),p.po_id
FROM po p,THE (SELECT po_detail FROM po WHERE po_id = 1) d
GROUP BY p.PO_ID

给某以固定的购物单添加详单项:

INSERT INTO THE (SELECT po_detail FROM po WHERE po_id = 1)
(item_id,qty)
VALUES(3,5);

看完了要说点啥么?