面向列的数据库与面向行的数据库

2023-12-29

我已经使用了很长时间的面向行的数据库设计,除了数据仓库项目和大数据示例之外,我还没有在 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;
           }
}
}

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

看来我们正面临真正的问题。面向列的设计是否得到业界广泛接受?


我对你的术语有疑问。您正在描述一个 EAV 结构(代表实体-属性-值)。

旁白:“面向列”数据库通常是指将每一列与其他列分开存储的数据库(当我了解数据库时,这称为“垂直分区”,但我认为这并不流行)。例子包括西沙群岛和Vertica。

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

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

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

在 OLTP 方面,还有另一个问题。当您想要插入实体时,通常还需要插入一堆属性。现在,一个插入已变成多个插入,您将需要开始将这些插入事务中,从而影响性能。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

面向列的数据库与面向行的数据库 的相关文章

随机推荐