Mysql 如何处理数据库中的大量记录存储以供用户授权?

Mysql 如何处理数据库中的大量记录存储以供用户授权?,mysql,sql,ruby-on-rails,ruby,ruby-on-rails-3,Mysql,Sql,Ruby On Rails,Ruby,Ruby On Rails 3,我正在使用RubyonRails3.2.2和MySQL。我想知道,在与一个类相关的数据库表中存储与其他两个类相关的所有记录(针对其实例的每个“组合”)是否“可取”/“可取” 也就是说,我有用户和文章模型。为了存储所有用户文章授权对象,我想实现一个ArticleUserAuthorization模型,以便 给定N个用户和M个文章,有N*M个ArticleUserAuthorization记录 因此,我可以如下所示陈述和使用ActiveRecord::Associations: class Arti

我正在使用RubyonRails3.2.2和MySQL。我想知道,在与一个类相关的数据库表中存储与其他两个类相关的所有记录(针对其实例的每个“组合”)是否“可取”/“可取”

也就是说,我有
用户
文章
模型。为了存储所有用户文章授权对象,我想实现一个
ArticleUserAuthorization
模型,以便 给定N个用户和M个文章,有N*M个
ArticleUserAuthorization
记录

因此,我可以如下所示陈述和使用
ActiveRecord::Associations

class Article < ActiveRecord::Base
  has_many :user_authorizations, :class_name => 'ArticleUserAuthorization'
  has_many :users, :through => :user_authorizations
end

class User < ActiveRecord::Base
  has_many :article_authorizations, :class_name => 'ArticleUserAuthorization'
  has_many :articles, :through => :article_authorizations
end
类文章“ArticleUserAuthorization”
拥有\u多个:用户,:通过=>:用户\u授权
结束
类用户'ArticleUserAuthorization'
拥有多篇:文章,:至=>:文章
结束
但是,上述存储所有组合的方法将导致一个包含数十亿行的大型数据库表!!!此外,理想情况下,我计划在创建
用户
文章
对象时创建所有授权记录(也就是说,我计划一次创建前面提到的所有“组合”,或者最好是在“延迟”中创建批处理…无论如何,此过程会创建其他数十亿的数据库表行!!!)并在销毁时生成代理(通过删除数十亿的数据库表行!!!)。此外,我计划在更新
用户
文章
对象时立即读取并更新这些行

因此,我的疑问是:

  • 这种方法是否“可取”/“可取”?例如,可能会出现什么样的性能问题?或者,使用非常大的数据库表管理/管理数据库是一种糟糕的“方式”/“处方”吗
  • 在我的情况下,我可以/可以/应该如何继续(也许,通过“重新思考”如何以更好的方式处理用户授权)

注意:我会使用这种方法,因为为了在检索
用户
文章
对象时仅检索“授权对象”,我认为我需要“原子”用户授权规则(即,每个用户和文章对象一条用户授权记录),因为系统不基于“管理员”之类的用户组,“已注册”等等。因此,我认为
ArticleUserAuthorization
表的可用性可以避免在每个检索到的对象上运行与用户授权相关的方法(注意:这些方法涉及一些可能会降低性能的MySQL查询-请参阅示例“授权”方法实现),方法是“访问/加入
ArticleUserAuthorization
表,以便仅检索“用户授权”对象。

事实上,如果您希望每个用户拥有文章级权限,则需要一种方法将
用户
与他们可以访问的
文章
关联起来。这要求您至少需要N*a(其中a是唯一许可的物品数量)

正如您所建议的,实现这一点的3NF方法是设置一个
UsersArticles
set。。。这将是一张非常大的桌子(正如您所指出的)

考虑到这张表会被大量访问。。。 在我看来,这似乎是稍微非规范化的方法(甚至是noSQL)更合适的情况之一

考虑Twitter用于其用户关注者表的模型:

这些文章中的一个例子是Twitter上的一个教训,从规范化的表中查询追随者会给
用户
表带来巨大压力。他们的解决方案是对关注者进行非规范化,以便将用户的关注者存储在各自的用户设置中

去规范化很多。单枪匹马救了他们。例如,它们将所有用户ID和朋友ID存储在一起,从而避免了大量代价高昂的连接。 -避免复杂的连接。 -避免扫描大型数据集


我设想可以使用类似的方法来提供文章权限,并避免一个压力巨大的
UsersArticles
单表。

如果真的有可能“一个包含数十亿行的大型数据库表”,那么也许您应该围绕一个人口稀少的表

大型数据库表会对系统查找相关行的速度造成重大性能挑战。这里确实需要索引和主键;但是,它们增加了存储需求,还需要在添加、更新和删除记录时维护CPU周期。即使如此,重载数据库系统也有分区特性(请参阅),可以解决这样的行位置性能问题

假设在没有返回行的情况下可以使用某些(可计算或常量)默认值,则填充稀疏的表可能可以达到此目的。仅在需要默认值以外的内容时插入行。人口稀少的表将需要更少的存储空间,系统将能够更快地定位行。(使用用户定义的函数或视图可能有助于保持查询的直观性。)

如果您真的无法让一个人烟稀少的表为您工作,那么您将陷入困境。也许您可以将那个巨大的表组合成一个较小的表集合,但如果您的数据库系统支持分区,我怀疑这是否有帮助。此外,一组较小的表有助于进行messier查询

因此,假设您有数百万或数十亿的用户,他们或可能没有关于系统中数百万或数十亿文章的特定权限。那么,在业务层面上呢
@article = Article.find(34)
@users = User.find(@article.user_authorizations.split(','))
class User < ActiveRecord 
   after_save :update_articles_authorizations
   def update_articles_authorizations
     #...
   end
end