我已经使用了很长时间的面向行的数据库设计,除了数据仓库项目和大数据示例之外,我还没有在 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(使用前将#替换为@)