简体   繁体   English

在Ruby on Rails应用程序中将表分成3个表

[英]Breaking up a table into 3 tables in Ruby on Rails application

I have a class called Stream that has many records in the database, and many more are constantly being added to it. 我有一个名为Stream的类,它在数据库中有许多记录,还有更多记录不断添加到它中。 A field in the streams table called rating can be -1, 0, 1, or be null. streams表中称为rating字段可以是-1,0,1或null。 I will say "rated" as having rating -1, 0, or 1, and "unrated" as having a null rating. 我会说“评级”为评级为-1,0或1,“未评级”为评级为空。 As of right now, there are 24M records in the streams table. 截至目前,流表中有24M条记录。 20M are rated, 4M are unrated. 额定20M,4M未评级。 The streams table needs to be queried often for the unrated records. 对于未评级的记录,需要经常查询流表。 The problem is, it takes time to query such a large table. 问题是,查询这么大的表需要时间。

I thought of breaking up the streams table into 3 separate tables. 我想把stream表分成3个单独的表。 There could be a rated streams table, an unrated streams table, and an old unrated streams table. 可能存在额定流表,未分级流表和旧的未分级流表。 The way it would work would be, a new stream is created. 它的工作方式是,创建一个新的流。 New records are unrated, so it would be placed in the unrated streams table. 新记录是未分级的,因此它将被放置在未分级的流表中。 If it is rated, it would be moved to the rated streams table. 如果它被评级,它将被移动到额定流表。 If it is unrated for more than a week, it would be moved to the old unrated streams table. 如果超过一周的时间,它将被移动到旧的未分级流表。 I would still need to be able to use methods and associations from the Stream class seamlessly, like: 我仍然需要能够无缝地使用Stream类中的方法和关联,例如:

buzz.rated_streams.first
interest.unrated_streams.first
user.old_streams.first
RatedStream.find(1).buzz
UnratedStream.find(2).interest
OldStream.find(3).user

The unrated streams table could be queried much faster. 可以更快地查询未分级的流表。 The rated streams table would be useful for analysis. 额定流表可用于分析。 The old unrated streams table would be a dump for old data. 旧的未分级流表将是旧数据的转储。

I have some questions. 我有一些疑问。 Would breaking up the table be a good idea? 打破桌子是个好主意吗? If so, how would I do it to keep everything from breaking, and use the same methods and associations from the Stream class? 如果是这样,我将如何保持一切不会破坏,并使用Stream类中相同的方法和关联? If breaking up the table is a bad idea, what should I do instead? 如果打破桌子是一个坏主意,我应该怎么办呢?

I think this is a baaaaad idea. 我认为这是一个baaaaad的想法。 A lot of custom code (which is not guaranteed to work). 很多自定义代码(不保证可以工作)。

You should create an index on rating instead. 您应该创建一个rating索引。 This will likely solve all your problems with queries (you might want to make it covered also). 这可能会解决您查询的所有问题(您可能也希望将其覆盖 )。

A good design depends on why you need to frequently query for a boolean property with 4 million matches. 一个好的设计取决于你为什么需要经常查询具有400万个匹配项的布尔属性。 Are you maintaining a to-do list of streams to rate? 您是否维护要对流进行的待办事项列表? Are you showing a "number of unrated streams" counter? 你是否展示了“未分级流”的数量? Are you querying by some other property as well? 您是否也被其他一些酒店查询?

Assuming the first, you could do something like 假设第一个,你可以做类似的事情

  • Have most of the information about a stream in the streams table. streams表中获得有关流的大部分信息。
  • Create a streams_ratings table which belongs_to :streams and has the rating 创建一个streams_ratings表,其中包含belongs_to :streams并具有评级
  • Create streams_tasks table which belongs_to :streams and has the priority, the assigned rater, the assignment date, etc. Index by assignee. 创建streams_tasks表,其中belongs_to :streams并具有优先级,分配的评估者,分配日期等。受让人的索引。
  • Find a stream that needs to be rated with StreamTask.first(:assignee => 'unassigned').stream . 找到需要使用StreamTask.first(:assignee => 'unassigned').stream评分的流StreamTask.first(:assignee => 'unassigned').stream You can used a named scope to make this smoother. 您可以使用命名范围来使此更平滑。
  • When you're done, create a new StreamRating and delete the StreamTask 完成后,创建一个新的StreamRating并删除StreamTask

不确定您使用的是哪个数据库,但您可以对表进行分区以帮助提高性能。

There turned out to be another way to write the query I was running that was so slow. 原来是另一种编写我正在运行的查询的方法,这种方式非常慢。 Instead of this which took 2 minutes or more: 而不是花了2分钟或更长时间:

user.streams.unrated.all( :conditions => "", :order => "id DESC", :limit => 10 ) user.streams.unrated.all(:conditions =>“”,:order =>“id DESC”,:limit => 10)

This works almost instantly: 这几乎立即起作用:

user.streams.unrated.find( :all, :conditions => "", :order => "id DESC", :limit => 10 ) user.streams.unrated.find(:all,:conditions =>“”,:order =>“id DESC”,:limit => 10)

I don't know what the difference could be. 我不知道有什么区别。 I gave Sergio the check since his was the best answer. 我给了Sergio支票,因为他是最好的答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM