2013-09-16 70 views
6

我已经使用了面向行的数据库设计很长一段时间,除了datawarehouse项目和大数据示例,我还没有使用OLTP应用程序的面向列的数据库设计。面向列的数据库vs面向行的数据库

我行面向表看起来像

ID, Make, Model, Month, Miles, Cost 
1 BMW Z3  12  12000 100 

有些人在我们的团队崇尚面向列的数据库设计。 他们建议所有的列名称应该是属性表中的属性名称。 然后另一个表格引用将有两列PropertyName和PropertyValue。

在.net代码中,我们读取每个键并比较并转换为强类型对象。代码真的很乱。

if (qwi.DomainCode == typeof(CoreBO.Base.iQQConstants.MBPCollateralInfo).Name) 
    { 
     if (qwi.RefCode == iQQConstants.MBPCollateralInfo.ENGINETYPE) 
     { 
      Aspiration = qwi.Value; 
     } 
     else if (qwi.RefCode == iQQConstants.MBPCollateralInfo.FUELTYPE) 
     { 
      FuelType = qwi.Value; 
     } 
     else if (qwi.RefCode == iQQConstants.MBPCollateralInfo.MAKE) 
     { 
      Make = qwi.Value; 
     } 
     else if (qwi.RefCode == iQQConstants.MBPCollateralInfo.MILEAGE) 
     { 
      int reading = 0; 
      bool success = int.TryParse(qwi.Value, out reading); 
      if (success) 
      { 
       OdometerReading = reading; 
      } 
} 
} 

此面向柱设计arguement是,我们不会有改变表模式和存储过程(我们仍然使用存储过程,而不是实体框架)。

好像我们正在进入真正的问题。行业导向设计是否被业界所接受。

+1

这个问题似乎与“面向列”(列存储)的DBMS无关。问题实际上是关于EAV设计模式。 – sqlvogel

+0

“我们仍然使用存储过程而不是实体框架” 我在许多较小和中等规模的项目中使用EF,并且不再认为EF是一种可行的方式。 从我测试和理解的情况来看,EF需要让内存中的数据能够操纵它(即更新),这是一个考虑到严肃工作时常常是门挡的情况。 – Mariusz

+0

“我们仍然使用存储的proc而不是实体框架” EF似乎需要内存中的数据才能修改它,所以这样简单: UPDATE dbo.MyTable SET Active = 1 WHERE Active = 0 对于大量的数据可能不是微不足道的使用EF(但我也喜欢它,因为它踢了屁股大的时间) – Mariusz

回答

10

我遇到了术语问题。您正在描述一个EAV结构(代表实体属性值)。另外:“面向列的”数据库通常是指将数据库中的每列与其他数据库分开存储的数据库(当我了解数据库时,这被称为“垂直分区”,但我不认为这种情况已经发生) 。例子包括Paracel和Vertica。

实体属性值数据库将实体的每个属性存储为单独的行。

您在特定结构中遇到的第一个问题是键入。一些属性是字符串,一些是数字。这成为EAV世界的管理噩梦。您可以将所有内容都存储为字符串(无法输入检查值并保证算术单词),也可以为不同类型的多列添加类型列(使查询更加复杂)。

类似地,约束和外键引用实现起来要困难得多。另外,由于您在每行重复实体ID和属性ID,因此数据通常会占用更多空间。 NULL值通常非常节省空间。

在OLTP方面,您有另一个问题。当你想插入一个实体时,你通常也想插入一堆属性。一个插入现在变成了许多插入,并且您将要开始在交易中包装这些插入,从而影响性能。

考虑到所有这些缺点,你可能会认为从来没有使用EAV模型。有一个地方给他们。当属性随时间变化时,它们特别有用。比如说,如果你有一个应用程序,用户可以通过标签输入他们自己的信息。在这种情况下,混合方法是最好的解决方案。使用具有许多列的常规关系表作为公共信息。使用EAV表为每个实体的可选信息。

4

来源:维基

  1. 面向列的组织都聚集需要计算在许多行,但仅用于数据的所有列的一个显着较小的子集时,更有效,因为读取数据的较小的子集可以比读取所有数据更快。
  2. 当为所有行同时提供新的列值时,面向列的组织效率更高,因为可以高效地写入列数据并替换旧列数据而不触及行的任何其他列。
  3. 当同一时间需要单行的许多列时,以及当行大小相对较小时,面向行的组织效率更高,因为可以使用单个磁盘查找来检索整行。
  4. 如果在同一时间提供所有列数据的情况下写入新行时,面向行的组织更高效,因为可以使用单个磁盘查找来写入整行。

实际上,面向行的存储布局非常适用于负载较重的OLTP类型的工作负载,并且交互式事务处理负载较重。面向列的存储布局非常适合类似OLAP的工作负载(例如数据仓库),这些工作负载通常涉及所有数据(可能是千兆字节)上的较少数量的高度复杂查询。

+1

当然你的正确,但问题没有要求柱状存储:-) – dnoeth

3

除了Gordon Linoff提到的问题,EAV数据模型也非常难以查询 - 找到所有的汽车制造商是宝马,12到24个月之间的月份和成本< 10000变成了一大堆讨厌的SQL ,尤其是如果你在数字上进行字符串比较...

0

通常,面向行和面向列是低级别(磁盘)上的存储机制。每个存储的好处取决于您的要求。在某些情况下,面向列的存储将会更好,在某些场景中,面向行的将是。

在Hbas数据库中,他们使用列组的概念,即列组。

面向行的区别在于,由行构成的逻辑表按行块存储一行,而面向列的存储每列块一列。

当我们正在解析查询时,面向行的结果是分析性的(如工资总额,工资平均值),但在我们需要访问行的各个细节或插入新记录时工作正常。尽管面向列的工作在分析查询上很好,但导致插入单个记录或访问行的所有细节时表现不佳。

你可以访问这个链接,这些链接描述了不同情况下他们的优点和缺点,以及他们的例子和他们的总结差异。

请点击这里:http://geekrandomstuff.blogspot.tw/2014/04/row-oriented-database-vs-column.html

0

从我的经验EAV是伟大的,用于存储应用程序设置IE浏览器。相对静态的数据,而不需要进一步加入和转换数据,除此之外就更不用说了。