Database design 数据库设计:跟踪每个用户的大量属性。如此之多,我可能会用完列(行存储空间)

Database design 数据库设计:跟踪每个用户的大量属性。如此之多,我可能会用完列(行存储空间),database-design,Database Design,我希望你能对我所关心的问题发表一些意见 我的数据库中有一个[用户]表,其中包含您期望的基本内容,如用户名、密码等 该应用程序要求我跟踪每个用户的大量属性。如此之多,我可能会用完列(行存储空间) 我试图添加一个包含UserID、PropertyKey和PropertyValue列的UserProperties表。这种方法非常符合需求 我担心的是,如果每个用户都有100个属性,那么当数据库中有100万用户时,我们将有100000000个属性行 我认为,如果用户ID上有聚集索引,访问速度仍然会非常快,

我希望你能对我所关心的问题发表一些意见

我的数据库中有一个[用户]表,其中包含您期望的基本内容,如用户名、密码等

该应用程序要求我跟踪每个用户的大量属性。如此之多,我可能会用完列(行存储空间)

我试图添加一个包含UserID、PropertyKey和PropertyValue列的UserProperties表。这种方法非常符合需求

我担心的是,如果每个用户都有100个属性,那么当数据库中有100万用户时,我们将有100000000个属性行

我认为,如果用户ID上有聚集索引,访问速度仍然会非常快,而且您实际上存储的数据量与使用mega columns方法时的数据量差不多

对性能问题有什么想法或想法吗?更好的数据库设计的想法

更新:

我一直在玩弄各种可能性,有一件事一直困扰着我。我需要非常频繁地查询其中一些属性,更糟糕的是,这些查询可能需要同时查找与这些属性中多达10个属性的条件匹配的所有用户

因此,我现在倾向于使用大列方法,但可能会将数据拆分为一个(或多个)单独的表,形成一对一的关系,并将其键入用户ID


我使用的是LinqToSql,虽然我认为有这么多列的表并不美观,但考虑到所有的挑战和权衡,我认为它可能是正确的,但我仍然渴望听到其他意见。

UserProperties表方法是我将如何建模的。正如您所建议的,userID上的聚集索引将意味着userID上的范围搜索将很快(即,对于与单个用户相关的所有属性)。还可能在UserID和PropertyKey上添加一个非聚集索引,以供每个用户选择单个键2值。

我怀疑用户表中的数据值太多,以至于行空间不足。您应该使用用户ID作为外键,只将1对多的值卸载到另一个表中。我发现您的用户表不太可能需要如此多的VARCHAR()字段,而这些字段无法从主值表转换为FKs。您维护的是什么类型的用户属性?

有没有办法对属性进行逻辑分组?您可能并不总是需要访问每个属性。此外,如果它们按逻辑分组,则更容易理解哪些属性可用、新属性适合何处等


分组可以与用户建立一对一或一对多的关系…

我们已经在几个项目中实施了UserProperties策略。这是一种常见的模式,使用适当的索引,我们从未遇到性能问题


另一个优点是,如果需要管理用户访问,可以有两个或多个属性表。例如,一般属性可以在PublicUserProps表中,而敏感信息(我不知道您在存储什么,但ssn、工资单信息等)可以在ControlledUserProps表中,只有一些用户具有读取或编辑权限。

我喜欢米奇·麦特和您自己描述的元表方法。但是,如果您有几个字段比其他字段(例如名称等)使用得更频繁,那么您可能会发现在用户表中包含这些字段是有益的,然后将用户表链接到UserProperties。我想这一切都取决于您设计的具体细节。

我可以想到几个选项:

  • 位字段:您可以在其中存储许多值,并且可以根据需要添加更多字段,甚至可以使用单独的表
  • 将最常见的设置放在用户表中,并将每个用户可能没有的设置放在第二个表中
  • 仅存储与默认设置不同的设置

    • 鉴于上述限制,我认为您真的没有其他选择

      好的,您可以在多个表之间拆分用户属性,这些表共享与主键(和聚集索引)相同的用户ID,但这可能会提高性能,也可能不会提高性能


      如果您只讨论100个属性,那么这可以由一个表处理(在MS-SQL中,最大值为1023个非键列);如果属性只是稀疏填充的,那么用户属性表可能更节省空间(只有探查器可以确定)

      您所描述的是实体属性值数据库,通常用于您描述的情况,即绑定到单个实体的稀疏数据

      E-A-V表很容易搜索。问题不在于查找行,而在于查找相关行

      为不同的实体提供不同的表提供了域建模,但它们也提供了一种较弱的元数据形式。在E-A-V中没有这样的抽象。(Java与E-A-V的类比是,声明所有函数的形式参数都是Object类型——因此不会进行类型检查。)

      我们可以很容易地查找属性键,但是没有任何东西可以对这些属性键进行分组

      维基百科上有一篇关于E-a-V的很好的文章,但现在就去读吧——这篇文章主要是一位作者的作品,并且被定为“改进”

      我认为,如果用户ID上有聚集索引,访问速度仍然会非常快,而且您实际上存储的数据量与使用mega columns方法时的数据量差不多

      我认为有了属性表,您最终将存储比实际需要多得多的内容。即用户id的额外索引、属性键列,以及属性值需要能够处理一般性质的值这一事实,这使得优化变得困难

      我的建议是试着把它放在一个适当的位置