前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >MogDB大对象LargeObject存取测试

MogDB大对象LargeObject存取测试

作者头像
数据和云
发布于 2022-02-25 09:35:01
发布于 2022-02-25 09:35:01
45800
代码可运行
举报
文章被收录于专栏:数据和云数据和云
运行总次数:0
代码可运行

openGauss/MogDB数据库里bytea二进制类型受segment size编译参数限制,默认不能超过1GB,如果字段存储数据超过1GB可以使用lo(Large Object)扩展类型。

01

lo类型需要先创建lo extension

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ gsql -p5432 -Uomm postgres -r
gsql ((MogDB 2.0.1 build f892ccb7) compiled at 2021-07-09 16:15:21 commit 0 last mr  )
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.

postgres=# create extension lo;
CREATE EXTENSION

创建完lo扩展,我们新建test_lo表,info字段使用lo类型。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
postgres=# create table test_lo(id int,info lo);
CREATE TABLE

创建test_lo表管理触发器,对update和delete操作使用lo_manage函数管理,不然会产生孤立大对象。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
postgres=# create trigger test_lo before UPDATE OR DELETE ON test_lo FOR EACH ROW EXECUTE procedure lo_manage(info);
WARNING:  Trigger function with non-plpgsql type is not recommended.
DETAIL:  Non-plpgsql trigger function are not shippable by default.
HINT:  Unshippable trigger may lead to bad performance.
CREATE TRIGGER

使用dd生成2GB文件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
postgres=#  \! dd if=/dev/zero of=test_lo bs=1M count=2048 && sync
记录了2048+0 的读入
记录了2048+0 的写出
2147483648字节(2.1 GB2.0 GiB)已复制,0.805435 s,2.7 GB/s

02

测试lo_import函数导入数据到数据表

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
postgres=# insert into test_lo values(1,lo_import('/home/omm/test_lo'));
INSERT 0 1

可以看到数据可以正常导入,如果不使用lo类型,使用bytea类型会提示下面的报错。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ERROR:  requested length too large

03

测试lo_export函数导出数据表数据到文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
postgres=# select lo_export(test_lo.info,'/home/omm/test_ext_lo') from test_lo where id=1;
 lo_export 
-----------
         1
(1 row)

可以看到数据正常导出。

查看导入导出的数据文件,也可以使用diff命令进行比对。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
postgres=# \! ls -lh test_*
-rw-r--r-- 1 omm dbgrp 2.0G 1217 13:00 test_ext_lo
-rw------- 1 omm dbgrp 2.0G 1217 12:58 test_lo

04

查看数据表大对象字段大小

分两步进行,首先查大对象字段的oid(lo类型字段在用户表里面只存储一个oid引用指针,并不实际存数据)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
postgres=# select * from test_lo;
 id | info  
----+-------
  1 | 16392
(1 row)

实际数据使用多条bytea记录存储在pg_largeobject表,可以根据oid查询统计字段的大小。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
postgres=# select loid,pg_size_pretty(sum(octet_length(data)))
from pg_largeobject 
where loid =16392  
group by loid;
 loid  | pg_size_pretty 
-------+----------------
 16392 | 2048 MB
(1 row)

也可以使用如下函数来查询:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
create or replace function get_lo_size(oid)
returns bigint
volatile strict
as $function$
declare
    fd integer;
    sz bigint;
begin
    fd := lo_open($1, x'40000'::int);
	perform lo_lseek64(fd, 0, 2);
    sz := lo_tell64(fd);
    perform lo_close(fd);
    return sz;
end;
$function$ language plpgsql;

查询结果如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
postgres=# select pg_size_pretty(get_lo_size(16392));
 pg_size_pretty 
----------------
 2048 MB
(1 row)

再来测试JDBC应用层的使用:

05

JDBC-Java文件入库

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	public static void main(String[] args) throws Exception{ 
		Class.forName("org.postgresql.Driver");

		Connection conn = DriverManager.getConnection("jdbc:postgresql://ip:port/dbname","username","password");
		
		conn.setAutoCommit(false);
		
		LargeObjectManager lobj = conn.unwrap(org.postgresql.PGConnection.class).getLargeObjectAPI();

		long oid = lobj.createLO(LargeObjectManager.READ | LargeObjectManager.WRITE);

		LargeObject obj = lobj.open(oid, LargeObjectManager.WRITE);

		File file = new File("c:/work/test_lo");
		FileInputStream fis = new FileInputStream(file);

		byte buf[] = new byte[10*1024*1024];
		int s, tl = 0;
		while ((s = fis.read(buf, 0, 2048)) > 0)
		{
		    obj.write(buf, 0, s);
		    tl += s;
		}

		obj.close();

		PreparedStatement ps = conn.prepareStatement("INSERT INTO test_lo VALUES (?, ?)");
		ps.setInt(1, 100);
		ps.setLong(2, oid);
		ps.executeUpdate();
		ps.close();
		fis.close();

		conn.commit();
		conn.close();
		
	}

