continuous.md 1.9 KB
Newer Older
M
Mars Liu 已提交
1 2
# 获取连续区间

M
Mars Liu 已提交
3 4
SmartMarket 交易所的系统中,所有订单在生成时,都从一个 oracle Sequence 中获取唯一的 
序列号,完成交易计算后各个撮合程序将其插入如下的 orders 表中:
M
Mars Liu 已提交
5

M
Mars Liu 已提交
6
```mysql
M
Mars Liu 已提交
7 8 9
create table orders
(
    id      integer primary key,
M
Mars Liu 已提交
10
    content json
M
Mars Liu 已提交
11 12 13 14
    -- ignore other definitions...
);
```

M
Mars Liu 已提交
15 16 17 18 19
后续的结算系统需要连续的获取订单,以便处理一些顺序敏感的业务。但是撮合发生在很多个异步节
点上,它们只能保证最终会将所有订单都保存到 orders 表,确保 id 列最终是连续的,但是最新
插入的一段记录集有可能不连续。而我们希望结算系统成批的读取数据,以优化性能,那么在结算系
统有它最后处理的订单id的前提下,下面哪一个查询可以确保从这个id向前读取 id 连续 的一批
订单?
M
Mars Liu 已提交
20 21 22

## 答案

M
Mars Liu 已提交
23
```mysql
M
Mars Liu 已提交
24 25 26 27 28 29 30
with recursive r(id) as (select id
                         from orders
                         where id = $1
                         union
                         select d.id
                         from orders as d
                                  join r on d.id = r.id + 1)
M
Mars Liu 已提交
31
select orders.id, content
M
Mars Liu 已提交
32 33 34 35 36 37 38 39 40 41 42 43
from orders
         join r on orders.id = r.id;
```

## 选项

### A

没有办法构造一个简单查询实现这个功能,因为它的数据过滤条件递归的依赖查询结果。

### B

M
Mars Liu 已提交
44 45
```mysql
select data.id, content
M
Mars Liu 已提交
46 47 48 49 50 51 52
from orders
         join orders as r on orders.id = r.id - 1
where id = $1;
```

### C

M
Mars Liu 已提交
53 54
```mysql
select id, content
M
Mars Liu 已提交
55 56 57 58 59 60
from orders
where id in (select id from orders where id = id + 1);
```

### D

M
Mars Liu 已提交
61
```mysql
M
Mars Liu 已提交
62 63 64 65 66 67 68
with r as (select id
           from orders
           where id = $1
           union
           select d.id
           from orders as d
                    join r on d.id = r.id + 1)
M
Mars Liu 已提交
69
select orders.id, content
M
Mars Liu 已提交
70 71 72
from orders
         join r on orders.id = r.id;
```