我是否真的需要使用活动记录为rails中的子表创建一个ID?

时间:2010-09-19 17:34:18

标签: ruby-on-rails database database-design

我有一个has_one:profile的用户模型(sql表)。 配置文件具有user_id以引用用户对象。 我真的需要有profile_id列吗?

有哪些优点和缺点? 我猜一个优点是表格的大小将是1个较小的。 有什么缺点?

4 个答案:

答案 0 :(得分:1)

没有。你不需要id。但是你需要主键,它可能是表中的其他列。自然地,主键意味着值必须是唯一的而不是空的。

只需创建没有id列的表:

create_table "profiles", :id => false, primary_key => 'user_id' do |t|
  t.integer "user_id"
  #...
end

然后在模特中:

class Profile < ActiveRecord::Base
  set_primary_key 'user_id'
end

表格不应该创建自动增量或音序器 - 只需检查一下。如果您使用关联方法(user.profile.create(...)),则应由您或框架设置该值。

缺点:有些插件可能会让'id'成为PK,但这意味着它们写得不好。

答案 1 :(得分:0)

使用配置文件的belongs_to :user关联,如果您希望下次从数据库加载对象时关联可用,则最好将user_id存储在profiles中表。真的没有别的办法。但是,对于相反的关联,您当然不需要profile_id列。在解释profiles的{​​{1}}关联时,Rails非常聪明,可以查看User表。

也就是说,一般来说,单个整数数据库列的成本无需担心。在这种情况下,您不需要整数列,但考虑到用户的电子邮件地址在存储字节和索引大小方面会大几倍。

顺便提一下,has_one :profile列有一些缺点。据我所知,如果你在profile_id上重新分配profile属性,Rails甚至不会自动更新列。这种行为特别适用于User关联。

此外,在关系数据库中存储冗余信息是一件麻烦事,因为它可能会导致收缩。如果用户1指向配置文件1,但配置文件1指向用户2,您如何解释?有两个多余的事实,你信任哪一个?如果一个事实总是被另一个事实所信任,那么存储第二个事实的重点是什么?这与你的问题有些相似,但我认为值得一提。

答案 2 :(得分:0)

您的个人资料表不需要profile_id列。它已经有idbelongs_to User,因此您在个人资料表中只需要user_id。外键(配置文件所属的对象的id)跟在belongs_to之后。

Profile has_one :user
User belongs_to :profile
# User table includes its own id ('id') and profile_id for the belongs_to

User has_one :profile
Profile belongs_to :user
# Profile table includes its own id ('id) as well as user_id for the belongs_to

答案 3 :(得分:0)

我认为没有任何缺点,假设它实际上是一个重复的列,并不是破坏现有代码的遗留代码。

另一个优点是Rails受约定的指导。其中之一是主键是名为id的列,因为许多其他方法都依赖于它。如果你违反惯例,你将不得不调整你的代码的其他部分,并避免Rails自动带来的好处(他们说,他们会咬你