链表:或如何正确存储活动队列列表

时间:2019-12-04 16:01:02

标签: javascript php mysql linked-list que

我正在为内部生产使用调度程序。 问题的故事是这样的: 我们有传入的“工作”,被发送到各个“机器”站。 我们将作业列表存储在mysql数据库中。 我想为生产协调员创建一个界面:负责将作业放到正确的机器上的人-这将由传入作业的列表以及代表该机器的工作队列的每台机器的列表组成。

我们需要执行的一些操作: -对列表进行重新排序,而无需大量写入sql DB-例如将作业放在que的顶部而不是que的末尾的机器上,让其余que正确更新(级联重编号就是我正努力避免)。

我担心的是可伸缩性,如果我们获得10万个工作,或者如果我们大量增加机器数量。

一些我们已经考虑过的事情-还在争论中: 创建具有以下结构的表:Jobkey,machineid,status,queposition。对机器ID而言,只有quequeque约束是唯一的。 这对于任何数量的机器都将是一件好事,但是快速更新que将需要在所有数据库中搜索每个机器ID,并且重新排序将不太容易。 另一个想法是要有一个prekey和postkey字段来模拟一个链接列表,其中prekey是最后一个que条目的表键,而post则指向下一个。 这样可以解决一些问题,但是解决问题可以归结为显示问题。

这些似乎都不能完全解决问题。

这似乎是一个足够普遍的问题,我敢肯定que的解决方案很不错-并且可以在不冲突的情况下修改所述列表的顺序。 在javascript,php和mysql中工作。

2 个答案:

答案 0 :(得分:0)

“排队位置”列的想法对我来说很有意义。 (继续,然后在该列上加上machine-id进行索引。)然后,在查询数据库时,ORDER BY ... DESC这个队列位置列和其他一些有意义的列 ... a时间戳。

队列位置值不必是连续的,也不是唯一的,并且简单的select.. MAX()查询可以告诉您当前(针对特定机器)的最高值。只需更新要撞到顶部的那一行即可。

如果您确实预期会有少量重新排序,则另一个简单的技巧是从旧的BASIC编程天开始借用,并使用增加了10的队列位置值。如果您希望定位非常准确,这将为您提供未使用的值。 (正如我所说,这些值不必是连续的,也不必是唯一的。)

答案 1 :(得分:0)

因此,您有10万个工作,您担心更新工作会花费多少工作? 100000确实不多。标准的mysql数据库应该能够相当快地处理这些查询。这让数据库重新使用所有相关项。

在mysql小提琴上创建模式需要187毫秒。

在我的本地开发机上运行它,插入100.000个虚拟行花费了650ms。排序顺序的实际更新?无法测量。

  

17:39:40创建表testid INT(11)NOT NULL AUTO_INCREMENT,machine_id INT NULL,job_id INT NULL,sort_order INT NULL,PRIMARY KEY(id),INDEX machinemachine_id ASC,sort_order ASC))受影响的0行0.016秒

     

17:39:40插入test(machine_id,job_id,sort_order)值(1,1,1)的1行影响0.000秒

     

17:39:40插入test(machine_id,job_id,sort_order)中,从test t 1条受影响的记录中选择t.machine_id,t.job_id,t.sort_order记录:1重复次数:0警告:0 0.000秒

     

17:39:40插入test(machine_id,job_id,sort_order)中,从test t,test t2,{}中选择t.machine_id,t.job_id,t.sort_order {1}} t3,test t4受影响的16行记录:16重复:0警告:0 0.000秒

     

17:39:40插入test(machine_id,job_id,sort_order)中,从test t,test t2,{}中选择t.machine_id,t.job_id,t.sort_order {1}} t3,test t4受影响的104976行记录:104976重复项:0警告:0 0.657秒

     

17:39:41更新测试集machine_id = 50,其中id> 49555和id <49999 443个受影响的行匹配的行:443已更改:443警告:0 0.000秒

     

17:39:41更新测试主内部联接(SELECT id,machine_id,@rowNumber:= @rowNumber + 10 AS rn FROM test,(SELECT @rowNumber:= 0)var where machine_id = 50 ORDER BY sort_order ASC) AS T ON MAIN.id = t.id SET MAIN.sort_order = t.rn其中MAIN.machine_id = 50443受影响的行匹配的行:443已更改:443警告:0 0.000秒

我的建议是:确保索引正常,并让数据库完成繁重的工作。在代码中进行一些测试,以利用数据库的最大潜能,使数据库服务器承受压力。让它在5分钟内完成一天的工作。我敢打赌,它将持续下去。

请确保您的sort_order排序之间始终相差10个步骤。这样,您始终可以在必须诉诸相关条目之前插入“ 9”个作业。 还有一个ligthweight关系表,该表将作业链接到计算机,仅将排序顺序作为额外数据,并可能添加了主键,以便能够轻松地直接更新作业关系。

以这个演示数据库为例:http://sqlfiddle.com/#!9/3cf11e/1

test
  

记录数:443;执行时间:11ms