【问题标题】:Column oriented database vs row oriented database面向列的数据库与面向行的数据库
【发布时间】:2013-09-20 19:41:13
【问题描述】:

我长期使用面向行的数据库设计,除了数据仓库项目和大数据样本,我没有为 OLTP 应用程序使用面向列的数据库设计。

我的面向行的表格看起来像

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

我们团队中的一些人提倡面向列的数据库设计。 他们建议所有列名都应该是属性表中的属性名。 然后另一个表 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;
           }
}
}

这种面向列的设计的论点是我们不必更改表架构和存储过程(我们仍然使用存储过程而不是实体框架)。

似乎我们正面临真正的问题。面向列的设计在行业中是否被广泛接受。

【问题讨论】:

  • 这个问题似乎与“面向列”(列存储)DBMS 无关。这个问题实际上是关于 EAV 设计模式的。
  • "我们仍在使用存储过程而不是实体框架" 我在许多中小型项目中使用 EF,并且不再认为 EF 是一种方法。根据我的测试和理解,EF 需要在内存中保存数据才能对其进行操作(即更新),这在考虑认真工作时通常是一个门塞。
  • "我们仍在使用存储过程而不是实体框架" EF 似乎需要内存中的数据才能修改它,所以很简单:UPDATE dbo.MyTable SET Active = 1 WHERE大量数据的 Active = 0 使用 EF 可能不是微不足道的(但我也喜欢它,因为它很重要)

标签: sql database database-design architecture


【解决方案1】:

根据我的经验,EAV 非常适合存储应用程序设置,即。相对静态的数据,无需进一步连接和转换数据,仅此而已。

【讨论】:

    【解决方案2】:

    一般来说面向行和面向列是底层(磁盘)的存储机制。每个存储的优劣取决于您的要求。在某些情况下,面向列的存储效果会更好,而在某些情况下,面向行的存储效果会更好。

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

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

    当我们发出分析查询(如工资总和、工资平均值)时,面向行的结果会导致性能不佳,但当我们需要访问行的单个详细信息或插入新记录时工作正常。而面向列在分析查询上工作得很好,但会导致插入单个记录或访问行的所有细节的性能很差。

    您可以访问此链接,该链接通过示例描述了不同场景的优缺点以及它们的总结差异。

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

    【讨论】:

      【解决方案3】:

      除了 Gordon Linoff 提到的问题之外,EAV 数据模型也非常难以查询 - 查找制造商为 BMW 并且月份在 12 到 24 之间且成本

      【讨论】:

        【解决方案4】:

        您的术语有问题。您正在描述 EAV 结构(代表 Entity-Attribute-Value)。

        顺便说一句:“面向列”的数据库通常是指将每一列与其他列分开存储的数据库(当我了解数据库时,这被称为“垂直分区”,但我认为这并不流行)。示例包括 Paracel 和 Vertica。

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

        您的特定结构遇到的第一个问题是打字。有些属性是字符串,有些是数字。这成为 EAV 世界中的管理噩梦。要么将所有内容存储为字符串(失去输入检查值和保证算术字的能力),要么在类型列中包含不同类型的多个列(使查询更加复杂)。

        同样,约束和外键引用更难实现。此外,由于您在每一行上重复实体 id 和属性 id,因此数据通常会占用更多空间。 NULL 值通常非常节省空间。

        在 OLTP 方面,您还有另一个问题。当你想插入一个实体时,你通常也想插入一堆属性。一个插入现在变成了许多插入,您需要开始将它们包装在事务中,从而影响性能。

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

        【讨论】:

          【解决方案5】:

          来源:维基

          1. 当需要针对多行计算聚合但仅针对所有数据列中明显较小的子集时,面向列的组织效率更高,因为读取较小的数据子集可能比读取所有数据更快。李>
          2. 当一次为所有行提供列的新值时,面向列的组织效率更高,因为可以高效地写入列数据并替换旧列数据,而无需触及行的任何其他列。
          3. 当同时需要单行的许多列时,面向行的组织效率更高,并且当行大小相对较小时,可以通过一次磁盘查找来检索整行。
          4. 如果同时提供所有列数据,则面向行的组织在写入新行时效率更高,因为只需一次磁盘寻道即可写入整行。

          在实践中,面向行的存储布局非常适合类似 OLTP 的工作负载,这些工作负载更多地承载着交互式事务。面向列的存储布局非常适合类似 OLAP 的工作负载(例如数据仓库),这些工作负载通常涉及对所有数据(可能是 TB)进行少量高度复杂的查询。

          【讨论】:

          • 当然你是对的,但问题并没有要求柱状存储:-)
          猜你喜欢
          • 2021-10-04
          • 2014-07-27
          • 2010-10-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-09-05
          • 2023-03-19
          相关资源
          最近更新 更多