从 OceanBase 迁移数据到 DolphinDB
OceanBase 是一款金融级分布式关系数据库,具有数据强一致、高可用、高性能、在线扩展、高度兼容 SQL标准和主流关系数据库、低成本等特点,但是其学习成本较高,且缺乏金融计算函数以及流式增量计算的功能。
DolphinDB 是一款国产的高性能分布式时序数据库产品。支持 SQL 和使用类 Python 的语法来处理数据,学习成本很低。并且 DolphinDB 提供了 1500 多个函数,对于复杂的数据处理场景有很强的表达能力,极大地降低了用户开发成本。同时 DolphinDB 还具有强大的流式增量计算能力,能够满足用户实时数据的处理需求。
本文旨在为有从 OceanBase 迁移至 DolphinDB 需求的用户提供一份简洁明了的参考,整体框架如下:

1. 应用需求
很多之前使用 OceanBase 的用户不可避免地需要将数据迁移同步至 DolphinDB。DolphinDB 提供了多种灵活的数据同步方法,来帮助用户方便地把海量数据从多个数据源进行全量同步或增量同步。本文中的实践案例基于该需求,提供了将逐笔成交数据从 OceanBase 迁移至 DolphinDB 的高性能解决方案。
现有 2021.01.04 一天的逐笔成交数据,存储于 OceanBase。其部分数据示例如下:
SecurityID | TradeTime | TradePrice | TradeQty | TradeAmount | BuyNo | SellNo | TradeIndex | ChannelNo | TradeBSFlag | BizIndex |
---|---|---|---|---|---|---|---|---|---|---|
600035 | 2021.01.04T09:32:59.000 | 2.9 | 100 | 290 | 574988 | 539871 | 266613 | 6 | B | 802050 |
600035 | 2021.01.04T09:25:00.000 | 2.91 | 2900 | 8439 | 177811 | 36575 | 8187 | 6 | N | 45204 |
600035 | 2021.01.04T09:25:00.000 | 2.91 | 2600 | 7566 | 177811 | 3710 | 8188 | 6 | N | 45205 |
600035 | 2021.01.04T09:32:59.000 | 2.9 | 100 | 290 | 574988 | 539872 | 266614 | 6 | B | 802051 |
600035 | 2021.01.04T09:25:00.000 | 2.91 | 500 | 1455 | 177811 | 8762 | 8189 | 6 | N | 45206 |
600035 | 2021.01.04T09:32:59.000 | 2.9 | 100 | 290 | 574988 | 539873 | 266615 | 6 | B | 802052 |
600035 | 2021.01.04T09:30:02.000 | 2.9 | 100 | 290 | 18941 | 205774 | 44717 | 6 | S | 252209 |
600035 | 2021.01.04T09:32:59.000 | 2.9 | 100 | 290 | 574988 | 539880 | 266616 | 6 | B | 802053 |
600035 | 2021.01.04T09:30:02.000 | 2.9 | 100 | 290 | 18941 | 209284 | 46106 | 6 | S | 256679 |
600035 | 2021.01.04T09:32:59.000 | 2.9 | 200 | 580 | 574988 | 539884 | 266617 | 6 | B | 802054 |
2. 实现方法
从 OceanBase 迁移数据到 DolphinDB 的方法有以下三种:
- MySQL 插件
MySQL 插件是 DolphinDB 提供的用于导入 MySQL 数据的插件,同样也适用于 OceanBase 的 MySQL 模式。MySQL 插件配合 DolphinDB 脚本使用,与服务器在同一个进程空间内运行,能高效地完成 OceanBase 数据到 DolphinDB 的数据写入。
MySQL 插件提供如下函数,函数的具体使用请参考 DolphinDB MySQL Plugin
- mysql::connect(host, port, user, password, db)
- mysql::showTables(connection)
- mysql::extractSchema(connection, tableName)
- mysql::load(connection, table_or_query, [schema], [startRow], [rowNum], [allowEmptyTable])
- mysql::loadEx(connection, dbHandle,tableName,partitionColumns,table_or_query,[schema],[startRow],[rowNum],[transform])
- ODBC 插件
ODBC(Open Database Connectivity) 插件是 DolphinDB 提供的通过 ODBC 接口访问 支持 ODBC 协议开源产品。其使用方式与 MySQL 插件类似,本文不再赘述,感兴趣的读者可参考 ODBC 插件使用指南。
- DataX 驱动
DataX 是可扩展的数据同步框架,将不同数据源的同步抽象为从源头数据源读取数据的 Reader 插件,以及向目标端写入数据的 Writer 插件,理论上 DataX 框架可以支持任意数据源类型的数据同步工作。
DolphinDB 提供基于 DataXReader 和 DataXWriter 的开源驱动。DolphinDBWriter 插件实现了向 DolphinDB 写入数据,使用 DataX 的现有 reader 插件结合 DolphinDBWriter 插件,即可实现从不同数据源向 DolphinDB 同步数据。用户可以在 Java 项目中包含 DataX 的驱动包,开发从 OceanBase 数据源到 DolphinDB 的数据迁移软件。
DataX 驱动的开发基于 Java SDK,支持高可用。
实现途径 | 数据写入效率 | 高可用 |
---|---|---|
MySQL 插件 | 高 | 不支持 |
DataX 驱动 | 中 | 支持 |
3. 迁移案例与操作步骤
3.1 在 DolphinDB 创建表
针对上面的测试数据,我们需要在 DolphinDB 里创建对应的库表,用于存储迁移过来的数据。对于实际的数据,需要综合考虑被迁移数据的字段、类型、数据量,在 DolphinDB 是否需要分区,分区方案,使用 OLAP还是 TSDB 引擎等情况,去设计建库建表方案。一些数据存储库表设计实践,可以参考 DolphinDB 数据库分区教程
本例建表文件 createTable.dos 内容如下:
def createTick(dbName, tbName){if(existsDatabase(dbName)){dropDatabase(dbName)}db1 = database(, VALUE, 2020.01.01..2021.01.01)db2 = database(, HASH, [SYMBOL, 10])db = database(dbName, COMPO, [db1, db2], , "TSDB")db = database(dbName)name = `SecurityID`TradeTime`TradePrice`TradeQty`TradeAmount`BuyNo`SellNo`ChannelNo`TradeIndex`TradeBSFlag`BizIndextype = `SYMBOL`TIMESTAMP`DOUBLE`INT`DOUBLE`INT`INT`INT`INT`SYMBOL`INTschemaTable = table(1:0, name, type)db.createPartitionedTable(table=schemaTable, tableName=tbName, partitionColumns=`TradeTime`SecurityID, compressMethods={TradeTime:"delta"}, sortColumns=`SecurityID`TradeTime, keepDuplicates=ALL)
}dbName="dfs://TSDB_tick"
tbName="tick"
createTick(dbName, tbName)
从 OceanBase 迁移到 DolphinDB 的数据字段映射关系如下表:
OceanBase 字段含义 | OceanBase 字段 | OceanBase 数据类型 | DolphinDB 字段含义 | DolphinDB 字段 | DolphinDB 数据类型 |
---|---|---|---|---|---|
证券代码 | SecurityID | varchar(10) | 证券代码 | SecurityID | SYMBOL |
交易时间 | TradeTime | timestamp | 交易时间 | TradeTime | TIMESTAMP |
交易价格 | TradePrice | double | 交易价格 | TradePrice | DOUBLE |
交易数量 | TradeQty | int(11) | 交易数量 | TradeQty | INT |
交易金额 | TradeAmount | double | 交易金额 | TradeAmount | DOUBLE |
买方委托索引 | BuyNo | int(11) | 买方委托索引 | BuyNo | INT |
卖方委托索引 | SellNo | int(11) | 卖方委托索引 | SellNo | INT |
成交编号 | TradeIndex | int(11) | 成交编号 | TradeIndex | INT |
频道代码 | ChannelNo | int(11) | 频道代码 | ChannelNo | INT |
成交方向 | TradeBSFlag | varchar(20) | 成交方向 | TradeBSFlag | SYMBOL |
业务序列号 | BizIndex | int(11) | 业务序列号 | BizIndex | INT |
3.2 通过 MySQL 插件迁移
3.2.1 安装 MySQL 插件
MySQL 插件的安装参考 DolphinDB MySQL Plugin
3.2.2 同步数据
1. 运行以下命令加载 MySQL 插件
loadPlugin("ServerPath/plugins/mysql/PluginMySQL.txt")
2. 运行以下命令建立与 OceanBase 的连接
conn = mysql::connect(`127.0.0.1,2881,`root,`123456,`db1)
3. 运行以下命令开始同步数据
mysql::loadEx(conn, database('dfs://TSDB_tick'), `tick, `TradeTime`SecurityID,"tick")
数据共 27211975 条,同步数据耗时约52秒。
4. 同步增量数据
如需实现增量同步,只需将mysql::loadEX
中的源数据表名替换为查询语句,并借助 DolphinDB 提供的scheduleJob
函数设置定时任务,即可实现增量同步,示例如下,每天 00:05 同步前一天数据:
def scheduleLoad(){sqlQuery = "select * from tick where date(TradeTime) = '" +temporalFormat(today()-1, 'y-MM-dd') +"' ;"mysql::loadEx(conn, database('dfs://TSDB_tick'), `tick, `TradeTime`SecurityID,sqlQuery)
}
scheduleJob(jobId=`test, jobDesc="test",jobFunc=scheduleLoad,scheduleTime=00:05m,startDate=2023.04.04, endDate=2024.01.01, frequency='D')
注:为防止节点重启时定时任务解析失败,预先在配置文件里添加 preloadModules=plugins::mysql
3.3 通过 DataX 驱动迁移
3.3.1 部署 DataX
从 DataX 下载地址 下载 DataX 压缩包后,解压至自定义目录。
3.3.2 部署 DataX-DolphinDBWriter 插件
将 DataX-DolphinDBWriter 中源码的 ./dist/dolphindbwriter 目录下所有内容拷贝到 DataX/plugin/writer 目录下。
3.3.3 执行 DataX 任务
1. 根据实际环境配置json文件。详情参考:#DataX DolphinDBWriter插件配置项,配置 json 文件
配置文件 OceanBase_tick.json 的具体内容如下,并将 json 文件置于自定义目录下,本教程中方放置于 datax-writer-master/ddb_script/ 目录下。
{"job": {"setting": {"speed": {"channel":1}},"content": [{"writer": {"parameter": {"dbPath": "dfs://TSDB_tick","tableName": "tick","userId": "admin","pwd": "123456","host": "127.0.0.1","batchSize": 200000,"table": [{"type": "DT_SYMBOL","name": "SecurityID"},{"type": "DT_TIMESTAMP","name": "TradeTime"},{"type": "DT_DOUBLE","name": "TradePrice"},{"type": "DT_INT","name": "TradeQty"},{"type": "DT_DOUBLE","name": "TradeAmount"},{"type": "DT_INT","name": "BuyNo"},{"type": "DT_INT","name": "SellNo"},{"type": "DT_INT","name": "TradeIndex"},{"type": "DT_INT","name": "ChannelNo"},{"type": "DT_SYMBOL","name": "TradeBSFlag"},{"type": "DT_INT","name": "BizIndex"}],"port": 8800},"name": "dolphindbwriter"},"reader": {"name": "oceanbasev10reader","parameter": {"username": "root","password": "123456","batchSize":10000,"column": ["*"],"connection": [{"table": ["tick"],"jdbcUrl": ["jdbc:oceanbase://127.0.0.1:2883/db1"]}]}}}]}
}
2. Linux 终端中执行以下命令以执行 DataX 任务
cd ./dataX/bin/
python datax.py ../../datax-writer-master/ddb_script/ocean.json
3. 查看 DataX 同步结果
任务启动时刻 : 2023-04-03 14:58:52
任务结束时刻 : 2023-04-03 15:00:52
任务总计耗时 : 120s
任务平均流量 : 12.32MB/s
记录写入速度 : 226766rec/s
读出记录总数 : 27211975
读写失败总数 : 0
4. 同步增量数据
使用 DataX 同步增量数据,可在 ocean.json 的 ”reader“ 中增加 "where" 条件对数据日期进行筛选,如此每次执行同步任务时至同步 where 条件过滤后的数据,以同步前一天的数据为例,示例如下:
"reader": {"name": "oceanbasev10reader","parameter": {"username": "root","password": "123456","batchSize":10000,"column": ["*"],"connection": [{"table": ["tick"],"jdbcUrl": ["jdbc:oceanbase://127.0.0.1:2883/db1"]}],"where":"date(TradeTime) = (SELECT DATE_ADD(CURDATE(), INTERVAL -1 DAY))"}
}
4. 基准性能
分别使用 MySQL 插件和 DataX 驱动进行数据迁移, 数据量 2721 万条,迁移耗时对比如下表所示:
MySQL插件 | DataX |
---|---|
52s | 120s |
综上,MySQL 插件与 DataX 均能实现 将 OceanBase 中数据迁移到 DolphinDB中,但是各有优缺点:
- MySQL 插件性能较好,适合批量数据的导入,但是运维管理不便。
- DataX 导入数据较慢,适合千万级别以下数据集导入,但是其日志追踪,可扩展性以及管理比较方便。
用户可以根据自己数据量的大小以及工程化的便捷性进行选择导入方式,同时,由于篇幅有限,涉及到DolphinDB 和 DataX 框架的一些其它操作未能更进一步展示,用户在使用过程中需要按照实际情况进行调整。也欢迎大家对本教程中可能存在的纰漏和缺陷批评指正。
附录
DataX DolphinDB-Writer 配置项
配置项 | 是否必须 | 数据类型 | 默认值 | 描述 |
---|---|---|---|---|
host | 是 | string | 无 | Server Host |
port | 是 | int | 无 | Server Port |
userId | 是 | string | 无 | DolphinDB 用户名导入分布式库时,必须要有权限的用户才能操作,否则会返回 |
pwd | 是 | string | 无 | DolphinDB 用户密码 |
dbPath | 是 | string | 无 | 需要写入的目标分布式库名称,比如"dfs://MYDB"。 |
tableName | 是 | string | 无 | 目标数据表名称 |
batchSize | 否 | int | 10000000 | datax每次写入dolphindb的批次记录数 |
table | 是 | 写入表的字段集合,具体参考后续table项配置详解 | ||
saveFunctionName | 否 | string | 无 | 自定义数据处理函数。若未指定此配置,插件在接收到reader的数据后,会将数据提交到DolphinDB并通过tableInsert函数写入指定库表;如果定义此参数,则会用指定函数替换tableInsert函数。 |
saveFunctionDef | 否 | string | 无 | 数据入库自定义函数。此函数指 用dolphindb 脚本来实现的数据入库过程。 此函数必须接受三个参数:dfsPath(分布式库路径), tbName(数据表名), data(从datax导入的数据,table格式) |
table 配置详解
table 用于配置写入表的字段集合。内部结构为
{"name": "columnName", "type": "DT_STRING", "isKeyField":true}
请注意此处列定义的顺序,需要与原表提取的列顺序完全一致。
- name :字段名称。
- isKeyField:是否唯一键值,可以允许组合唯一键。本属性用于数据更新场景,用于确认更新数据的主键,若无更新数据的场景,无需设置。
- type 枚举值以及对应 DolphinDB 数据类型如下
DolphinDB 类型 | 配置值 |
---|---|
DOUBLE | DT_DOUBLE |
FLOAT | DT_FLOAT |
BOOL | DT_BOOL |
DATE | DT_DATE |
MONTH | DT_MONTH |
DATETIME | DT_DATETIME |
TIME | DT_TIME |
SECOND | DT_SECOND |
TIMESTAMP | DT_TIMESTAMP |
NANOTIME | DT_NANOTIME |
NANOTIMETAMP | DT_NANOTIMETAMP |
INT | DT_INT |
LONG | DT_LONG |
UUID | DT_UUID |
SHORT | DT_SHORT |
STRING | DT_STRING |
SYMBOL | DT_SYMBOL |
完整代码及测试数据
- DataX: OceanBase_tick.json
- DolphinDB: mysql插件导入数据.dos, createTable.dos
- 模拟产生数据: genTickCsv.dos
相关文章:

从 OceanBase 迁移数据到 DolphinDB
OceanBase 是一款金融级分布式关系数据库,具有数据强一致、高可用、高性能、在线扩展、高度兼容 SQL标准和主流关系数据库、低成本等特点,但是其学习成本较高,且缺乏金融计算函数以及流式增量计算的功能。 DolphinDB 是一款国产的高性能分布…...

淘宝商品列表数据接口(支持价格、销量排序)
淘宝商品列表数据接口是淘宝提供的一种可以获取淘宝商品信息的接口。通过该接口,可以获取到具有一定规则的商品信息,例如按照价格排序、按照销量排序等。接口返回的数据格式为JSON格式,可以方便地处理数据。 我们可以通过调用淘宝提供的API&…...
Android 11 版本变更总览
Android 11 版本 Android 11 总览重大隐私权变更行为变更:所有应用行为变更:以 Android 11 为目标平台的应用功能和 API 概览Intent系统广播 intent(API 级别 30)通用应用 intent(API 级别 30) Android 11 …...

传染病学模型 | Matlab实现基于SIS传染病模型模拟城市内人口的互相感染及城市人口流动所造成的传染
文章目录 效果一览基本描述模型介绍程序设计参考资料效果一览 基本描述 传染病学模型 | Matlab实现基于SIS传染病模型模拟城市内人口的互相感染及城市人口流动所造成的传染 模型介绍 SIS模型是一种基本的传染病学模型,用于描述一个人群中某种传染病的传播情况。SIS模型假设每个…...
物联网技术如何改变我们的生活:一位资深物联网专家的见解
物联网(IoT)是指通过网络互联的物理设备、车辆、建筑物以及其他物品,这些物品都内置了传感器、执行器、软件和网络连接器,使它们能够收集和交换数据。物联网技术已经在各个领域产生了深远的影响,包括家庭、医疗、交通、…...

node.js+vue.js大学生在线选课系统的设计与实现93pul
本次设计任务是要设计一个选课系统的设计与实现,通过这个系统能够满足用户对选课信息的需求。系统的主要功能包括:个人中心、学生管理、教师管理、选课信息管理等功能。 管理员可以根据系统给定的账号进行登录,登录后可以进入选课系统的设计与…...

华为OD机试真题 Java 实现【寻找符合要求的最长子串】【2023Q1 200分】
一、题目描述 给定一个字符串 s ,找出这样一个子串: 该子串中的任意一个字符最多出现2次;该子串不包含指定某个字符;请你找出满足该条件的最长子串的长度。 二、输入描述 第一行为要求不包含的指定字符,为单个字符,取值范围[0-9a-zA-Z]。 第二行为字符串s,每个字符范…...

接口测试工具Postman接口测试图文教程
目录 一、前言 二、Postman安装和使用 三、请求方式 四、资金记录接口实例演示 一、前言 在前后端分离开发时,后端工作人员完成系统接口开发后,需要与前端人员对接,测试调试接口,验证接口的正确性可用性。而这要求前端开发进…...

视频编辑软件:迅捷视频工具箱
这是一款功能强大、易于使用的视频编辑工具,支持视频剪辑、视频转换、音频转换、视频压缩、视频水印、字幕贴图等实用功能,可以帮助你制作出高质量的视频作品。(传送门:https://www.xunjiepdf.com/xjspgjx) 功能简介 …...

网络知识点之-HTTP协议
超文本传输协议(Hyper Text Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。请求和响应消息的头以ASCII形式给出;而消息内…...
K类函数和KL类函数
Class K \mathcal{K} K function- K \mathcal{K} K类函数 Definition: A continuous function α : [ 0 , a ) → [ 0 , ∞ ) \alpha:[0,a)\rightarrow[0,\infin) α:[0,a)→[0,∞) is said belong to class K \mathcal{K} K if it strictly increasing and α ( 0 ) 0 …...

华为OD机试之完美走位(Java源码)
完美走位 题目描述 在第一人称射击游戏中,玩家通过键盘的A、S、D、W四个按键控制游戏人物分别向左、向后、向右、向前进行移动,从而完成走位。 假设玩家每按动一次键盘,游戏任务会向某个方向移动一步,如果玩家在操作一定次数的键…...
Vue 原始(传统)或特别的视频组件具体实现方法
一、原始的播放器组件(传统的视频播放组件) 参考链接 1. Vue2视频播放(Video) 二、自定义视频播放组件,自播放,无控制模式 简单点的理解,就是没有点击就会暂停播放视频,还有忽略…...

香豆素荧光标记652966-03-5,ATTO425 acid,ATTO 425 羧酸,进行简析说明
中文名称:ATTO 425 羧酸 英文名称:ATTO425 COOH,ATTO-425 carboxylic acid 规格标准:10mg,25mg,50mg CAS:652966-03-5 分子式:C22H27NO6 分子量:401.46结构式:…...

linux信号量与PV操作知识点总结
信号量 信号量(semaphore) 与已经介绍过的 IPC 结构不同,它是一个计数器,信号量用于实现进程间的与斥与同步,而不是用于存储进程间通信数据。 1、特点 (1)信号量用于进程间同步,若要在进程间传递数据需要结…...
6-python中的string类型
目录 内容提要字符串截取python的转义字符 \python的字符串格式化format()的参数format()的数字格式化 字符串常用函数count()函数endwith()函数 与 startwith()函数find()函数与index()函数find()函数 ⭐index()函数 判断字符串内的字符种类函数isalnum()函数isalpha()函数isd…...

Windows系统内核溢出漏洞提权
目录 Windows内核溢出漏洞原理 溢出漏洞简介 什么是缓冲区 缓冲区溢出 缓冲区溢出目的 Windows内核溢出漏洞利用流程 提权实战思路 手工提权测试 辅助提权 EXP如何寻找 使用MSF提权 关于提权时可能遇到的问题 如果提权的时候发现无法执行命令的话,可以上…...

BlackIce病毒分析
概述 blackice是一个古老的感染型病毒,可感染系统中exe、doc和xls文件,通过USB设备和网络驱动器来传播,会向C&C下载pe执行,会关闭常用的杀软进程。下面找了一个样本,这个样本的代码结构清晰,用IDA pro…...

软件测试基础知识整理(八)- 软件缺陷
目录 一、软件缺陷 1.1 缺陷定义 1.2 缺陷判定标准 1.3 软件缺陷产生的原因 1.4 软件缺陷产生的根源 1.5 软件缺陷信息 1.5.1 缺陷状态 1.5.2 缺陷严重程度 1.5.3 缺陷优先级 1.6 缺陷报告模板 1.7 缺陷报告注意事项 1.8 缺陷跟踪流程 1.9 缺陷数据分析关注的问题 …...

有没有想过一种可能,30岁之后,转行去做IT售前?
灵魂拷问 IT行业的变化是非常迅速的,各种新技术、新产品、新观念、新的业务模式层出不穷,不仅是我们,客户也在不断地学习进步,因此我们注定要终身学习。 IT售前这个岗位为许多IT职场人提供了一种新的选择: 你不需要成为某一方面…...

Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...

MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...

ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...

iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...
简单介绍C++中 string与wstring
在C中,string和wstring是两种用于处理不同字符编码的字符串类型,分别基于char和wchar_t字符类型。以下是它们的详细说明和对比: 1. 基础定义 string 类型:std::string 字符类型:char(通常为8位)…...

21-Oracle 23 ai-Automatic SQL Plan Management(SPM)
小伙伴们,有没有迁移数据库完毕后或是突然某一天在同一个实例上同样的SQL, 性能不一样了、业务反馈卡顿、业务超时等各种匪夷所思的现状。 于是SPM定位开始,OCM考试中SPM必考。 其他的AWR、ASH、SQLHC、SQLT、SQL profile等换作下一个话题…...

break 语句和 continue 语句
break语句和continue语句都具有跳转作用,可以让代码不按既有的顺序执行 break break语句用于跳出代码块或循环 1 2 3 4 5 6 for (var i 0; i < 5; i) { if (i 3){ break; } console.log(i); } continue continue语句用于立即终…...
npm install 相关命令
npm install 相关命令 基本安装命令 # 安装 package.json 中列出的所有依赖 npm install npm i # 简写形式# 安装特定包 npm install <package-name># 安装特定版本 npm install <package-name><version>依赖类型选项 # 安装为生产依赖(默认&…...

【前端实战】如何让用户回到上次阅读的位置?
目录 【前端实战】如何让用户回到上次阅读的位置? 一、总体思路 1、核心目标 2、涉及到的技术 二、实现方案详解 1、基础方法:监听滚动,记录 scrollTop(不推荐) 2、Intersection Observer 插入探针元素 3、基…...