class User include Mongoid::Document field :name, type: String has_many :topics, dependent: :destory end
class Topic include Mongoid::Document belongs_to :user field :title, type: String field :like_ids, type => Array. :default => [] end
删除 user,那么 user 所创建的 topics 全部删除,这没什么问题。 但是在其他 user 创建的 topic 中,like_ids 保存有被删除 user 的 id,应该怎么处理比较方便?
目前我能想出的苯的方法是删除 user 前,检索一遍所有其他 user 的 like_ids Array 中是否有被删除的 user.id,调用 pull () 在 like_ids Array 中去掉被删除的 user.id。但是如果日后 user 和 topic 记录多了之后,就会比较影响性能。
请指点一下,谢谢。
#10 楼 @joezhang 噢,ruby-china 源码我确实没有仔细看过,可能有性能考虑什么的。我说的是普通的数据库设计原则,你可以看这里,http://mongoid.org/en/mongoid/docs/relations.html#has_and_belongs_to_many
这样你就可以topic.liked_users
user.liked_topics
随便找了
#13 楼 @Yujing_Z谢谢,我前面举的例子是省略了的,其实我的设计是 like user 同样需要 reply something 的,你上面提到的多对多设计我也考虑了,不过觉得再加 reply 的时候不好处理,所以才想着仿照 ruby-china 的设计,呵呵,想着是大牛们的设计,肯定有他们的道理。大牛们能出来解答一下就好了。
我想大概就是因为:Many to many relations require usually double the amount of hits to the database to keep both sides of the relation in sync, since keys are stored on both sides. Due to this they are slower and should be used with caution.
#14 楼 @joezhang 你这个说法不对。ruby-china 没有 找一个用户关注的所有的帖子
这个功能,所以可以这样设计。而很明显你不一样,你有找到一个帖子所有 liked_user 的需求。所以你这样设计,想来想去也没有什么特别好的办法,那是因为根本没有这样的办法。只能每次都遍历,这样跟你设计成 N-to-N 来比,真的就有性能优势?我看未必,还带来了代码复杂度
而 reply 完全又是一个独立的功能,跟这个完全没有关系,很好处理
used with caution 不代表不能用,NN 是很常见的需求,确实会慢一点,但是就跟 kgen 说的一样,这么早的阶段担心个啥,怎么让程序员方便怎么来。加快开发速度
不过我当然不反对你这样每次都遍历一遍的做法,个人有个人追求
#7 楼 @Yujing_Z 其实就算有查找用户关注的所有帖子功能,也可能是在 Topic 单边存 like_ids 更快。
以前做过性能测试,不过测试脚本不小心删了,仅供参考,最好自己试一试 http://codecampo.com/topics/168
清除 User 的 like 数据我在 4 楼已经说了
Topic.where(like_ids: user.id).pull(:like_ids: user.id)