这是一个有点长的问题,因为我想解释问题的所有细节。
系统描述
我们有一个来自外部系统的传入消息队列。消息会立即存储在例如 INBOX 表中。很少有线程工作者从表中获取作业块(首先用 UPDATE 标记一些消息,然后 SELECT 标记的消息)。工作人员不处理消息,他们根据消息命令将它们分派到不同的内部组件(称为“处理器”)。
每条消息都包含几个文本字段(最长的是 200 个 varchars)、几个 id 和一些时间戳等;总共 10-15 列。
每个处理消息的内部组件(即处理器)的工作方式不同。有些会立即处理消息,有些会触发一些长时间的操作,甚至通过 HTTP 与系统的其他部分进行通信。换句话说,我们不能只处理来自收件箱的消息,然后将其删除。我们必须使用该消息一段时间(异步任务)。
尽管如此,系统中的处理器并不多,最多 10 个。
消息都是内部的,即用户浏览它们、分页等并不重要。用户可能需要处理过的相关消息的列表,但这不是关键任务功能,因此它不必很快。有时可能会删除一些无效的消息。
重要的是要强调预期的流量可能会非常高——我们不希望因为糟糕的数据库设计而出现瓶颈。数据库是MySql。
决定
其中一个决定是不要为所有消息提供一个大表,其中有一些标志列将指示各种消息状态。想法是每个处理器都有表;并移动消息。例如,收到的消息将存储在 INBOX 中,然后由调度程序移动到某个例如 PROCESSOR_1 表,最后移动到 ARCHIVE 表。此类动作不应超过 2 个。W
在处理状态下,我们确实允许使用标志来指示特定于处理的状态(如果有)。换句话说,PROCESSOR_X 表可以跟踪消息的状态;因为当前正在处理的消息的数量将大大减少。
这样做的原因是不要对所有事情都使用一个 BIG 表。
问题
由于我们正在四处移动消息,我想知道这对于大容量来说有多昂贵。以下哪种情况更好:
(A) 将所有类似的表分开,就像解释的那样,并移动完整的消息行,例如从收件箱中读取完整的行,写入处理器表(带有一些附加列),从收件箱中删除。
或者
(B) 为了防止内容的物理移动,如何拥有一个只存储内容(并且仍然不是状态)的大 MESSAGES 表。如上所述,我们仍然有其他表,但它们只包含消息的 ID 和其他列。所以现在,当消息即将移动时,我们在物理上移动的数据要少得多——只是 ID。消息的其余部分始终未修改地保留在 MESSAGE 表中。
换句话说,一个小表和一个大表之间的 sql join 是否有惩罚?
感谢您的耐心等待,希望我足够清楚。