设计 STI、MTI 与单独的表格
我有一个使用设备进行身份验证的 Rails 3.1 项目。
我有多种用户类型,每种用户类型在数据库中都有非常不同的字段。我为每个模型都有不同的模型,但是模型之间有足够的重叠功能(例如消息传递),因此使用单个模型是有意义的。在处理不同类型用户之间的消息传递时,这尤其是一个问题。
我应该将它们全部保留为单独的表还是将它们移动到单个表中?考虑到我们一直在查找用户,多表继承实际上没有多大意义。明智的加盟成本太高了。
在表中为每个用户类型提供所有未使用的列感觉真的很脏。
想法?
I have a rails 3.1 project using devise for authentication.
I have several user types, each taking really remarkably different fields in the database. I had different models for each, but there was enough overlapping functionality between models such as messaging that it makes sense to have a single model. This was particularly an issue when dealing with messaging between users of different types.
Should I leave them all as individual table or move them into a single table? Multiple Table Inheritance really doesn't make a lot of sense given the fact that we'll be looking up users all the time. It would simply be too expensive join wise.
It just feels really dirty to have all the unused columns for each user type in the table.
Thought?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
就我个人而言,我认为未使用的列没什么大不了的,但是如果它真的困扰您,您可能想尝试一种非正统的解决方案。您是否考虑过“存储”不同类型用户不常见的所有属性?我正在谈论使用 attr_bucket 之类的插件。
本质上,您将向数据库表添加额外的列:
然后在每个不同的用户模型(从公共类继承)中,您将拥有类似的内容:
您将使用属性,就像它们以正常方式定义一样,但是当您将模型保存到数据库中时,所有这些属性都将通过 YAML 进行序列化并存储在
:non_common_attributes
列中。当您再次加载模型时,它们将被透明地反序列化。有一些警告,例如您不想通过任何分桶属性搜索用户(因为您无法对这些属性建立索引)等。但在您的情况下,它可能就是您想要的后。我不会太担心序列化和反序列化的成本,这可能不会成为问题,因为您不太可能同时保存/加载数千个用户。
事实上,我使用了类似的解决方案(但是是手工滚动而不是使用 gem),其中大多数属性需要加密的模型。我只是将所有属性存储在一起并对存储桶进行加密 - 很不错。
Personally I don't think that unused columns are that much of a big deal, however if it really bothers you, you might want to try an unorthodox solution. Have you considered 'bucketing' all the attributes which aren't common to your different types of users? I am talking about using a plugin such as attr_bucket.
Essentially you would add am extra column to you db table:
Then in each of your different user models (that inherit from a common class) you would have something like:
You would use the attributes just like they were defined in the normal way, but when you save the model into the database, all those attributes would be serialized via YAML and stored in the
:non_common_attributes
column. When you load the model again, they will be transparently deserialized.There are some caveats, such as the fact that you don't want to search for users via any of the bucketed attributes (since you can't index on those attributes) etc. But in your case it may just be what you're after. I wouldn't worry too much about the cost of serializing and deserializing, it probably won't be an issue since you're unlikely to be saving/loading thousands of users at the same time.
Infact, I have used a similar solution (but hand rolled rather than using a gem), with a model where most attributes need to be encrypted. I just bucket all the attributes together and encrypt the bucket - works a treat.