对于我所担心的问题,我会很感激.
我的数据库中有一个[User]表,包含您期望的基本内容,如用户名,密码等...
此应用程序要求我为每个用户跟踪大量属性.这么多,我可能会用完列(行存储空间).
我很想添加一个UserProperties表,其中包含UserID,PropertyKey和PropertyValue列.这种方法非常符合要求.
我担心的是,如果每个用户都说100个属性,当数据库中有100万个用户时,我们将拥有100,000,000个属性行.
我认为,对于UserID上的聚集索引,该访问仍然会快速尖叫,并且您实际上存储的数据量与使用mega-columns方法时相同.
关于性能问题的任何想法或想法?想要更好的数据库设计?
谢谢!
更新:
首先,非常感谢所有伟大的回应!
我一直在四处寻找可能性,有一件事让我烦恼.我需要经常查询其中一些属性,更糟糕的是,这些查询可能涉及同时查找多达10个这些属性的标准的所有用户.
因此,我现在倾向于采用巨型列方法,但可能将数据拆分为一个(或多个)单独的表,从而形成一个一对一的关系,该关系键入UserID.
我正在使用LinqToSql,虽然我认为有这么多列的表格不够优雅,但我认为考虑所有的挑战和权衡,它可能是正确的,但我仍然渴望听到其他意见.
您所描述的是实体 - 属性 - 值数据库,它通常用于您描述的情况,稀疏数据绑定到单个实体.
EAV表易于搜索.问题不是找到行,而是找到相关的行.
为不同的实体提供不同的表提供了域建模,但它们也提供了弱形式的元数据.在EAV中没有这样的抽象.(Java类比EAV会声明所有函数的形式参数都是Object类型 - 所以你不会进行类型检查.)
我们可以轻松查找属性键,但没有任何组合这些属性键.
维基百科有一篇关于EAV的非常好的文章,但现在读它 - 它主要是一位作者的作品,并且是为了"改进".
我建议您考虑称为垂直分区的方法.这意味着您继续使用UserID键定义表,您可以将它们称为User1,User2等.当您达到数据库的最大行大小时,启动一个新表.这种方法的好处是值仍然是真正的数据库属性.这将最终节省处理此数据的时间,例如数据绑定.
要回答的关键问题是:这些属性真的是什么?它们是否代表您必须收集的有关用户的信息结构.如果是这样,建模它们的最佳方法是使它们成为列.必须求助于垂直分区的唯一原因是数据库的行大小限制.
另一方面,如果要求灵活的属性系统,那么一定要使用属性键/属性值系统.例如,如果允许用户动态定义自己的属性,那么您肯定需要键/值系统.但是,如果您了解数据的结构并合法地为用户确定了数百个属性,我会说键/值不是最好的方法.
作为旁注,我必须说你应该质疑具有大量属性的实体.它们可能是有效的,但是你很可能在概念层面遗漏了一些实体.换句话说,mabe所有这些属性与用户本身无关,而与用户相关的其他实体无关.