-
LWLock 称为轻量级锁,只存在两种锁类型(LWLockMode):共享锁(Shared)和排它锁(Exclusive),当无法获取到锁时,会进行阻塞等待状态; 原生PG不提供死锁检测,DWS自己支持了死锁检测; 加锁解锁对外部用户透明,使用完一般应该立即主动释放,不等事务结束。 SpinLock 称为自旋锁,一般依赖于硬件支持,需要CPU支持TAS(test-and-set)指令集; 由于没有cpu上下文切换,性能高,主要用于临界区很短的场景,能快速释放锁,如几个指令内的内存状态修改和计算; 最多只有一个持有者,如未能获取到锁,则cpu busy做轮询检查直到拿到(超时后会PANIC退出); 没有等待队列和死锁检测。 RegularLock 称为常规锁,底层使用hash 表,持锁时间可以较长,有死锁检测和等待队列,事务结束时会自动释放; 可细分为表锁,事务锁,文件扩展锁,咨询锁等。
-
当前HStore并发更新同一行仍然是不支持的,其中同一行上并发update/delete操作会先等锁然后报错,同一行上的并发upsert操作会先等锁然后继续执行。由于等待开销也是会影响业务的入库性能,甚至可能产生死锁,所以需要在入库时保证不会并发更新到同一行或者同一个key。索引相关 索引会占用额外的空间,同时带来的点查性能提升有限,所以HStore表只建议在需要做 Upsert 或者有点查(这里指唯一性与接近唯一的点查) 的诉求下创建一个主键或者btree 索引。 MERGE相关 由于HStore表依赖后台autovacuum来将操作MERGE到主表,所以入库速度不能超过MERGE速度,否则会导致Delta表的膨胀,可以通过控制入库的并发来控制入库速度。同时由于Delta表本身的空间复用受oldestXmin的影响,如果有老事务存在可能会导致Delta空间复用不及时而产生膨胀。 UPSERT性能 HStore 表虽然相比普通列存,并发upsert入库性能得到了很大提升,但相比行存还是有差距,大概只有行存的1/3。所以在不追求压缩率以及批量查询性能、只追求单点查询性能的场景下,还是推荐行存表入库。
-
虽然列存老Delta表解决了小批量入库产生的小CU问题,但是没有解决同一个 CU 上的并发更新产生的锁冲突问题。而实时入库的场景下,需要将insert+upsert+update 操作实时并发入库,数据来源于上游的其他数据库或者应用,同时要求入库后的数据要能及时查询,且对于查询的效率要求很高。 目前的列存表由于锁冲突的原因无法支持并发upsert/update入库,导致这些有需要的局点只能使用行存表,但是行存表因为格式的天然劣势,在AP查询场景下一方面性能较慢,另一方面由于压缩差导致占用了大量的磁盘空间,对用户产生额外成本。 GaussDB(DWS)中的HStore表, 在使用列存储格式尽量降低磁盘占用的同时,支持高并发的更新操作入库以及高性能的查询效率。面向对于实时入库和实时查询有较强诉求的场景,同时拥有处理传统TP场景的事务能力。HStore 表的实现主要依靠一张新设计的Delta表以及内存并发控制机制,这里简单讲一下Delta表的实现以及简单的观察Delta表。 HStore 的 Delta 表主要用于存放入库产生的 Insert/Delete/Update 操作,小批量Insert 的数据会先进入Delta形成一条类型是I(Insert)的记录;删除会往Delta表插入一条类型是D(Delete)的记录;更新操作(Upsert与Update)会拆分成 Delete + Insert会插入一条类型 X(表示由更新产生的删除)的记录以及一条类型 I 的记录;(类型是U(Update)的记录由轻量化Update产生,不过当前轻量化更新默认关闭,所以不用管。) 可以看到,入库时的 Upsert/Update/Delete 都会转换成相应类型的记录插入的HStore 的 Delta 表中,再结合内存并发控制机制,就能保证同一个CU上更新于删除操作不会阻塞。同时,由于小批量的插入只会在Delta表上形成一条记录,相比与列存老Delta的直接存储数据,能减少IO占用,提高MERGE效率。
-
最基础的表类型,顾名思义,数据按行存储,在实际的物理块中,数据的所示的方式存储: 优势很明显,点查场景下,直接就能索引到行存某行元组的位置,点查性能好。数据库中的系统表就是行存表,对于用户的一些对点查性能要求高或者频繁更新的小表,都推荐用行存表。 AP场景下,常常需要对某列进行批量查询来做分析业务,这时候采用行存的话就会把所有列都读出来产生冗余IO, 同时AP场景下的表数据量往往很大,行存表压缩暂未商用,使用行存表也会导致占用空间过大。GaussDB(DWS)中的列存表就是针对这种场景实现的。列存表将每列的数据批量存储成一个 CU(Compress Unit), 能带来了很好的空间压缩与批量查询性能提升,对于一些涉及多表关联的分析类复杂查询、数据不经常更新的表,推荐使用列存表。对于列存表,如果业务是频繁的小批量插入,那么将产生大量的小CU(单个CU里只有几百条甚至几条数据), 每个列的CU都是有压缩代价的,小CU过多将严重影响列存表的查询性能。列存的 Delta 表就是针对这种场景实现的,让小批量插入的数据先存储到行存Delta 表,满6w后由后台autovacuum异步merge到主表CU。如图3所示,需要注意的是列存带Delta表只解决小批量入库产生的小CU问题,不解决同一个CU上的并发更新问题。
-
在对HStore进行点查时,会首先通过CU的min/max来进行粗过滤,我们希望通过min/max 过滤掉大部分数据,这就要求每个 CU 的数据尽可能的接近,而不能过于分散。目前GaussDB(DWS)已经实现了局部聚簇 (Partial Cluster Key, 简称PCK),在数据批插过程中就会进行排序。但还是会有如下几种情况导致CU的聚簇性无法达到要求: 1) 写入数据时,如果不是批量导入,则不会把数据写入排序器,而是直接插入Delta表,当 Delta 表 MERGE 的时候,也不会先走排序逻辑,而是直接将数据写入CU; 2) 当CU中的数据被删除的足够多时,就变成了小CU,聚簇性本身就会变差,就算进行了小 CU 合并,也依然不会走排序逻辑,而是将数据直接写入 Delta 表,merge流程与1)一致; 3) 实际上就是增加数据+删除数据。通过将HStore中多个CU的数据根据partial cluster key进行排序,生成新的CU再重新写入,新CU的数据会有更高的聚集性,即CU的min,max会在一个较小的区间内。异步排序时的并发处理与小CU合并类似。经过测试,排序后的CU聚簇性极大提升,粗过滤效率的提升与原本的数据特征有关。但是排序过程中会对所有参与排序的CU加CU级锁,此过程会阻塞部分DML操作,因此不建议在业务高峰期使用此功能。
-
小CU合并不是直接产生新的CU,而是将小CU数据重新插入到delta表后标记删除,然后依赖Delta表的自动MERGE攒够后再产生完整的新CU; 和正常的Delta merge不同在于,小CU被标记删除后新插入Delta表的记录会申请新的ctid,因为 ctid是变化的,所以该操作和DML操作存在冲突。当DML操作时遇到小CU合并,使用等待重试的方式处理;当compact操作时遇到DML冲突时直接跳过即可,原因就是删除和更新操作还是会将数据标记删除,因此可以直接放弃合并此条数据。小CU合并的事务可见性基于现有的csn机制,compaction inprogress或者回滚对外不可见,还是看到老记录,compaction提交老记录就不再可见看到新记录。 具体一个 CU 中剩余多少条数据才算是小 CU,应该是与业务强相关。因此,小CU阈值应该可以使用GUC参数调节。0CU的处理比小CU的处理简单的多,我们直接从CUDESC表中将0CU记录删除即可。这里指的删除天然支持MVCC,因此老的快照查询依然可以访问被删除的记录。 小CU合并的过程就是不断的尝试把小于一定阈值的CU标记删除,转移数据到Delta 中,直到这个CU全部被标记删除后变成0 CU,就可以当做0 CU彻底清理。成功解决小CU问题,并且在小CU合并期间对实时入库性能几乎没有影响(推荐小CU行数阈值下upsert性能劣化1%),但是因为小CU问题的解决,可以很好的解决查询性能劣化,空间膨胀等问题,并且小CU合并完成后,最终实时入库性能还是会有显著提升。
-
问题诱因 1) 有些实时表入库量并不大,不定期会有入库,因为 MERGE 的判断标准有两个:行数或者时间,超过时间没有入库后也会强制MERGE,这种情况下MERGE产生的CU的行数不可控,可能产生小CU; 2) 对于缓慢变化维表来说,可能很长时间才改变一次,每次都可能产生一个小 CU,虽然不会有太多这种小CU,但长期运行后,这种维度表数量还很多的情况下,小CU的数量就会到达影响系统性能的级别; 3) 频繁upsert、update、delete等更新后,CU中大部分数据被标记删除,这样的CU虽然会被列存VACUUM通过填充NULL进行回收,但是依然会导致小IO和cudesc表的膨胀,进而影响性能。 问题影响 1) CUDesc 并不会因为 CU 变小而变小,因此当小 CU 过多会导致存储利用率过低。比如一个1000列的大宽表产生的CU只包含1行数据,但是因为每一列都会在CUDESC表中记录,CUDesc也会增加一千多行数据; 2) 只剩下几十行甚至几行的小CU会引发大量的小IO; 3) 粗过滤效率降低,因为CUDESC表中会存储CU的最值,当进行查询时可以先通过最值进行粗过滤,但是如果CU中数据太少导致数据范围小,则会降低粗过滤效率; 4) 降低压缩率。因为数据压缩是以CU为单位的,但是CU过小会导致压缩表现达不到预期。
-
列存储优势明显,但是劣势也比较明显,传统列存表基本无法支持并发更新入库。随着业务复杂程度的提升,出现了对于实时入库和实时查询有较强诉求的场景,这要求数据库同时拥有处理传统TP 场景的事务能力和强大的数据分析能力。这时就可以使用HStore 来处理这些场景了。 HStore 利用Delta表存储update/delete/insert等操作信息。之后依赖后台常驻autovacuum 来做MERGE操作将数据写入主表。 利用特有的 Delta 表,HStore 解决了传统列存表 CU 锁的问题,支持上游upsert/update 等操作实时并发入库。同时还能保证和普通列存表相近的数据分析与数据压缩能力。 HStore 表技术特点如下:完整的事务一致性:支持全面的事务能力,数据插入或者更新提交后即可见不存在时延,保证数据ACID一致性。 全面的功能支持:提供和当前列存一样全面的功能和语法支持。 查询性能好:适用多表关联等复杂AP查询场景,相对于传统行存表,拥有更完善的分布式查询计划与更先进的分布式执行器,性能优势明显。支持复杂的子查询和存储过程,支持主键等传统索引能力去重和加速点查,也支持分区、全局字典、局部排序等方式进一步加速AP查询。 入库快:彻底解决列存CU锁冲突问题,支持高并发的更新入库操作,典型场景下,并发更新性能是之前的百倍以上。 高压缩:数据在MERGE进入列存主表后,按列存储具有天然的压缩优势,能极大地节省磁盘空间与IO资源。
-
行存储 传统OLTP(OnLine Transaction Processsing 联机事务处理)场景与功能、业务强相关,数据需要进行频繁的增删改查,这时比较适合使用行存储式。行存储的优势主要有两个方面:首先是点查性能好,在点查场景下可以直接索引到某行数据的元组位置;其次就是更新效率高,行存储在实时并发入库,并发更新方面依然有着比较大的优势。 列存储 传统行存储形式的数据库主要为业务服务,但是如果涉及到分析查询场景,特别是在数据量大且复杂的查询时,就会遇到性能瓶颈了,性能瓶颈是数据存储方式决定的。因此OLTP(OnLine Transaction Processsing 联机事务处理)场景一般会交给列存储引擎去做。列存储的优势主要有两方面:首先是批量查询性能好,当分析查询只涉及某列或者某几列,不需要访问无关列,特别是在表的宽度比较大时(如一千列),优势更加明显;其次就是列存储的压缩性能更高,原因就是因为数据按列存储,单列类型相同。 列存储引擎的最小存储单位是CU(Compression Unit, 压缩单元):一个CU是由表中某一列的一部分数据组成的压缩数据块, 通过(cu_id,col_id)标识一个CU。另外,列存引擎通过Delta表,避免了小CU的产生,显著提升列存表单条导入的性能,同时解决由于小CU导致的数据膨胀问题。当单条或小批量数据导入到列存表时,需先存入Delta表,当Delta表中数据积攒到指定行数时再存入新产生的CU中。
-
时序表的建表语法,在很大程度上继承了行存和列存的语法,降低了用户的学习成本,能够更容易理解和使用。我们将时序表的列分为三种kv_type类型(tag、field、time),那么如何将对应的列指定为合适的类型,帮助我们更好的提高导入、查询等场景的性能,让业务场景运行的更加高效呢?对于不随时间的变化而变化,描述发电机的属性信息的列(发电机信息、生产厂商、型号、位置、ID)被设置为tag列,在建表时需要将对应的列后面指定为TSTag; 对于采样数据的维度(电压、功率、频率、电流相角)这些对应的采样数值随时间的变化而变,我们将这些维度设置为 field 列,建表语句数据类型后面指定为TSField; 最后一列我们指定为时间列time,存储field列数据对应的时间信息,建表时将指定为TSTime。 在写建表语句时,对于tag列的顺序,我们可以适当优化一下,将唯一性(distinct值)较高的列尽量写在前面,这样对于时序场景的性能有一些提升。如果用户没有手动优化,GaussDB(DWS) IoT数仓也可以自适应的帮助用户提高时序场景的性能。另外,创建时序表时一定要指定表级参数orientation属性设置为timeseries。时序表不需要手动指定DISTRIBUTE BY和PARTITION BY, 默认按照所有tag列分布,且分区健默认为tstim指定的时间列。 对于create table like 语法,该语法需要自动从源表中继承列名和对应的kv_type类型。因此如果源表是非时序表,新表是时序表,对应的列的kv_type类型无法确定,则无法创建成功。
-
案例介绍本案例使用Vanna配合本地Ollama/华为mass服务,并借助开发者空间云开发环境提供的免费GaussDB数据库和HCE2.0开发环境进行本地部署,来构建一个先进的AI自然语言分析系统。 案例内容一、概述1.1 案例介绍使用Vanna配合本地Ollama/华为mass服务,并借助开发者空间云开发环境提供的免费GaussDB数据库开发环境进构建一个先进的AI自然语言分析系统。GaussDB:华为自主创新研发的分布式关系型数据库。该产品支持分布式事务,同城跨AZ部署,数据0丢失,支持1000+的扩展能力,PB级海量存储。同时拥有云上高可用,高可靠,高安全,弹性伸缩,一键部署,快速备份恢复,监控告警等关键能力,能为企业提供功能全面,稳定可靠,扩展性强,性能优越的企业级数据库服务。Vanna:作为数据处理和自然语言处理(NLP)的关键组件,Vanna负责数据的预处理、清洗、转换以及NLP任务的执行,如文本分类、情感分析、实体识别等。Ollama:作为AI模型和算法的核心,Ollama提供了丰富的机器学习模型和深度学习算法,用于训练和优化自然语言处理任务。它与Vanna紧密集成,共同实现高效的数据分析和知识提取。ModelArts Studio(MaaS)平台:是华为云推出的一款大模型即服务平台,可以一站式的对业界主流开源大模型进行部署托管,同时开放大模型API服务,可以结合业界主流Agent开发框架,轻松构建AI Agent应用。华为开发者空间,是为全球开发者打造的专属开发者空间,致力于为每位开发者提供一台云开发环境、一套开发工具和云上存储空间,汇聚昇腾、鸿蒙、鲲鹏、GaussDB、欧拉等华为各项根技术的开发工具资源,并提供配套案例指导开发者 从开发编码到应用调测,基于华为根技术生态高效便捷的知识学习、技术体验、应用创新。1.2 适用对象企业个人开发者高校学生1.3 案例时间本案例总时长预计60分钟。1.4 案例流程说明:在开发者空间中安装Ollama与Vanna申请华为云开发者空间的GaussDB数据库;启动vanna链接GaussDB数据库进行自然语言数据库分析。申请ModelArts Studio(MaaS)免费服务1.5 资源总览本案例预计花费0.8元。资源名称规格单价(元)时长(分钟)华为开发者空间 - 云开发环境鲲鹏通用计算增强型 kc1 | 2vCPUs | 4G | HCE2.0免费60华为开发者空间 - 生态版GaussDB单副本集中式版 | 4 vCPUs | 16G | HCE OS 64bit (200GB)免费60弹性公网IP按流量计费 5Mbit/s0.8元/GB60二、案例准备工作2.1 配置云开发环境根据案例《开发者空间 - 云开发环境使用指导》,请查看下面链接,配置云开发环境,并通过xshell、crt等链接工具登录云开发环境。开发者空间 - 云开发环境使用指导参考如上案例链接进行配置并连接:创建本地PC和远程云开发环境的隧道链接通过xshell、crt等链接工具登录云开发环境,进行测试2.2 领取GaussDB数据库2.2.1 免费领取GaussDB在线试用版(2025年 06月 21日 - 2025年 12月 31日)。华为开发者空间-GaussDB云数据库领取与使用指导注:部署的Django项目需要对接GaussDB,因此GaussDB需要绑定EIP,参考上述指导中领取部分第(5)步因为默认vanna的postgrs驱动连接gaussdb认证方式有问题,实例创建完成后修改password_encryption_type参数为0,然后在基本信息里修改一下root密码 2.2.2 进行数据初始化领取Gaussdb实例后连接数据库点击登录 输入用户名密码进行登录 点击新建数据库,创建数据库school,兼容选择mysql点击确定 点击去school数据库,创建schema名字school,点击确认 初始化表和数据点击sql窗口,数据库选择school,schema也选择上面创建的school,拷贝表和数据脚本到窗口栏,点击执行sql样例数据: CREATE TABLE students ( student_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '学生ID', name VARCHAR(50) NOT NULL COMMENT '学生姓名', age INT COMMENT '年龄', major VARCHAR(100) COMMENT '专业', email VARCHAR(100) UNIQUE COMMENT '电子邮件'); INSERT INTO students (name, age, major, email) VALUES('张三', 20, '计算机科学', 'zhangsan@example.com'),('李四', 21, '电子工程', 'lisi@example.com'),('王五', 19, '数学', 'wangwu@example.com'),('赵六', 22, '物理', 'zhaoliu@example.com'),('钱七', 20, '化学', 'qianqi@example.com'),('孙八', 21, '生物', 'sunba@example.com'),('周九', 19, '历史', 'zhoujiu@example.com'),('吴十', 22, '哲学', 'wushi@example.com'),('郑十一', 20, '艺术', 'zhengshiyi@example.com'),('王十二', 21, '音乐', 'wangshier@example.com'),('陈十三', 19, '体育', 'chenshisan@example.com'),('冯十四', 22, '英语', 'fengshisi@example.com'),('董十五', 20, '法语', 'dongshiwu@example.com'),('萧十六', 21, '德语', 'xiaoshiliu@example.com'),('曹十七', 19, '日语', 'caoshiqi@example.com'),('许十八', 22, '韩语', 'xushiba@example.com'),('蒋十九', 20, '西班牙语', 'jiangshijiu@example.com'),('沈二十', 21, '意大利语', 'shenshier@example.com'),('韩二十一', 19, '心理学', 'hanershiyi@example.com'),('杨二十二', 22, '社会学', 'yangershi@example.com'); CREATE TABLE courses ( course_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '课程ID', course_name VARCHAR(100) NOT NULL COMMENT '课程名称', credits INT COMMENT '学分', teacher_id INT COMMENT '教师ID'); INSERT INTO courses (course_name, credits, teacher_id) VALUES('数据结构', 4, 1),('微积分', 3, 2),('编程基础', 3, 3),('物理实验', 2, 4),('化学原理', 3, 5),('生物技术', 4, 6),('历史概论', 2, 7),('哲学思考', 3, 8); CREATE TABLE enrollments ( enrollment_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '选课记录ID', student_id INT NOT NULL COMMENT '学生ID', course_id INT NOT NULL COMMENT '课程ID', grade FLOAT COMMENT '成绩'); INSERT INTO enrollments (student_id, course_id, grade) VALUES(1, 1, 85.5),(2, 2, 90.0),(3, 3, 78.5),(4, 4, 82.0),(5, 5, 88.5),(6, 6, 75.0),(7, 7, 80.5),(8, 8, 87.0),(9, 1, 81.0),(10, 2, 85.5),(11, 3, 79.0),(12, 4, 83.0),(13, 5, 86.5),(14, 6, 77.0),(15, 7, 82.5),(16, 8, 88.0),(17, 1, 84.0),(18, 2, 87.5),(19, 3, 80.0),(20, 4, 85.0),(21, 5, 83.5),(22, 6, 78.0),(23, 7, 81.5),(24, 8, 86.0),(25, 1, 82.0),(26, 2, 84.5),(27, 3, 79.5),(28, 4, 83.0),(29, 5, 86.5),(30, 6, 77.5); 2.3 验证云开发环境与GaussDB互通通过xshell或windows命令终端登录云开发环境,测试GaussDB能否连接,如下是通的 如不通去修改安全组的入方向规则,增加需要的端口如图(默认应该没通的)三、 安装Ollama首先我们要先配置pycharm远程开发环境可参考如下用例基于华为开发者空间-云开发环境,PyCharm SSH远程开发环境搭建:cid:link_2后续所有操作都基于pycharm的远程命令行进行操作 3.1 安装OllamaOllama 是一个强大的开源工具,旨在帮助用户轻松地在本地运行、部署和管理大型语言模型(LLMs)。它提供了一个简单的命令行界面,使用户能够快速下载、运行和与各种预训练的语言模型进行交互执行安装命令如下:方式一(推荐,安装速度快):curl -fsSL https://dtse-mirrors.obs.cn-north-4.myhuaweicloud.com/case/0035/install.sh | sudo bash 3.2 模型部署接下来可以借助 Ollama 工具来部署 Deepseek 大模型,部署 deepseek-r1:1.5b 版本,因为资源有限我们部署一个小一点的模型,执行命令:ollama pull deepseek-r1:1.5b 部署的时间长短依赖于网络的情况,部署完成后,我们就可以与 Deepseek 大模型进行对话了:ollama run deepseek-r1:1.5b 四、 安装配置Vanna4.1 更新python配置虚拟环境vanna使用python 安装建议3.10以上,开发者空间中的python版本为3.9.9,需要先升级python4.1.1 安装所需包sudo yum groupinstall "Development Tools" -ysudo yum install openssl-devel -ysudo yum install gcc -y sudo yum install gcc-c++ -y sudo yum install bzip2-devel -y sudo yum install libffi-devel -y sudo yum install zlib-devel -y sudo yum install wget -y sudo yum install make -y sudo yum install glibc-devel -y sudo yum install libgcc -y sudo yum install tar -y sudo yum install bzip2 -y sudo yum install zlib -y sudo yum install xz -y sudo yum install readline-devel -y sudo yum install sqlite-devel -y sudo yum install sqlite-libs -y 4.1.2 升级pythonsudo wget https://mirrors.huaweicloud.com/python/3.10.14/Python-3.10.14.tgzsudo tar xzf Python-3.10.14.tgzcd Python-3.10.14OPENSSL_PREFIX=/usrsudo ./configure --enable-optimizations --with-ensurepip=install \ --with-openssl=$OPENSSL_PREFIXsudo make -j$(nproc)sudo make altinstallpython3.10 -m sslpython3.10 --version4.1.3 配置python虚拟环境因为业务场景的Python开发,多数都是构建一个大型应用程序,并且不希望各种组件的各种版本之间相互冲突,所以需要设置一个虚拟环境。先需要更新下载源。执行如下命令sudo yum -y updatesudo yum -y upgradepip3 install virtualenv -i cid:link_8 #安装virtualenvpython3.10 -m venv myenv #创建虚拟环境source myenv/bin/activate #激活环境 4.2 python下安装Vannapython 安装建议3.10以上安装前更新下pip,然后执行安装python3.10 -m pip install --upgrade pip -i cid:link_8pip3 install 'vanna[chromadb,ollama,postgres]' -i cid:link_8 4.3 Vanna官网生成示例代码Vanna是一款基于开源Python框架的SQL生成工具,可以用日常用语提问,Vanna自动将其转换为SQL语句,简化数据库查询过程。生成实例代码官网:https://vanna.ai/文档:https://vanna.ai/docs/Vanna的例子,链接如下,按照如下图选择生成示例代码:https://vanna.ai/docs/postgres-ollama-chromadb/依次选择Ollama-ChromaDB-postgres 会生成示例代码, 选择使用的模型商选择使用向量数据库的类型 选择要连接的数据库 样例代码:from vanna.ollama import Ollamafrom vanna.chromadb import ChromaDB_VectorStoreclass MyVanna(ChromaDB_VectorStore, Ollama): def __init__(self, config=None): ChromaDB_VectorStore.__init__(self, config=config) Ollama.__init__(self, config=config)vn = MyVanna(config={'model': 'deepseek-r1:1.5b', 'ollama_host': 'http://localhost:11434'})vn.connect_to_postgres(host='xxxxxxx', dbname='school', user='xxxx', password='xxxx', port='8000')vn.train(ddl="""CREATE TABLE school.students ( student_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '学生ID', name VARCHAR(50) NOT NULL COMMENT '学生姓名', age INT COMMENT '年龄', major VARCHAR(100) COMMENT '专业', email VARCHAR(100) UNIQUE COMMENT '电子邮件');CREATE TABLE school.courses ( course_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '课程ID', course_name VARCHAR(100) NOT NULL COMMENT '课程名称', credits INT COMMENT '学分', teacher_id INT COMMENT '教师ID');CREATE TABLE school.enrollments ( enrollment_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '选课记录ID', student_id INT NOT NULL COMMENT '学生ID', course_id INT NOT NULL COMMENT '课程ID', grade FLOAT COMMENT '成绩');""")from vanna.flask import VannaFlaskAppVannaFlaskApp(vn, allow_llm_to_see_data=True).run() 五、 启动应用并使用4.1 代码配置打开pycham把样例代码粘贴进main.py,并修改模型和数据库配置vn = MyVanna(config={'model': 'deepseek-r1:1.5b', 'ollama_host': 'http://localhost:11434'})vn.connect_to_postgres(host='xxxx', dbname='school', user='xxxx', password='xxxx', port='8000')上传代码到远程开发环境 5.2 启动应用进入自己配置的ssh远程目录启动应用nohup python3.10 main.py & 查看输出日志,日志最后有系统的登录地址tail nohup.out 创建应用启动的对应端口(8084)的隧道协议,可参考开发者空间 - 云开发环境使用指导-第4章2小节hdspace devenv start-tunnel --instance-id=0edfc31f922c4b54b74ba8819 --remote-port=8084 --local-port=8084 5.3 使用自然语言分析数据库在浏览器输入http://127.0.0.1:8084,进行登录,第一次比较慢等待一下 然后我们可以用自然语言操作数据库了,因为已开发环境内存有限,deepseek-r1:1.5b回答的不太好,如果资源充足可以换别的模型,生成的sql问题可以点击修复;使用自然语言提问:每门课程的做高分是多少 sql结果会自动生成表格和图表 六、 使用华为maas部署使用ollama本地模型比较安全但相对复杂,我们还可以使用华为ModelArts Studio(MaaS)服务来作为系统的智能模型6.1 申请ModelArts免费服务参考下面的步骤,免费体验ModelArts Studio(MaaS)预置服务cid:link_5按下面的步骤获取相关信息:区域切换到“西南-贵阳一”,依次点击:ModelArts Studio->模型推理->在线推理->预置服务->免费服务->领取 领取后点击->调用说明->OpenAI SDKAPI Key管理-> 创建API Key把api key,api地址,model参数保留好备用 6.2 生成vanna代码整体可参考<<四、安装配置vanna>>https://vanna.ai/docs/postgres-ollama-chromadb/依次选择OpenAI-ChromaDB-postgres 成示例代码 生成的示例代码6.3 安装python包注意: 要重新安装使用的包与ollama部署时的不一样pip3 install 'vanna[chromadb,openai,postgres]' -i cid:link_8pip3 install openai #安装openai本地客户端 6.4 修改代码并运行整体可参考步骤<<五、启动应用并使用>>在6.2生成的模板代码下我们进行修改,添加进去华为maas的参数及OpanAI客户端的代码运行前修改如下模型和数据库配置my_llm_api_key = 'key' #上面步骤我们创建的apikeymy_llm_base_url = 'https://maas-cn-southwest-2.modelarts-maas.com/v1/infers/271c9332-4aa6-4ff5-95b3-0cf8bd94c394/v1' # 上面步骤调用说明里的apiurlmy_llm_name = 'DeepSeek-V3' #上面步骤的modelnamevn.connect_to_postgres(host='xxx', dbname='school', user='root', password='xxx', port='8000')代码:from vanna.ollama import Ollamafrom vanna.chromadb import ChromaDB_VectorStorefrom vanna.openai import OpenAI_Chatfrom openai import OpenAImy_llm_api_key = 'key' #上面步骤我们创建的apikeymy_llm_base_url = 'https://maas-cn-southwest-2.modelarts-maas.com/v1/infers/271c9332-4aa6-4ff5-95b3-0cf8bd94c394/v1' # 上面步骤调用说明里的apiurlmy_llm_name = 'DeepSeek-V3' #上面步骤的modelnameclient = OpenAI( api_key=my_llm_api_key, base_url=my_llm_base_url)class MyVanna(ChromaDB_VectorStore, OpenAI_Chat): def __init__(self, client=None, config=None): ChromaDB_VectorStore.__init__(self, config=config) OpenAI_Chat.__init__(self, client=client, config=config)vn = MyVanna(client=client, config={"model": my_llm_name})vn.connect_to_postgres(host='xxx', dbname='school', user='root', password='xxx', port='8000')vn.train(ddl="""CREATE TABLE school.students ( student_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '学生ID', name VARCHAR(50) NOT NULL COMMENT '学生姓名', age INT COMMENT '年龄', major VARCHAR(100) COMMENT '专业', email VARCHAR(100) UNIQUE COMMENT '电子邮件');CREATE TABLE school.courses ( course_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '课程ID', course_name VARCHAR(100) NOT NULL COMMENT '课程名称', credits INT COMMENT '学分', teacher_id INT COMMENT '教师ID');CREATE TABLE school.enrollments ( enrollment_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '选课记录ID', student_id INT NOT NULL COMMENT '学生ID', course_id INT NOT NULL COMMENT '课程ID', grade FLOAT COMMENT '成绩');""")from vanna.flask import VannaFlaskAppVannaFlaskApp(vn, allow_llm_to_see_data=True).run() 上传代码并运行整体可参考步骤<<五、启动应用并使用>>nohup python3.10 main.py & 在浏览器输入http://127.0.0.1:8084,进行登录使用,我们可以看到使用准确的模型一次就回答对了,如果生产部署选对模型很重要 至此本案例关于在开发者空间–远程开发环境中使用Vanna配合ollama/maas基于GaussDB的自然语言分析系统实践操作完毕。 我正在参加【案例共创】第6期 开发者空间-基于云开发环境和GaussDB构建应用 cid:link_7
-
GaussDB P模式下自增主键是通过序列自增主键,但是如果在M模式下使用序列好像是不行的,一直报游标cursor错误,2种方式兼容不了,M模式下使用AUTO_INCREMENT进行自增主键
-
使用列存表时,如果使用场景不当,如时时入库场景,会很容易产生小cu问题。小cu介绍:cid:link_1cid:link_0 830版本后有hstore opt功能,可以部分场景减少小cu,主要是insert入库场景,但是update和delete依然会产生小cu,原因是在进行update时,是把目标数据delete再insert一条数据,一个cu单元6W行数据,当delete掉大部分数据后,就会变成小cu,频繁delete和频繁大量update容易产出小cu。 注意事项与列存一样,当前版本HStore opt上的UPDATE操作始终先DELETE再INSERT。全局GUC参数可控制打开HStore opt的轻量化UPDATE,当前版本默认关闭。对于并发UPDATE场景, 传统列存储格式由于同时操作相同CU时会产生锁冲突所以并发性能较差, 对于HStore opt表由于不需要阻塞等待,并发UPDATE性能可达到列存的百倍以上。业务侧:对列存表进行攒批入库,单次入库量(有分区则针对单分区单次入库量)接近或大于6w*主DN个数。表数据量不大时建议改为行存表。运维侧:当业务侧因业务特征无法调整入库量时,定期对列存表进行vacuum full可达到整合小CU的目的,一定程度缓解小CU问题。
-
欢迎体验华为云GaussDB!GaussDB针对开发者和高校教师等不同用户群体,提供了满足各自需求的专属产品版本。面向开发者 华为云提供了GaussDB在线试用版(领取入口),您可以通过领取入口获取并试用。 - 领取方式:开发者需要完成报名且通过审核后,可前往开发者空间工作台领取GaussDB实例,先到先得。 - 申请流程:请参考GaussDB在线试用版活动页中的“活动信息”说明。注:GaussDB在线试用版实例在区域、部署形态、性能规格、存储空间等方面有特定规格,完全能够满足开发者的在线体验需求,有问题可以进“云数据库GaussDB开发者”企业微信群交流。面向高校老师若您是高校教师,希望将GaussDB融入教学或寻求其他合作方式,华为云GaussDB可为您提供所需的云资源、教学材料及技术支持。 - 获取方式:方式1:在帖子下方留言,内容格式为:“所在高校+老师姓名+联系方式+开课时间”;方式2:关注“GaussDB数据库”公众号并留言,内容格式为:“所在高校+老师姓名+联系方式+开课时间”;届时将有工作人员与您联系。
-
Oracle 和 GaussDB 中的 VARCHAR2 类型在定义、存储机制和功能上存在显著差异 1. 长度定义与单位Oracle支持显式指定单位:BYTE(字节)或 CHAR(字符),例如 VARCHAR2(100 BYTE) 或 VARCHAR2(100 CHAR)。多字节字符集(如 UTF-8)下,CHAR 单位按字符数计算存储空间(例如 VARCHAR2(10 CHAR) 可存储 10 个中文字符)。最大长度:标准模式:4000 字节(受行大小限制)扩展模式(12c+):32767 字节(需开启参数 max_string_size=EXTENDED)。GaussDB仅支持 BYTE 单位:定义如 VARCHAR2(n) 时,n 固定为字节长度(例如 VARCHAR2(100) 表示 100 字节)。不支持 CHAR 单位,多字节字符需手动计算字节占用(如 UTF-8 中文字符需预留 3-4 字节)。 2. 最大容量限制Oracle受 MAX_STRING_SIZE 参数控制:STANDARD 模式:4000 字节EXTENDED 模式:32767 字节(实际受数据库块大小限制)。GaussDB固定最大长度:10 MB(10485760 字节),远大于 Oracle 的扩展模式上限。 3. 存储机制与校验Oracle严格校验输入长度:插入超过定义长度的数据直接报错(除非显式截断)。存储变长数据,仅占用实际字节空间(无填充)。GaussDB长度定义仅为建议值:实际插入时不校验字节长度是否超限(例如定义 VARCHAR2(5) 仍可插入 'tooooo_long',仅警告不报错)。超长数据自动截断至定义长度(如 'too long'::VARCHAR2(5) 存储为 'too l')。 4. 空字符串的处理Oracle空字符串 '' 自动转换为 NULL,即 VARCHAR2 字段不允许存储空字符串。GaussDB在 A 兼容模式下行为与 Oracle 一致(空字符串转为 NULL)。其他模式下支持存储空字符串(非 NULL)。 5. 多字节字符集支持Oracle通过 CHAR 单位规避字符集影响:例如 VARCHAR2(10 CHAR) 在 UTF-8 下可存储 10 个中文(约 30–40 字节)。GaussDB仅按字节计算长度:若使用 UTF-8 字符集,VARCHAR2(10) 仅能存储约 3 个中文字符(每个汉字占 3–4 字节),需预留更大空间。 6. 别名和兼容性OracleVARCHAR2 是主力字符串类型,VARCHAR 仅为兼容标准 SQL 的别名(实际行为一致)。GaussDBVARCHAR2 是 VARCHAR 的别名,两者功能完全相同(例如 VARCHAR2(10) 等价于 VARCHAR(10))。 对比总结表一下下特性OracleGaussDB长度单位支持 BYTE 或 CHAR仅支持 BYTE最大长度4000 字节(标准) / 32767 字节(扩展)10 MB(10485760 字节)超长数据处理直接报错自动截断(不报错)空字符串视为 NULLA 兼容模式下视为 NULL多字节支持按字符定义(CHAR 单位)需手动计算字节占用类型本质独立类型VARCHAR 的别名 迁移建议长度单位转换:若 Oracle 使用 CHAR 单位,迁移到 GaussDB 时需按字符集重新计算字节长度(如 UTF-8 中文需 原长度 × 3)。空值处理:在 GaussDB 中启用 A 兼容模式(sql_compatibility='A')以保持与 Oracle 的空字符串行为一致。超长数据:依赖应用层校验长度,避免依赖数据库自动截断导致数据丢失。大文本存储:超过 10 MB 的数据需改用 TEXT 或 CLOB 类型。
上滑加载中
推荐直播
-
华为云码道-AI时代应用开发利器2026/03/18 周三 19:00-20:00
童得力,华为云开发者生态运营总监/姚圣伟,华为云HCDE开发者专家
本次直播由华为专家带你实战应用开发,看华为云码道(CodeArts)代码智能体如何在AI时代让你的创意应用快速落地。更有华为云HCDE开发者专家带你用码道玩转JiuwenClaw,让小艺成为你的AI助理。
回顾中 -
Skill 构建 × 智能创作:基于华为云码道的 AI 内容生产提效方案2026/03/25 周三 19:00-20:00
余伟,华为云软件研发工程师/万邵业(万少),华为云HCDE开发者专家
本次直播带来两大实战:华为云码道 Skill-Creator 手把手搭建专属知识库 Skill;如何用码道提效 OpenClaw 小说文本,打造从大纲到成稿的 AI 原创小说全链路。技术干货 + OPC创作思路,一次讲透!
回顾中 -
码道新技能,AI 新生产力——从自动视频生成到开源项目解析2026/04/08 周三 19:00-21:00
童得力-华为云开发者生态运营总监/何文强-无人机企业AI提效负责人
本次华为云码道 Skill 实战活动,聚焦两大 AI 开发场景:通过实战教学,带你打造 AI 编程自动生成视频 Skill,并实现对 GitHub 热门开源项目的智能知识抽取,手把手掌握 Skill 开发全流程,用 AI 提升研发效率与内容生产力。
回顾中
热门标签