06

JDBC-Java读数据输出到文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	public static void main(String[] args) throws Exception{ 
		Class.forName("org.postgresql.Driver");

		Connection conn = DriverManager.getConnection("jdbc:postgresql://ip:port/dbname","username","password");

		conn.setAutoCommit(false);

		LargeObjectManager lobj = conn.unwrap(org.postgresql.PGConnection.class).getLargeObjectAPI();

		PreparedStatement ps = conn.prepareStatement("SELECT info FROM test_lo WHERE id = ?");
		ps.setInt(1, 100);
		ResultSet rs = ps.executeQuery();
		
		File file = new File("c:/work/test_out_lo");
		FileOutputStream fos = new FileOutputStream(file);
		
		while (rs.next())
		{
		    long oid = rs.getLong(1);
		    LargeObject obj = lobj.open(oid, LargeObjectManager.READ);

			byte buf[] = new byte[10*1024*1024];
			int s, tl = 0;
			while ((s = obj.read(buf, 0, 2048)) > 0)
			{
				fos.write(buf, 0, s);
			    tl += s;
			}

		    obj.close();
		}
		rs.close();
		ps.close();
		fos.close();

		conn.commit();
		conn.close();
		
	}

Jdbc-Java Large Object示例参考:(复制链接至浏览器中浏览)

https://jdbc.postgresql.org/documentation/head/binary-data.html


墨天轮原文链接:https://www.modb.pro/db/214758?sjhy

关于作者

彭冲,云和恩墨PG技术顾问,网名“多米爸比”,PG社区认证专家,中国首期PostgreSQL ACE Partner,多年从事基于PostgreSQL数据库的软件研发,擅长于PL/PGSQL业务迁移及优化,Oracle到PostgreSQL的迁移升级,异构数据库整合;作为墨天轮PostgreSQL实践专栏作者,热衷于PostgreSQL实践技术分享,在自己的岗位积极推广PostgreSQL,致力为PG社区多做奉献。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-01-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据和云 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
判断手机上是否安装某个APP(iOS)
今天项目中有一需求,判断手机上是否安装百度或高德地图,如果安装了,点击导航时选择百度,高德,或苹果地图,如果没有安装则直接苹果地图导航。
honey缘木鱼
2019/05/30
5.9K0
ios 跳转第三方App实现导航
要跳转第三方App实现导航就首先需要了解两个问题 1.怎么判断手机上是否安装了第三方导航App 2.怎么实现跳转到第三方App
赵哥窟
2018/09/13
2.6K0
ios 跳转第三方App实现导航
两个app应用之间的跳转
一,应用跳转的原理 从一个应用跳转到另一个应用,作为APP开发者,最熟悉的莫过于第三方登录,支付宝,微信支付时,那时候我们可能仅仅按照集成文档一步一步操作,在文档中配置很多类似URL Schemes
honey缘木鱼
2018/07/05
2.9K0
基础篇-应用之间的跳转
在应用A跳转到应用B,则给A、B自身自定义URL Schemes(自定义的协议头)后,通过在A中处理B的URL Schemes,就可以在A中启动B了。
進无尽
2018/09/12
9320
基础篇-应用之间的跳转
iOS开发之诱导用户为自己的App评论功能
allluckly.cn.jpg "由于我自己的App下载量少,评论也少,出于App的aso优化,想尽办法,而评论是aso里边比较重视的一块,前面的版本都没有诱导用户评论的这一功能,导致有些被动。" 由此自己简单的封装了该功能,下面我们先看看效果图: 1.png 弹出试图并没有做什么处理,就是系统的8.0以前用的UIAlertView8.0以上用的UIAlertController 具体的一些算法,都可以看代码,闲话不多说,直接贴码, 新建一个NSObject的类命名为LBToAppStore 具
Bison
2018/07/04
1.1K0
iOS开发--一步步教你彻底学会『iOS应用间相互跳转』
本文首发于我的个人博客:『不羁阁』 https://bujige.net 文章链接:https://bujige.net/blog/iOS-Application-jump.html 这篇文章通过一步步指导,教你彻底学会『iOS应用间相互跳转』问题。文末有Github的学习Demo。 1. 应用间相互跳转简介 在iOS开发的过程中,我们经常会遇到需要从一个应用程序A跳转到另一个应用程序B的场景。这就需要我们掌握iOS应用程序之间的相互跳转知识。 下面来看看我们在开发过程中遇到的应用场景。 2.
程序员充电站
2018/05/31
1.6K0
URL Scheme
本文转自 Migrant的博客,原文:《The Complete Tutorial on iOS/iPhone Custom URL Schemes》
星宇大前端
2022/12/22
1.3K0
URL Scheme
iOS_调起各个地图软件
#pragma mark - 弹出选择地图alert + (void)popMapsAlertWithVC:(UIViewController *)vc toCoor:(CLLocationCoordinate2D)toCoor targetName:(NSString *)targetName { NSArray *mapSchemeArr = @[@"iosamap://", @"baidumap://", @"qqmap://", @"comgooglemaps://"]; NSArray *
mikimo
2022/07/20
3760
iOS 手机网站支付转Native支付(使用WKUIDelegate协议获取url)
为了节约开发成本,很多Native-H5混合App采用手机网站支付的方式去实现支付模块。但手机网站支付的网络依赖比较严重,也通常需要经过更多的验证,这种种原因导致手机网站支付的成功率比Native支付低,对商户的利益造成影响。
网罗开发
2021/01/29
6340
ios捕获异常并发送图片,便于解决bug[通俗易懂]
在开发过程中,我们有时候会留下Bug,用户在使用我们的app 的时候,有时会出现闪退,这时候我们能够让用户给我们发送邮件,以让我们开发者更加高速的地位到Bug的所在。以最快的时间解决。同一时候也提高用户体验。
全栈程序员站长
2022/07/07
2540
iOS系统关于URL Schemes的漏洞探究
    我想这个东西的设计的目的是为了方便App之间的相互调用与通讯,你可以在自己的App中使用OpenURL方法来唤起其他的App。比如微信的URL Schemes是wiexin,我们新建一个工程,实现如下代码后运行程序:
