我长时间使用面向行的数据库设计,除了数据仓库项目和大数据样本,我还没有使用面向列的数据库设计用于OLTP应用程序。
我的面向行的表看起来像
ID, Make, Model, Month, Miles, Cost
1 BMW Z3 12 12000 100
我们团队中的一些人主张面向列的数据库设计。 他们建议所有列名都应该是Property表中的属性名。 然后另一个表Quote将有两列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;
}
}
}
这个面向列的设计的争论是我们不必更改表模式和存储过程(我们仍然使用存储过程而不是实体框架)。
好像我们正在走向真正的问题。以列为导向的设计在业界得到广泛认可。
答案 0 :(得分:11)
我的术语有问题。您正在描述EAV结构(代表实体 - 属性 - 值)。
除此之外:“面向列的”数据库通常指的是一个数据库,它将每个列与其他列分开存储(当我了解数据库时,这被称为“垂直分区”,但我认为这并不存在)。例子包括Paracel和Vertica。
实体属性值数据库将实体的每个属性存储为单独的行。
您对特定结构的第一个问题是输入。一些属性是字符串,一些是数字。这成为EAV世界的管理噩梦。您可以将所有内容存储为字符串(无法输入检查值并保证算术字),或者为类型列包含不同类型的多个列(使查询更加复杂)。
同样,约束和外键引用更难实现。此外,因为您在每行重复实体ID和属性id,所以数据通常占用更多空间。 NULL
值通常非常节省空间。
在OLTP端,您还有另一个问题。如果要插入实体,通常还需要插入一组属性。现在,一个插入已经转换为许多插入,并且您将要在事务中开始包装它们,从而影响性能。
鉴于所有这些缺点,您可能会认为从不使用EAV模型。他们有一个地方。当属性随时间变化时,它们特别有用。比方说,如果您有一个应用程序,用户可以使用标签输入自己的信息。在这种情况下,混合方法是最佳解决方案。使用包含许多列的常规关系表来获取公共信息。使用EAV表获取每个实体的可选信息。
答案 1 :(得分:5)
资料来源:WIKI
实际上,面向行的存储布局非常适合类似OLTP的工作负载,这些工作负载的交互式事务负载更重。面向列的存储布局非常适合类似OLAP的工作负载(例如,数据仓库),这些工作负载通常涉及对所有数据(可能是太字节)的较少数量的高度复杂查询。
答案 2 :(得分:3)
除了Gordon Linoff提到的问题之外,EAV数据模型也非常难以查询 - 找到制造商是宝马的所有汽车以及12到24之间的月份和成本< 10000变成了一个讨厌的SQL的巨大混乱,特别是如果你正在对数字进行字符串比较......
答案 3 :(得分:0)
通常,面向行和面向列的是低级别(磁盘)的存储机制。每个存储的好处取决于您的要求。在某些情况下,面向列的存储将会更好,并且在某些情况下会面向行的存储。
在Hbas数据库中,他们使用列族的概念,即列组。
面向行的区别在于,由行组成的逻辑表每行存储一行,而面向列的每个存储块存储一列。
当我们触发分析(如工资总额,工资平均值)的查询时,行导向导致性能不佳,但是当我们需要访问行的隐含细节或插入新记录时工作正常。而面向列的分析查询在分析查询中工作正常,但导致单个记录的插入或访问行的所有细节的性能较差。
您可以访问此链接,其中描述了不同场景的优缺点以及示例及其摘要差异。
点击此处:http://geekrandomstuff.blogspot.tw/2014/04/row-oriented-database-vs-column.html
答案 4 :(得分:0)
根据我的经验,EAV非常适合存储应用程序设置,即。相对静态的数据,不再需要加入和转换数据,仅此而已。