Database design 单表继承是解决Rails问题的正确方法吗?
大家好, 我正在使用RubyonRails开发一个应用程序,我们需要为每个用户(例如,Facebook、MySpace、Google、SalesForce、Twitter、WordPress等)跟踪应用程序将代表用户访问的一系列外部服务。对于某些服务,我们需要存储(加密的)用户名和密码,对于某些服务,我们需要保存OAuth数据,对于某些OAuth2数据,等等。随着应用程序的发展,我们需要支持更多类型的帐户,每个帐户都有自己的身份验证数据集 每个用户都可以在应用程序中创建帖子,我们将获取这些帖子并将它们发送到外部服务,以便为用户发布。然后,我们跟踪对已发布帖子的回复(推特上的转发,Facebook上的喜欢/分享,等等) 因此:Database design 单表继承是解决Rails问题的正确方法吗?,database-design,activerecord,ruby-on-rails-3,single-table-inheritance,Database Design,Activerecord,Ruby On Rails 3,Single Table Inheritance,大家好, 我正在使用RubyonRails开发一个应用程序,我们需要为每个用户(例如,Facebook、MySpace、Google、SalesForce、Twitter、WordPress等)跟踪应用程序将代表用户访问的一系列外部服务。对于某些服务,我们需要存储(加密的)用户名和密码,对于某些服务,我们需要保存OAuth数据,对于某些OAuth2数据,等等。随着应用程序的发展,我们需要支持更多类型的帐户,每个帐户都有自己的身份验证数据集 每个用户都可以在应用程序中创建帖子,我们将获取这些帖子并
class用户
我正在争论对我的服务
类型使用单表继承(例如,WordpressService
,FacebookService
,TwitterService
,以及简单地序列化一个简单的散列以保存身份验证数据)和使用传统的,规范化方案,其中每种类型的服务都有自己的模型和表。我希望能够轻松地迭代与用户关联的所有服务,发布需要能够与任何类型的服务关联(例如,发布可能会发送到WordPress、Facebook或Twitter)
我可以使用传统的规范化方法实现这种模型关系吗?或者这正是STI想要解决的问题
谢谢。您将存储多少百万用户,每秒查询该表多少次?一般来说,这种类型的存储会影响您的物理设计,但对于大量应用程序,硬件将克服这些设计缺陷。如果您不是在大规模日期或大量事务上操作,那么您可以随意使用任何工具。虽然我仍然不确定这是否是解决此问题的“正确”方法,但我决定使用单表继承,以便轻松获得另一个模型
拥有的所有服务的列表(由于服务
的每个子类也是服务
,因此我可以调用model\u instance.services
来获取它们)
为了解决代码重复的问题,我创建了一个模块,用于任何模型,该模型应该有许多:服务,以及每种类型的服务:
module HasServices
extend ActiveSupport::Concern
included do
has_many :services
has_many :facebook_services
has_many :twitter_services
has_many :wordpress_services
end
end
服务也知道其子类,因此可以轻松创建菜单等:
class Service < ActiveRecord::Base
@child_classes = []
...
protected
def self.inherited(child)
@child_classes << child
super
end
def self.child_classes
@child_classes
end
end
类服务 @child_classes您可能想查看,它非常容易设置,并且可以处理存储许多服务的即时验证凭据。有几个RailsCast演示了如何设置。如果没有其他内容,您可以看到它们建议如何存储内容。作为STI的替代方案,您可以使用polymorph社区协会:
class AccountAuth < AR::Base
belongs_to :account
belongs_to :authentication, :polymorphic => true
end
# account_id :integer
# authentication_id :integer
# authentication_type :string
module Auth
#common logic
end
class FacebookAuth < AR::Base
include Auth
has_one :account_auth,:as=>:authentication
has_one :account, :through => :account_auth
end
class Account < AR::Base
has_many :account_auths
has_many :authentications, :through => :account_auths
end
类AccountAuthtrue
结束
#帐户id:整数
#身份验证\u id:integer
#身份验证类型:字符串
模块认证
#共同逻辑
结束
类FacebookAuth:身份验证
拥有一个:帐户,:通过=>:account\u auth
结束
类帐户:帐户\u身份验证
结束
可能会对你有所帮助。嗨,Stephanie,谢谢你的回答——但我指的更多的是Rails框架本身中的模型关系。现在我清醒过来了,我回去澄清了这个问题。:)用数据库设计来标记它让我感到困惑。
class AccountAuth < AR::Base
belongs_to :account
belongs_to :authentication, :polymorphic => true
end
# account_id :integer
# authentication_id :integer
# authentication_type :string
module Auth
#common logic
end
class FacebookAuth < AR::Base
include Auth
has_one :account_auth,:as=>:authentication
has_one :account, :through => :account_auth
end
class Account < AR::Base
has_many :account_auths
has_many :authentications, :through => :account_auths
end