珲少
2018/08/16
2.2K0
iOS系统关于URL Schemes的漏洞探究
实践-小细节Ⅶ
所以网页的y 坐标是 0 ,但是在 iOS 11里面就是无法在 状态栏上显示,iOS11下的系统不会这样会占用 状态栏的位置
進无尽
2018/09/12
9190
实践-小细节Ⅶ
进程/线程间通信
因为线程是共享内存空间的,所以线程间通信相比于进程间通信会简单一些,线程间通信的体现
Helloted
2022/06/07
7680
进程/线程间通信
小程序,公众号,App的微信支付详解
现在我们好多开发应用几乎80%都用到了支付接口,小程序,公众号,App在微信支付上有什么相似于不同呢? 一.APP支付(https://open.weixin.qq.com) 1.项目设置APPID
honey缘木鱼
2018/06/08
4.4K0
IOS开发系列——APP间相互调用专题【整理,部分原创】
如果一个应用程序支持一些已知类型的URL,您就可以通过对应的URL模式和该程序进行通讯。然而,在大多数情况下,URL只是用于简单地启动一个应用程序并显示一些和调用方有关的信息。举例来说,对于一个用于管理地址信息的应用程序,您就可以在发送给它的URL中包含一个Maps程序可以处理的地址,以便显示相应的位置。这个级别的通讯为用户创造一个集成度高得多的环境,减少应用程序重新实现设备上其它程序已经实现的功能的必要性。
江中散人_Jun
2022/03/08
9680
(译)openURL 在 iOS10中已弃用
翻译自:openURL Deprecated in iOS10 译者:Haley_Wong
Haley_Wong
2018/08/22
2.9K0
iOS 禁止使用H5加载核心功能的解决办法
iOS 审核规则的每次变动对于iOSer来说都是一次大的震荡,今天我们针对禁用H5加载核心功能给出一种解决办法。 众所周知iOS时可用通过URL Schemes来实现App跳转传值的,不过这种方式正在被逐渐废弃(当然了支付宝依然在用,但是微信支付已经启用了Universial Link)改投更加好用的Universial Link啦。
大话swift
2020/03/26
1.3K0
iOS 禁止使用H5加载核心功能的解决办法
【IOS开发高级系列】App间跳转专题
        如果一个应用程序支持一些已知类型的URL,您就可以通过对应的URL模式和该程序进行通讯。然而,在大多数情况下,URL只是用于简单地启动一个应用程序并显示一些和调用方有关的信息。举例来说,对于一个用于管理地址信息的应用程序,您就可以在发送给它的URL中包含一个Maps程序可以处理的地址,以便显示相应的位置。这个级别的通讯为用户创造一个集成度高得多的环境,减少应用程序重新实现设备上其它程序已经实现的功能的必要性。
江中散人_Jun
2023/10/16
1K0
【IOS开发高级系列】App间跳转专题
iOS开发中支付宝支付的集成(其实很简单)
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010105969/article/details/77865207
用户1451823
2018/09/13
8170
ios应用接入微信开放平台
公众平台针对的是公众账号,除了提供管理后台之外。也开放了若干接口,让微信server和开发人员自己的应用系统可以对接
全栈程序员站长
2022/07/07
7650
相关推荐
判断手机上是否安装某个APP(iOS)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档