在本文中,我将分析(关系)数据库中组织数据的不同方式,在本文的例子中,我采用Oracle进行阐述,但其他关系数据库面临同样的问题,这些关系数据库组织数据的方式既有优点也有缺点,将给以区分,据此读者可判定适合他们的需要数据组织方式。

采用何种数据组织方式,取决于业务需求和开发需要,各种存储数据的方式可以实现。第一种组织数据的方式是横向结构,这是传统的数据存储方式,每一新的数据记录插入为一行,表中的列横向组织(布局),正如其名。第二种组织数据的方式为纵向结构,这是纵向存储数据的特定方式,表中仅包含两个实际数据列,其中之一用于标识行(但可有更多的列),数据以键/值对(key/value pair)方式存储,亦如其名。

纵向结构与横向结构的比较

下面是传统的横向表结构的例子:

表 HR

ID

First_Name

Last_Name

Dept

Sex

123

Vlad

Kofman

IT

M

234

Jim

Cramer

Marketing

M

456

Olimpia

Dukakis

Accounting

F

下表为纵向表结构的例子:

表 VR

ID

Key

Value

123

First_Name

Vlad

234

First_Name

Jim

456

First_Name

Olimpia

123

Last_Name

Kofman

234

Last_Name

Cramer

456

Last_Name

Dukakis

123

Dept

IT

234

Dept

Marketing

456

Dept

Accounting

123

Sex

M

234

Sex

M

456

Sex

F

正如所见,数据从 3行 x 4列 的矩阵(表HR)转换为 12行 x 2列 的矩阵(表VR),好像纵向表的行数等于横向表的记录数乘以横向表的列数,例如 3x4=12。然而,这种假设并不正确,将在下文中讨论该问题。

纵向数据存储的优点和缺点

基于预知的结构和列,以传统的横向结构存储数据具有很多优点,但也存在缺点。加入有一应用表单,其表单完全是动态的,无具体的字段数量和名称,用户可能随时创建一新的字段,并给定其名称和值,如何将其持久化到数据库中呢?

先假设另一不同的场景,其中表单基于业务需求创建,包含一些特定业务要求的字段,每一表单的数据存储在横向表中,其中每一字段插入一特定的列,每一表单存储为一行,一月后,应用上线,业务需要一新的字段,在表单中加入新的字段,UI及其存储逻辑需要调整,实际数据表也需要额外加入字段,应用也需要重新测试和部署。

I在开发人员无权直接访问数据库的环境中,DBA要直接介入更改实际表(结构)。

那么,若一月后需增加另一字段将如何呢?

上述两种应用场景,纵向数据结构可应用于差异的动态应用逻辑层及UI。由于数据仅以Key/Value对的两列存储,通过唯一的id与逻辑表单关联,对表单中字段的数量无限制;此外,纵向表结构下,一逻辑行可含有不同数量的字段,因此,纵向表结构的最大优点就是其可扩展性,但也存在很多缺点。

(葱香结构表)具备了可扩展性,但失去了对数据的可控性,意味着正常数据极难维护。不属于单表的逻辑行可能存储在一起,例如,纵向结构表中的Mutual Fund信息可与分析师名称和合同信息混合,而正常情况下此类信息应该存储在另外的表中,而以其外键id与Fund关联。

纵向结构表中也缺失数据类型。 因为列值仅有一类(例如 varchar),所有列值不仅需要类型,且在存储和检索时需要类型转换,且在纵向结构表中不可能存储特殊数据类型,诸如 Blob 或 Clob。

纵向结构表的另一缺点是数据的一致性。事实上,所有列名作为Key列的数据,利于用户(或应用)存储不同的名为key的可能的标识数据。例如,某用户可创建一新字段将其值“Oracle”作为“Company”存储,但另一用户可将“Oracle”作为“Organization”。

此外,操纵及应用纵向结构表也非常困难。为找到所需的逻辑行,需要许多自连接(self-join),因此,只有极少数的商业报表系统可工作于纵向表结构下并生成各类有意义的报表。

例如:从横向表中获取所有男性人员,select语句如下:

Select * from HR where sex like 'M'

要从纵向表中获取同样的数据,需要自连接(self-join),先获取id(集合),然后获取数据:

Select * from VR where id in

(Select id from VR

where key = 'sex'

and value = 'M')

许多开发人员,编写特定的数据库函数或存储过程来讲纵向结构的数据转换为横向结构的数据,以便易于获取报表或其它工作所需的数据。

纵向数据存储结构的变种为包含用于聚合逻辑数据行的定制算法,其含义为可用更多的ID列作为分组(group)属性,例如:

ID

Grouping

KEY

VALUE

123

1

name

Vlad

123

1

phone

555-555-5555

123

2

machine

Dell 560

123

2

ISP

Verizon

234

1

name

Mariya

234

1

phone

555-456-8392

234

1

email

m@mail.com

243

2

machine

Dell 1750

报表生成后,可轻易地基于“grouping”列分成不同的页面(page)或片段(section)。因此,上述纵向表可变成如下报表:

Report 1  
  Page 1  
