continuous.md 2.0 KB
Newer Older
M
Mars Liu 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
# 获取连续区间

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

```postgresql
create table orders
(
    id      integer primary key,
    meta    jsonb default '{}'::jsonb,
    content jsonb default '{}'::jsonb
    -- ignore other definitions...
);
```

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

## 答案

```postgresql
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)
select orders.id, meta, content
from orders
         join r on orders.id = r.id;
```

## 选项

### A

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

### B

```postgresql
select data.id, meta, content
from orders
         join orders as r on orders.id = r.id - 1
where id = $1;
```

### C

```postgresql
select id, meta, content
from orders
where id in (select id from orders where id = id + 1);
```

### D

```postgresql
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)
select orders.id, meta, content
from orders
         join r on orders.id = r.id;
```