我长期使用面向行的数据库设计,除了数据仓库项目和大数据样本外,我没有为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;
}
}
}
这种面向列的设计的争论在于,我们不必更改表架构和存储的proc(我们仍在使用存储的proc而不是Entity Framework)。
似乎我们正在走向真正的问题。面向列的设计在业界已广为接受。
我在用您的术语时遇到麻烦。您正在描述一个EAV结构(代表Entity-Attribute-Value)。
另外:“面向列”数据库通常是指将每一列与其他列分开存储的数据库(当我了解数据库时,这被称为“垂直分区”,但我认为这并不流行)。示例包括Paracel和Vertica。
实体属性值数据库将实体的每个属性存储为单独的行。
特定结构的第一个问题是键入。一些属性是字符串,一些属性是数字。这成为EAV世界中的管理梦night。您要么将所有内容存储为字符串(失去键入检查值的能力并保证算术单词),要么将类型不同的多个列包含在类型列中(使查询复杂得多)。
同样,约束和外键引用很难实现。另外,由于您要在每一行上重复实体ID和属性ID,因此数据通常会占用更多空间。NULL
值通常非常节省空间。
在OLTP方面,您还有另一个问题。当您要插入实体时,通常还希望插入一堆属性。现在,一个插入已变成许多插入,您将需要开始将它们包装在事务中,从而影响性能。
考虑到所有这些缺点,您可能会认为永远不要使用EAV模型。有一个适合他们的地方。当属性随时间变化时,它们特别有用。说,如果您有一个应用程序,用户可以在其中添加带有标签的自己的信息。在这种情况下,混合方法是最佳解决方案。使用包含许多列的常规关系表来获取公共信息。将EAV表用于每个实体的可选信息。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句