2013-02-20 52 views
0

我在Oracle数据库中有一个有60列的表。以下是表格结构。Oracle表结构

ID NAME TIMESTAMP PROERTY1 ...... PROPERTY60 

该表格将有许多行。该表的大小将以GB为单位。但是,表结构的问题在于,如果必须添加新属性,我必须更改模式。为了避免这种情况,我想将表格结构更改为以下内容。

ID NAME TIMESTAMP PROPERTYNAME PROPERTYVALUE 

将会有一个样本行。

1 xyz 40560 PROPERTY1 34500 

这样我就可以解决问题,但表格的大小会变大。它在提取数据方面是否会对性能产生影响?我是Oracle的新手。我需要你的建议。

+0

为什么您必须更改架构以将新属性列添加到您的表中? – Wolf 2013-02-20 06:10:34

+0

可以说,我想在将来支持“PROPERTY61”,在这种情况下,如果我采用第一种方法,我必须更改模式。 – user2032118 2013-02-20 06:13:53

+0

这与EAV [实体,属性,值](http://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model)方案很接近。由于各种原因,这通常是一个糟糕的主意。这不会阻止人们使用它,但查询变得非常困难,甚至更难以确保数据的自我一致。 – 2013-02-20 06:14:28

回答

1

如果我要添加新的属性,我必须要改变架构

是实际的问题?在较新版本的Oracle中添加列已得​​到cheapermore convenient


但是,如果你仍然需要让你的系统的动态,从某种意义上说,你不必执行DDL新特性,下面简单EAV实施可能会是一个良好的开端:

CREATE TABLE FOO (
    FOO_ID INT PRIMARY KEY 
    -- Other fields... 
); 

CREATE TABLE FOO_PROPERTY (
    FOO_ID INT REFERENCES FOO (FOO_ID), 
    NAME VARCHAR(50), 
    VALUE VARCHAR(50) NOT NULL, 
    CONSTRAINT FOO_PROPERTY_PK PRIMARY KEY (FOO_ID, NAME) 
) ORGANIZATION INDEX; 

注意ORGANIZATION INDEX:整个表只是一个大的B-Tree,根本没有表堆。属于相同FOO_ID的属性在物理上紧密地存储在一起,因此检索已知FOO_ID的所有属性将很便宜(但不像所有属性位于同一行时便宜)。

您也可能要考虑是否是恰当的:

  • 在FOO_PROPERTY添加更多的索引(例如对属性名称或值搜索)。只要注意索引组织表中的二级索引的额外成本。
  • 切换FOO_PROPERTY PK中列的顺序 - 如果您主要搜索属性名称并且很少检索给定FOO_ID的所有属性。这也会使得index compression可行,因为索引的前沿现在是相对较宽的字符串(而不是窄整数)。
  • 对VALUE使用不同的类型(例如RAW,或者甚至是in-line BLOB/CLOB,这可能会影响性能,但也可能会提供额外的灵活性)。或者,您甚至可以为每种可能的值类型都有一个单独的表格,而不是将所有内容填入字符串中。
  • 将属性“声明”分离到自己的表中。这个表有两个关键字:除了字符串NAME之外,它还会有整数PROPERTY_ID,然后它可以用作FOO_PROPERTY中的FK而不是NAME(以更多JOIN的价格节省一些存储空间)。