我实现小型队列来处理该方法到达第一运行。我使用的数据库中的表来做到这一点。下面是表的结构(我嘲笑它在SQLite的):

        "id" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL ,
        "identifier" VARCHAR NOT NULL ,
        "priority_number" INTEGER DEFAULT 15,
        "timestamp" DATETIME DEFAULT CURRENT_TIMESTAMP,
        "description" VARCHAR

我试图写SQL给我这些过程可以运行下的行。下面是一些示例数据:

id  identifier  priority_number timestamp   description
1   test1   15  2009-01-20 17:14:49 NULL
2   test2   15  2009-01-20 17:14:56 NULL
3   test3   10  2009-01-20 17:15:03 NULL
4   test4   15  2009-01-20 17:15:08 NULL
5   test5   15  2009-01-20 17:32:23 NULL
6   test6   14  2009-01-20 17:32:30 NULL
7   test7   7   2009-01-20 17:32:38 NULL
8   test8   20  2009-01-20 17:32:57 NULL
9   test9   7   2009-01-21 13:47:30 NULL
10  test10  15  2009-01-21 13:50:52 NULL

如果我用这个SQL,我可以以适当的顺序数据:

select * from queue_manager order by priority_number, timestamp;

这会给我在顶部最低优先级数(最重要的)的项目,在这些优先号码,最早到顶部的队列(由时间戳)。

我可以运行此查询,并且只取第一行,但我宁愿做一个SQL查询,这将使我的过程,是在队列的顶部的一排(在本例以上数据与ID = 7)的行。

我试着做自我连接和子查询,但我必须有一个心理障碍 - 我似乎无法得到它的权利。

提前感谢!

修改

我忘了提,我找了一个独立于数据库查询。我SQLite中嘲笑他了,但我会在DB2或Oracle实现一个很好的可能性。我曾想过使用“限制1”式的经营者本人的查询,但那是不同的数据库引擎之间的不同。

有帮助吗?

解决方案

请参阅如果这个工程:

select * from queue_manager where priority_number = 
(select min(priority_number) from queue_manager) and  
timestamp = (select min(timestamp) 
from queue_manager qm2 
where qm2.priority_number = queue_manager.priority_number)

其他提示

select * from queue_manager order by priority_number, timestamp LIMIT 1;

对于这种所谓的“数据库独立性”,这是大多数现实世界任务的神话。作为一项规则,你甚至不能在创建数据库无关的方式架构。

如果您希望它是“并发安全”的东西像InnoDB的事:

1)添加 'IN_PROGRESS' 字段。

2)关闭自动提交

3)SELECT * FROM queue_manager其中IN_PROGRESS = 0 ORDER BY priority_number,时间戳LIMIT 1 FOR UDPATE;

4)UPDATE SET queue_manager IN_PROGRESS = 1其中id = X;

5)COMMIT

6)做的工作。然后删除该行的时候做满意。有一个'主进程的句柄/重新委派/清理旧“IN_PROGRESS”的工作。

要做到这一点,最好的方法是数据库依赖性的;这是一个有不同的检索特效为不同的目标的DBMS与所有游标或其他结构的开销要简单得多的事情。

按行的数量有限,不同的是在SQL的不同口味做,所以这取决于你正在使用可能会有办法做到这一点内置。例如,在MS SQL服务器:

SELECT TOP 1
     identifier,
     priority_number,
     timestamp,
     description
FROM
     dbo.Queue_Manager
ORDER BY
     priority_number,
     timestamp

要在ANSI兼容的SQL做到这一点,下面的方法应该工作:

    SELECT
         QM1.identifier,
         QM1.priority_number,
         QM1.timestamp,
         QM1.description
    FROM
         Queue_Manager QM1
    LEFT OUTER JOIN Queue_Manager QM2 ON
         QM2.priority_number < QM1.priority_number OR
         (QM2.priority_number = QM1.priority_number AND QM2.timestamp < QM1.timestamp)
    /* If you're concerned that there might be an exact match by priority_number
and timestamp then you might want to add a bit more to the join */
    WHERE
         QM2.identifier IS NULL

或者你可以尝试:

SELECT
     QM1.identifier,
     QM1.priority_number,
     QM1.timestamp,
     QM1.description
FROM
     Queue_Manager QM1
INNER JOIN
     (
          SELECT
               priority_number
               MIN(timestamp) AS timestamp,
          FROM
               Queue_Manager
          WHERE
               priority_number = 
                    (
                         SELECT
                              MIN(priority_number)
                         FROM
                              Queue_Manager
                    )
          GROUP BY
               priority_number
     ) SQ1 ON
          SQ1.priority_number = QM1.priority_number AND
          SQ1.timestamp = QM1.timestamp

这两种方法都占两个priority_number和时间戳精确匹配,所以,如果你认为这是可能的(甚至如果你没有),你需要添加一两行使用标识符走一个多层次或别的事情,保证唯一性。或者只写你的前端处理取回两行的偶然情况下(也许只是忽略第二 - 通过下一次你会得到它)。

测试每个方法,看看哪对你的作品好。

另外,如何大你期望的队列中得到什么?这可能是合理的,只是你的ORDER BY查询并且只前端获取第一条记录。

这部分和选择,为您提供最变种合适的相容性。也许使用游标是唯一或多或少普遍兼容的方式,但有一定的性能损失,可能不能使它值得(配置文件!)。

关系数据库是不是很大,在管理队列。

尝试在Windows世界看MSMQ,ActiveMQ的在Java世界或WebSphere MQ的在商业世界。

这些产品做一件事,管理队列,但他们做得很好。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top