如何在 Tarantool 中执行客户端全面扫描?
How to perform a client-side full scan in Tarantool?
我需要在我的应用程序中持续遍历整个 space。
目前我正在使用批处理(例如经典的限制偏移方法),但是
它不能在一个事务中完成并且会不一致(例如,从已读取元组的子集中删除将导致丢失元组,因为偏移量已更改)。
此外,手动批处理不是那么人性化,我想要这样的东西:
rows, err := conn.Query(ctx, "SELECT id, title, tags FROM video")
if err != nil {
panic(err)
}
var videos []Video
for rows.Next() {
var v Video
if err := rows.Scan(&v.ID, &v.Title, &v.Tags); err != nil {
panic(err)
}
videos = append(videos, v)
}
这就是我如何在 go 和 postgresql 中执行 SELECT 整个 table,这将在内部缓冲并且仍然一致。
有没有办法在 Tarantool 中实现这一点?
可能回答可能与您的主题不完全相关,但我尝试描述没有SQL应该怎么做。
首先,Tarantool 不支持交互式事务 (https://github.com/tarantool/tarantool/issues/2016) 和服务器端游标。
您不能执行多个选择并确保它们之间的所有数据都没有被修改。
所以,如果您对这些限制感到满意,我们就继续吧。这是一个小例子。这里我使用官方的 Tarantool go connector (https://github.com/tarantool/go-tarantool)
spaceName := "tester"
indexName := "scanner"
idFn := conn.Schema.Spaces[spaceName].Fields["id"].Id // field number of Id
bandNameFn := conn.Schema.Spaces[spaceName].Fields["band_name"].Id
var tuplesPerRequest uint32
cursor := []interface{}{}
tuplesPerRequest = 10
for {
resp, err := conn.Select(spaceName, indexName, 0, tuplesPerRequest, tarantool.IterGt, cursor)
if err != nil {
panic(err)
}
if resp.Code != tarantool.OkCode {
panic(err)
}
if len(resp.Data) == 0 {
break // No more data
}
tuples := resp.Tuples()
for _, tuple := range tuples {
fmt.Printf("\t%v\n", tuple)
}
lastTuple := tuples[len(tuples) - 1]
cursor = []interface{}{lastTuple[idFn], lastTuple[bandNameFn]}
}
我应该注意一些事情。我不使用偏移量。切勿在 Tarantool 中使用偏移量!我使用“游标”。它是一组您已编制索引的字段加上一个迭代器(在我的示例中为 Gt)。简而言之,“偏移量”导致对 B-Tree 索引进行全面扫描,而建议的方法指定了一个扫描点 started/continued.
您可以为 lua 存储过程使用“调用”,而不是使用 Select 函数。例如。您想直接在 database/application 服务器级别过滤元组。
我需要在我的应用程序中持续遍历整个 space。 目前我正在使用批处理(例如经典的限制偏移方法),但是 它不能在一个事务中完成并且会不一致(例如,从已读取元组的子集中删除将导致丢失元组,因为偏移量已更改)。
此外,手动批处理不是那么人性化,我想要这样的东西:
rows, err := conn.Query(ctx, "SELECT id, title, tags FROM video")
if err != nil {
panic(err)
}
var videos []Video
for rows.Next() {
var v Video
if err := rows.Scan(&v.ID, &v.Title, &v.Tags); err != nil {
panic(err)
}
videos = append(videos, v)
}
这就是我如何在 go 和 postgresql 中执行 SELECT 整个 table,这将在内部缓冲并且仍然一致。
有没有办法在 Tarantool 中实现这一点?
可能回答可能与您的主题不完全相关,但我尝试描述没有SQL应该怎么做。
首先,Tarantool 不支持交互式事务 (https://github.com/tarantool/tarantool/issues/2016) 和服务器端游标。 您不能执行多个选择并确保它们之间的所有数据都没有被修改。
所以,如果您对这些限制感到满意,我们就继续吧。这是一个小例子。这里我使用官方的 Tarantool go connector (https://github.com/tarantool/go-tarantool)
spaceName := "tester"
indexName := "scanner"
idFn := conn.Schema.Spaces[spaceName].Fields["id"].Id // field number of Id
bandNameFn := conn.Schema.Spaces[spaceName].Fields["band_name"].Id
var tuplesPerRequest uint32
cursor := []interface{}{}
tuplesPerRequest = 10
for {
resp, err := conn.Select(spaceName, indexName, 0, tuplesPerRequest, tarantool.IterGt, cursor)
if err != nil {
panic(err)
}
if resp.Code != tarantool.OkCode {
panic(err)
}
if len(resp.Data) == 0 {
break // No more data
}
tuples := resp.Tuples()
for _, tuple := range tuples {
fmt.Printf("\t%v\n", tuple)
}
lastTuple := tuples[len(tuples) - 1]
cursor = []interface{}{lastTuple[idFn], lastTuple[bandNameFn]}
}
我应该注意一些事情。我不使用偏移量。切勿在 Tarantool 中使用偏移量!我使用“游标”。它是一组您已编制索引的字段加上一个迭代器(在我的示例中为 Gt)。简而言之,“偏移量”导致对 B-Tree 索引进行全面扫描,而建议的方法指定了一个扫描点 started/continued.
您可以为 lua 存储过程使用“调用”,而不是使用 Select 函数。例如。您想直接在 database/application 服务器级别过滤元组。