DolphinDB流数据表:创建与订阅

目录

    • 摘要
    • 一、流数据表概述
      • [1.1 流数据表特点](#1.1 流数据表特点)
      • [1.2 流表 vs 普通表](#1.2 流表 vs 普通表)
    • 二、创建流数据表
      • [2.1 基本创建](#2.1 基本创建)
      • [2.2 指定容量](#2.2 指定容量)
      • [2.3 创建带默认值的流表](#2.3 创建带默认值的流表)
      • [2.4 查看流表结构](#2.4 查看流表结构)
    • 三、流表订阅
      • [3.1 基本订阅](#3.1 基本订阅)
      • [3.2 订阅参数详解](#3.2 订阅参数详解)
      • [3.3 多订阅者](#3.3 多订阅者)
      • [3.4 取消订阅](#3.4 取消订阅)
    • 四、处理函数
      • [4.1 简单处理](#4.1 简单处理)
      • [4.2 过滤处理](#4.2 过滤处理)
      • [4.3 转换处理](#4.3 转换处理)
      • [4.4 聚合处理](#4.4 聚合处理)
      • [4.5 复杂处理](#4.5 复杂处理)
    • 五、批量处理
      • [5.1 批量处理配置](#5.1 批量处理配置)
      • [5.2 批量处理优势](#5.2 批量处理优势)
      • [5.3 批量处理最佳实践](#5.3 批量处理最佳实践)
    • 六、流表持久化
      • [6.1 启用持久化](#6.1 启用持久化)
      • [6.2 持久化模式](#6.2 持久化模式)
      • [6.3 持久化配置](#6.3 持久化配置)
      • [6.4 持久化监控](#6.4 持久化监控)
    • 七、流表高可用
      • [7.1 高可用配置](#7.1 高可用配置)
      • [7.2 故障恢复](#7.2 故障恢复)
    • 八、实战案例
      • [8.1 实时数据采集系统](#8.1 实时数据采集系统)
    • 九、总结
    • 参考资料

摘要

本文深入讲解DolphinDB流数据表的创建与订阅。从流表创建到订阅配置,从处理函数到批量处理,从持久化到高可用,全面介绍流数据表的核心操作。通过丰富的代码示例,帮助读者掌握流数据表管理的核心技能。


一、流数据表概述

1.1 流数据表特点

流数据表特点
实时写入
发布订阅
多订阅者
实时处理
核心功能
数据缓冲
持久化
高可用

1.2 流表 vs 普通表

特性 普通表 流表
写入 普通写入 实时写入
订阅 不支持 支持发布订阅
持久化 手动 自动持久化
容量 无限制 可配置容量

二、创建流数据表

2.1 基本创建

python 复制代码
// 创建流数据表
share streamTable(1:0, 
    `device_id`timestamp`temperature`humidity,
    [INT, TIMESTAMP, DOUBLE, DOUBLE]) as sensor_stream

// 参数说明:
// - 1:0 -> 初始容量:初始行数
// - `device_id`timestamp`temperature`humidity -> 列名
// - [INT, TIMESTAMP, DOUBLE, DOUBLE] -> 列类型
// - share -> 共享给所有会话
// - as sensor_stream -> 表名

2.2 指定容量

python 复制代码
// 指定初始容量
share streamTable(100000:0, 
    `device_id`timestamp`temperature`humidity,
    [INT, TIMESTAMP, DOUBLE, DOUBLE]) as sensor_stream

// 容量说明:
// - 100000:0 -> 预分配100000行空间,初始0行
// - 预分配可以提高写入性能

2.3 创建带默认值的流表

python 复制代码
// 创建带默认值的流表
share streamTable(10000:0,
    `device_id`timestamp`temperature`humidity`status,
    [INT, TIMESTAMP, DOUBLE, DOUBLE, SYMBOL]) as sensor_stream

// 写入时可以省略某些列
insert into sensor_stream (device_id, timestamp, temperature)
values (1, now(), 25.5)
// humidity和status使用默认值

2.4 查看流表结构

python 复制代码
// 查看流表结构
schema(sensor_stream)

// 查看流表数据
select count(*) from sensor_stream
select top 100 * from sensor_stream

三、流表订阅

3.1 基本订阅

python 复制代码
// 创建流表
share streamTable(1:0, 
    `device_id`timestamp`temperature,
    [INT, TIMESTAMP, DOUBLE]) as sensor_stream

// 创建结果表
share table(1:0,
    `device_id`timestamp`temperature,
    [INT, TIMESTAMP, DOUBLE]) as result_table

// 订阅流表
subscribeTable(, "sensor_stream", "handler1", -1,
    def(msg) {
        result_table.append!(msg)
    }, true)

// 参数说明:
// - 第一个参数: 数据库路径(流表为空)
// - "sensor_stream": 流表名
// - "handler1": 订阅名称
// - -1: offset,-1表示从最新开始
// - handler: 处理函数
// - true: batchSize,true表示批量处理

3.2 订阅参数详解

python 复制代码
// 完整订阅参数
subscribeTable(
    "",                    // database: 数据库路径
    "sensor_stream",       // tableName: 流表名
    "handler1",            // actionName: 订阅名称
    -1,                    // offset: 起始位置
    handler,               // handler: 处理函数
    true,                  // batchSize: 批量处理
    1000,                  // throttle: 节流时间(ms)
    true,                  // hash: 是否哈希分组
    10,                    // filter: 过滤条件
    true                   // reconnect: 是否自动重连
)

// offset参数说明:
// - -1: 从最新数据开始
// - 0: 从头开始
// - N: 从第N条开始

3.3 多订阅者

python 复制代码
// 创建多个订阅者
// 订阅者1:实时数据
subscribeTable(, "sensor_stream", "realtime_handler", -1,
    def(msg) {
        realtime_table.append!(msg)
    }, true)

// 订阅者2:告警检测
subscribeTable(, "sensor_stream", "alert_handler", -1,
    def(msg) {
        alerts = select * from msg where temperature > 30
        alert_table.append!(alerts)
    }, true)

// 订阅者3:数据持久化
subscribeTable(, "sensor_stream", "persist_handler", -1,
    def(msg) {
        loadTable("dfs://db", "sensor_data").append!(msg)
    }, true, 10000, true)

3.4 取消订阅

python 复制代码
// 查看订阅状态
getSubscriptionStat()

// 取消指定订阅
unsubscribeTable(, "sensor_stream", "handler1")

// 取消流表的所有订阅
unsubscribeTable(, "sensor_stream")

// 取消所有订阅
unsubscribeAll()

四、处理函数

4.1 简单处理

python 复制代码
// 简单处理:直接写入
def simpleHandler(msg) {
    result_table.append!(msg)
}

subscribeTable(, "sensor_stream", "simple", -1, simpleHandler, true)

4.2 过滤处理

python 复制代码
// 过滤处理
def filterHandler(msg) {
    filtered = select * from msg 
               where temperature between 20 and 30
    result_table.append!(filtered)
}

subscribeTable(, "sensor_stream", "filter", -1, filterHandler, true)

4.3 转换处理

python 复制代码
// 转换处理
def transformHandler(msg) {
    transformed = select device_id,
                         timestamp,
                         temperature,
                         temperature * 1.8 + 32 as fahrenheit,
                         humidity
                  from msg
    result_table.append!(transformed)
}

subscribeTable(, "sensor_stream", "transform", -1, transformHandler, true)

4.4 聚合处理

python 复制代码
// 聚合处理
def aggHandler(msg) {
    agg = select device_id,
                 avg(temperature) as avg_temp,
                 max(temperature) as max_temp,
                 min(temperature) as min_temp,
                 count(*) as cnt
          from msg
          group by device_id
    agg_result.append!(agg)
}

subscribeTable(, "sensor_stream", "agg", -1, aggHandler, true)

4.5 复杂处理

python 复制代码
// 复杂处理:多步骤
def complexHandler(msg) {
    // 步骤1:数据清洗
    cleaned = select * from msg 
              where temperature is not null
              and temperature between -40 and 100
    
    // 步骤2:数据转换
    transformed = select device_id,
                         timestamp,
                         temperature,
                         case when temperature > 30 then "高温"
                              when temperature < 10 then "低温"
                              else "正常" end as status
                  from cleaned
    
    // 步骤3:写入结果
    result_table.append!(transformed)
    
    // 步骤4:触发告警
    alerts = select * from transformed where status != "正常"
    alert_table.append!(alerts)
}

subscribeTable(, "sensor_stream", "complex", -1, complexHandler, true)

五、批量处理

5.1 批量处理配置

python 复制代码
// 批量处理:累积一定数量后处理
subscribeTable(, "sensor_stream", "batch_handler", -1,
    def(msg) {
        result_table.append!(msg)
    }, 
    1000)  // batchSize=1000,累积1000条后处理

// 批量处理 + 节流
subscribeTable(, "sensor_stream", "batch_throttle_handler", -1,
    def(msg) {
        result_table.append!(msg)
    },
    1000,   // batchSize=1000
    5000)   // throttle=5000ms,最多等待5秒

5.2 批量处理优势

优势 说明
减少IO 批量写入减少IO次数
提高吞吐 批量处理提高吞吐量
降低延迟 合理配置降低延迟

5.3 批量处理最佳实践

python 复制代码
// 最佳实践:根据场景选择批量大小
// 高吞吐场景:batchSize=10000
subscribeTable(, "sensor_stream", "high_throughput", -1,
    def(msg) { result_table.append!(msg) }, 10000)

// 低延迟场景:batchSize=100
subscribeTable(, "sensor_stream", "low_latency", -1,
    def(msg) { result_table.append!(msg) }, 100)

// 平衡场景:batchSize=1000, throttle=1000ms
subscribeTable(, "sensor_stream", "balanced", -1,
    def(msg) { result_table.append!(msg) }, 1000, 1000)

六、流表持久化

6.1 启用持久化

python 复制代码
// 启用持久化
enableTablePersistence(sensor_stream, true, true, 1000000)

// 参数说明:
// - async=true: 异步持久化
// - sync=true: 同步持久化(高可靠)
// - capacity=1000000: 内存中保留的最大行数

6.2 持久化模式

模式 说明 适用场景
async=true 异步持久化 高吞吐
sync=true 同步持久化 高可靠
async+sync 双重持久化 最高可靠

6.3 持久化配置

python 复制代码
// 高吞吐配置
enableTablePersistence(sensor_stream, true, false, 1000000)

// 高可靠配置
enableTablePersistence(sensor_stream, false, true, 1000000)

// 平衡配置
enableTablePersistence(sensor_stream, true, true, 1000000)

6.4 持久化监控

python 复制代码
// 查看持久化状态
getPersistenceStat()

// 查看持久化文件
persistenceDir()

七、流表高可用

7.1 高可用配置

python 复制代码
// 高可用流表配置
// 1. 启用持久化
enableTablePersistence(sensor_stream, true, true, 1000000)

// 2. 订阅配置自动重连
subscribeTable(, "sensor_stream", "ha_handler", -1,
    def(msg) { result_table.append!(msg) },
    true, 1000, false, , true)  // reconnect=true

// 3. 监控订阅状态
def monitorSubscription() {
    stat = getSubscriptionStat()
    for (row in stat) {
        if (row.status != "OK") {
            print("订阅异常: " + row.actionName)
        }
    }
}

7.2 故障恢复

python 复制代码
// 故障恢复流程
def recoverStream() {
    // 1. 检查流表状态
    stat = getStreamStat()
    
    // 2. 重新创建流表(如果需要)
    if (stat.rows() == 0) {
        share streamTable(1:0, 
            `device_id`timestamp`temperature,
            [INT, TIMESTAMP, DOUBLE]) as sensor_stream
        enableTablePersistence(sensor_stream, true, true, 1000000)
    }
    
    // 3. 重新订阅
    subscribeTable(, "sensor_stream", "handler", -1,
        def(msg) { result_table.append!(msg) }, true)
    
    print("流表恢复完成")
}

八、实战案例

8.1 实时数据采集系统

python 复制代码
// ========== 1. 创建流表 ==========
share streamTable(100000:0, 
    `device_id`timestamp`temperature`humidity`pressure,
    [INT, TIMESTAMP, DOUBLE, DOUBLE, DOUBLE]) as sensor_stream

// ========== 2. 启用持久化 ==========
enableTablePersistence(sensor_stream, true, true, 1000000)

// ========== 3. 创建分布式表 ==========
db = database("dfs://realtime_db", VALUE, 1..100)
schema = table(1:0, `device_id`timestamp`temperature`humidity`pressure,
               [INT, TIMESTAMP, DOUBLE, DOUBLE, DOUBLE])
db.createPartitionedTable(schema, `sensor_data, `device_id)

// ========== 4. 创建订阅 ==========
// 实时数据订阅
share table(1:0,
    `device_id`timestamp`temperature`humidity`pressure,
    [INT, TIMESTAMP, DOUBLE, DOUBLE, DOUBLE]) as realtime_data

subscribeTable(, "sensor_stream", "realtime", -1,
    def(msg) { realtime_data.append!(msg) }, true)

// 持久化订阅
subscribeTable(, "sensor_stream", "persist", -1,
    def(msg) {
        loadTable("dfs://realtime_db", "sensor_data").append!(msg)
    }, 10000, 5000)

// 告警订阅
share table(1:0,
    `device_id`timestamp`alert_type`value,
    [INT, TIMESTAMP, SYMBOL, DOUBLE]) as alert_table

subscribeTable(, "sensor_stream", "alert", -1,
    def(msg) {
        alerts = select device_id, timestamp,
                        `temperature_high as alert_type,
                        temperature as value
                 from msg
                 where temperature > 30
        alert_table.append!(alerts)
    }, true)

// ========== 5. 监控函数 ==========
def monitorStream() {
    print("=== 流表监控 ===")
    print("流表行数: " + string(exec count(*) from sensor_stream))
    print("实时数据行数: " + string(exec count(*) from realtime_data))
    print("告警数量: " + string(exec count(*) from alert_table))
    
    stat = getSubscriptionStat()
    print("订阅状态: " + string(stat.rows()) + " 个订阅")
}

monitorStream()

print("实时数据采集系统创建完成")

九、总结

本文详细介绍了DolphinDB流数据表的创建与订阅:

  1. 流表创建:基本创建、指定容量、查看结构
  2. 流表订阅:基本订阅、参数配置、多订阅者
  3. 处理函数:简单、过滤、转换、聚合处理
  4. 批量处理:批量配置、优势分析、最佳实践
  5. 流表持久化:启用持久化、模式选择、监控
  6. 高可用:配置、故障恢复

思考题

  1. 如何选择合适的批量大小?
  2. 流表持久化有什么作用?
  3. 如何设计高可用的流处理系统?

参考资料

相关推荐
再写一行代码就下班1 小时前
根据给定word模板,动态填充指定内容,并输出为新的word文档。(${aa}占位符方式且支持循环动态表格)
java·开发语言
彦为君2 小时前
JavaSE-05-字符串(全面深入)
java·开发语言·python·ai·ai编程
charlie1145141912 小时前
现代C++特性指南(4)——完美转发与移动语义实战
开发语言·c++·现代c++
kels88992 小时前
实时外汇api的节假日交易时间表,能自动判断休市吗?
开发语言·经验分享·笔记·python·金融·区块链
布吉岛的石头2 小时前
Java 程序员第 29 阶段-01:大模型微调入门:小样本业务适配方案
java·开发语言·人工智能
高林雨露2 小时前
Java 转 Kotlin 对照开发指南
java·开发语言·kotlin
我不是懒洋洋2 小时前
大语言模型(LLM)入门:从Transformer到ChatGPT
c语言·开发语言·c++
MY_TEUCK2 小时前
【Java 后端 | 微服务远程调用实战】Nacos + OpenFeign 从入门到公共模块抽取
java·开发语言·微服务
love_muming2 小时前
Java编程核心技巧全解析
java·开发语言·idea