Name Phone  
Vlad 555-555-5555  
Page 2  
Machine: Dell 560
ISP: Verizon
Report 2  
  Page 1  
Name Phone Email
Mariya 555-456-8392 m@mail.com
Page 2  
Machine: Dell 1750

可注意到不同形式的报表和页面其中数据的数目各不相同。

结论

上文中,揭示了在数据库表中持久化数据的不同方式,纵向结构所具有的优势和扩展性常被其短处掩蔽。然其可扩展性,通常是设计数据结构的仅有方法。此外,横向结构表可很好适用于正常的数据,也是关系数据库系统持久化数据的传统方式。软件及其数据库架构师对于特定的应用需求将决定采用何种数据库表的设计方式。

原文:http://www.developer.com/db/article.php/10920_3736011_2/Using-Vertical-and-Horizontal-Table-Structures-in-Oracle.htm

在Oracle中采用纵向和横向结构表相关推荐

  1. Oracle中select函数以及分组多表连接等重要点以及示例

    Oracle中select函数以及分组多表连接等重要点 函数 –函数 –内置函数和自定义函数 –单行函数:一条记录返回一个结果的 –多行函数|组函数|聚合函数:多条记录返回一条结果的 单行函数 单行函 ...

  2. oracle自动释放表空间,Oracle中关于清除数据和释放表空间

    一.表的重命名 flashback table test2 to before drop rename to test3;--[to test3]将表重命名 drop table test3 purg ...

  3. oracle中删除yuj_oracle三种删除表的方法解译

    DELETE FROM表名 WHERE 条件; 注意:删除记录并不能释放ORACLE里被占用的数据块表空间. 它只把那些被删除的数据块标成unused. 如果确实要删除一个大表里的全部记录, 可以用 ...

  4. android竖直和横向,如何在android中为纵向和横向模式定义不同的控件

    定义,在这两种资源的文件出现在你的代码 并在onCreate()在所有视图中Activity可以检查方向绑定的意见,你的类的对象. 示例. 在这里我们有包含在这两个文件的ImageView的,并在画像 ...

  5. 怎样在Word 2010文档中选择纵向或横向

  6. oracle中创建同义词(synonyms)表

    一.同义词概念和作用. Oracle的同义词(synonyms)从字面上理解就是别名的意思,和视图的功能类似,就是一种映射关系. 同义词作用之一:多用户的数据库中,有时候访问其他用户的表必须通过use ...

  7. oracle 如何删除表列,Oracle中增加,修改,删除表中的列

    内核对TCP REUSEPORT的优化 Q&A 当有人问起我关于reuseport的一些事的时候,我们的对话基本如下:Q1:什么是reuseport?A1:reuseport是一种套接字复用机 ...

  8. oracle中只存储两年数据,Oracle中作为永久存储机制的嵌套表的数据追加

    头几天有人问了一个问题: --创建类型minutiae create OR REPLACE type minutiae_t as object(x number(3,0),y number(3,0), ...

  9. oracle中dba所能查询的表,ORACLE--DBA常用查询

    –1. 查询系统所有对象 select owner, object_name, object_type, created, last_ddl_time, timestamp, status from ...

最新文章

  1. HDU 1596 find the safest road (Floyd)
  2. Visual Studio 2017 15.8概览
  3. Python读取保存在hdf5文件中的脑电数据
  4. 使用OKHttp3实现下载(断点续传、显示进度)
  5. 为什么一般不将'在制品转出科目'设为初级成本要素
  6. 前端JavaScript规范
  7. 开发们 点广告-赚点BT币
  8. A. Red and Blue Beans
  9. 【转】为什么博士叫PhD?
  10. 同花顺崩了上热一!网友:早盘血亏,你还不让我跑 官方回应...
  11. 树莓派服务器证书,【原创】在树莓派3上给Nginx部署免费HTTPS证书
  12. EMS设置发送连接器和接收连接器邮件大小
  13. 科技文献检索(九)——检索步骤和策略
  14. 【9】数据可视化:基于 Echarts + Python 实现的动态实时大屏 - 酒店行业
  15. 微信小程序 获取用户的昵称和头像
  16. Linux下删除特殊字符的文件或文件夹
  17. linux7 inittab没有,CentOs7 7个运行级别介绍,(CentOs7 inittab在使用systemd时不再使用)...
  18. stm32f103电子钟心得体会_STM32中的时钟
  19. CenOs安装jdk
  20. BloomFilter布隆过滤器

热门文章

  1. Excel输入汉字,出现Setup Error错误解决方法
  2. 导出excel,sheetName名字乱码
  3. VB运行后去除窗体标题栏且可改变窗口大小及移动窗体
  4. 阿里云第七代ECS现已上线
  5. ubuntu 离线下载安装包 及安装
  6. 健康老年人静息态EEG的功率和功能连接变化
  7. 智能数据可视化-雷达图的使用方法
  8. Ubnutu 部署 k8s 的一个坑
  9. android 浏览器 遥控器 光标,Unified Remote!让手机变身电视遥控器
  10. 分享63个JS幻灯片代码,总有一款适合您