在表格中移动行的有效方法?

时间:2013-03-06 23:48:42

标签: mysql database-design

这是一个很长的问题,因为我想解释这个问题的所有细节。

系统描述

我们有一个来自外部系统的传入消息队列。 消息立即存储在例如消息中。 INBOX表。几个线程工人 从表中获取作业块(首先用UPDATE标记一些消息, 然后选择标记的消息)。工人不处理消息, 他们将它们分配给不同的内部组件(称为“处理器”), 取决于消息命令。

每条消息包含多个文本字段(最长的是200个varchars), 几个ID和一些时间戳等;总共10-15列。

处理消息的每个内部组件(即处理器)的工作方式不同。 有些人立即处理消息,其他人触发一些长时间的操作, 甚至通过HTTP与系统的其他部分进行通信。其他 单词,我们不能只处理来自INBOX的消息然后将其删除。 我们必须使用该消息一段时间(异步任务)。

但是,系统中没有太多处理器,最多10个。

消息都是内部的,即用户浏览并不重要 他们,分页等。用户可能需要处理相关消息的列表, 但这不是关键任务功能,所以它不一定要快。 有时可能会删除一些无效消息。

重要的是要强调预期的流量可能会很高 - 而我们却没有 由于数据库设计不好而需要瓶颈。数据库是MySql。

决策

其中一个决定是不要为所有消息都有一个大表,一些标志列将指示各种消息状态。想法是每个表 处理器;并移动消息。例如,收到的消息将存储在INBOX中,然后由调度员移动到某些例如PROCESSOR_1表,最后移到ARCHIVE表。不应该超过2个这样的动作。 w ^

在处理状态时,我们允许使用标志来指示特定于处理的状态(如果有的话)。换句话说,PROCESSOR_X表可以跟踪消息的状态;因为当前正在处理的消息数量会明显减少。

这样做的原因是不要为所有事情使用一张BIG表。

问题

由于我们正在传递信息,我想知道这是多么昂贵的大量。以下哪种情况更好:

(A)具有所有单独的类似表,如所解释的那样,并移动完整的消息行,例如:从INBOX读取完整行,写入PROCESSOR表(带有一些额外的列),从INBOX中删除。

(B)为了防止内容的物理移动,如何有一个只存储内容的大MESSAGES表(并且仍然不是状态)。如上所述,我们仍然会有其他表,但它们只包含消息和其他列的ID。所以现在,当消息即将移动时,我们实际上移动的数据要少得多 - 只是ID。消息的其余部分始终未经修改地保留在MESSAGE表中。

换句话说,一个较小的表和一个巨大的表之间的sql连接是否有惩罚?

感谢您的耐心等待,希望我足够清楚。

1 个答案:

答案 0 :(得分:0)

解决方案B的原因如下:

  1. 移动大量数据不会占用内存
  2. I / O操作较少
  3. 数据库碎片较少
  4. 在表格列中使用标记:布尔字段(读取,存档,删除...)并适当地设置它们。 另一个优化是在服务器不忙时推迟冗长/繁重的任务。这种优化不能由操作系统或数据库完成,因为它需要业务意识。