continuous.md 2.0 KB
Newer Older
M
Mars Liu 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# 获取连续区间

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

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

M
Mars Liu 已提交
15
后续的结算系统需要连续的获取订单,以便处理一些顺序敏感的业务。但是撮合发生在很多个异步节点上,它们只能保证最终会将所有订单都保存到 orders 表,确保 id 列最终是连续的,但是最新插入的一段记录集有可能不连续。而我们希望结算系统成批
M
Mars Liu 已提交
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
的读取数据,以优化性能,那么在结算系统有它最后处理的订单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;
```