大文本与图像数据在数据库内部的存储原理

作者&投稿:大叔残 (若有异议请与网页底部的电邮联系)
1. 论文写作时间:截止到2010年12月21日,逾期成绩按0分计算。
2. 论文写作要求:
(1) 独立性。要求每名学生独立写作完成。
(2) 论文相关资料。允许网上搜索,并对有用的资料借鉴参考,但不可原封不动地抄袭。
(3) 论文可不要求有太多创新,主要是在别人的基础上进行总结认识和深化。
3.论文提交要求:
论文要求用Word编写,文件名为“学号姓名.doc” ,字体大小统一为小四,中文为宋体,英文及数字用Times New Roman字体样式,段落间距单倍距离,完成后交给各班学委。

图像使用二进制方式存储在数据库中的
文本是用text类型存在数据库中

分析大文本与图像数据在数据库内部的存储原理。~

图像数据在数据库内部的存储原理:
XML 是文本型的数据交换结构,对于字符类型的文本交换非常的方便,实际工作中我们往往需要通过 XML 将二进制格式的图形图像信息数据进行数据交换。本文从介绍 BASE64 编码的原理入手,通过采用 C 语言编写 DB2 的嵌入存储过程,实现了在数据库内存中将文本格式的图片文件到二进制 BLOB 字段之间的转换,并且就性能优化等提出若干建议,该设计思路和程序可以广泛的应用到图像图形数据在 XML 的存储和转换。


--------------------------------------------------------------------------------
回页首
XML 存储图形图像的基本原理

XML 作为一种非常广泛的数据交换的载体被广泛的应用到了各行各业的数据交换中。对于图形图像数据的转换,需要采用 Base64 编码将二进制格式的图形图像信息转换成文本格式再进行传输。

Base64 编码转换的思想是通过 64 个 ASCII 字符码对二进制数据进行重新编码组合,即将需要转换的数据每三个字节(24 位)为一组,再将这 24 位数据按每组 6 位进行重新划分,在每组的最高 2 位填充 0 最终成一个完整的 8 位字节。如果所要编码的数据的字节数不是 3 的整数倍,需要在最后一组数据填充 1 到 2 个字节的 0 字节。例如:我们对 ABC 进行 BASE64 的编码,ABC 的编码值:A(65), B(66), C(67)。再取二进制 A(01000001)B(01000010)C(01000011)连接起来构成 010000010100001001000011,然后按 6 位为单位分成 4 个数据块并在最高位填充两个 0 后形成 4 个字节的编码后的值(00010000)(00010100)(00001001)(00000011)。再将 4 个字节的数据转换成十进制数为(16)(20)(19)(3)。最后根据 BASE64 给出的 64 个基本字符表,查出对应的 ASCII 码字符(Q)(U)(J)(D)。这里的值实际就是数据在字符表中的索引。

BASE64 字符表:

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789。


某项目的数据交换采用 XML 的为介质,XML 的结构包括个人基本信息:姓名、性别、相片等信息,其中相片信息是采用经过 BASE64 函数转换后的文本型数据,图像图形信息通过 BASE64 进行数据转换后,形成文本格式的数据类型,再将相应的数据存放到 XML 中,最终形成可供交换的文本型的 XML 数据结构。

XML 的数据结构如下所示:



10
2007-10-18


张三

/9j/4AAQSkZJRgABAQAAAQABAAD......




--------------------------------------------------------------------------------
回页首
相片数据在 DB2 嵌入式 C 程序的实现方法

该项目要求能够在 DB2 数据库中将相片数据存储为二进制 BLOB 格式。我们采用 DATASTAGE 进行 XML 数据加载,将 XML 中的姓名、性别等基本数据项加载到相应的字段,其中文本型的相片数据则加载到 CLOB 字段中,再按照 BASE64 的编码规则进行逆向转码,整个数据流程如下图所示:


图 1. 相片存储流程图


用户的相片每天的更新数据为 30 万条,而且每个相片的平均大于 32KB,为了获得最佳的数据库性能,选择采用 C 存储过程的方式开发了 BASE64 的转换函数。每次函数读取存储在 CLOB 字段的文本格式数据全部存储到内存中,并且通过 decode 函数在内存中进行转码,转码后再存入数据库中。

程序的清单 1 是逐行读取 CLOB 字段,并且调用 decode 函数进行转码;程序的清单 2 是 decode 函数的关键性代码。完整的程序见源代码下载部分。


清单 1. 读入 CLOB,写入 BLOB 字段

EXEC SQL BEGIN DECLARE SECTION;
SQL TYPE IS CLOB(100 K) clobResume; //CLOB 结构体变量
SQL TYPE IS BLOB(100 K) blobResume; //BLOB 结构体变量

sqlint16 bobind;
sqlint16 lobind;
sqlint16 cobind;
sqlint32 idValue;

EXEC SQL END DECLARE SECTION;
int clob2bin(void)
{
// 声明 SQLCA 结构
struct sqlca sqlca;
int charNb;
int lineNb;
long n;
n=0;

// 定义数据库游标
EXEC SQL DECLARE c1 CURSOR WITH HOLD FOR
SELECT czrkxp_a
FROM CZRK_blob for update;
EXEC SQL OPEN c1;

// 活动 CLOB 字段的信息,已经 CLOB 字段的大小
EXEC SQL FETCH c1 INTO :clobResume:cobind;
// 循环读取 CLOB 字段,并且调用 DECODE 转码函数
while (sqlca.sqlcode != 100)
{
if (cobind < 0)
{
printf(“ NULL LOB indicated.
”);
}
else
{
n++;
decode(); // 文本格式到二进制流的转码函数
printf(“
Current Row =%ld”,n);
// 数据写入 BLOB 字段
EXEC SQL update czrk_blob set czrkxp_blob = :blobResume
where current of c1; ;
// 提交事务
EXEC SQL COMMIT;
}
EXEC SQL FETCH c1 INTO :clobResume:cobind ;
}
// 关闭游标
EXEC SQL CLOSE c1;
EXEC SQL COMMIT;
return 0;
}



清单 2. 文本文件到二进制文件的转换

void decode( void )
{
unsigned char in[4], out[3], v;
int I, len;
long j,k;
j = -1;
k=0;
// 将读入 CLOB 结构体变量的数据进行转换
while( j < clobResume.length){
for( len = 0, I = 0; I < 4 && ( j < clobResume.length ); i++ ) {
v = 0;
while((j < clobResume.length) && v == 0 ) {
j++;
v = (unsigned char) clobResume.data[j];
v = (unsigned char) ((v 122) ? 0 : cd64[ v – 43 ]);
if( v ) {
v = (unsigned char) ((v == ‘$’) ? 0 : v – 61);
}
}
if( j < clobResume.length ) {
len++;
if( v ) {
in[ I ] = (unsigned char) (v – 1);
}
}
else {
in[i] = 0;
}
}
if( len ) {
decodeblock( in, out );
// 写入到 BLOB 结构体变量中
for( I = 0; I < len – 1; i++ ) {
blobResume.data[k] = out[i];
k++;
}
}
}
blobResume.length= k;
}



--------------------------------------------------------------------------------
回页首
数据的转换效率和优化建议

在 IBM P570 数据库服务器上运行,该程序的运行效率非常高,先后进行了几个数量级的测试,最终平均测试的转换效率为:每 1 万笔数据记录,转换的效率 55 秒,即 182 条 / 秒。值得注意的是,整个转换过程占用 CPU 的量并不特别大,主要的性能瓶颈在磁盘阵列中。

以后可以进一步在以下方面进行调优,确保程序转换的效率更高:

1)采用多进程调用的方式,以获得更高的并发数量;

2)采用每 10 次或者 100 次提交事务的方式,减少访问磁盘的次数;

3)将 CLOB 和 BLOB 分别放置在不同的表空间上,并且将表空间分布在在多个磁盘上,获得最佳的磁盘访问速度。

向数据库中保存不同类型的文件,和在数据库中保存图片是一样的。就是向数据库以byte形式存入
向数据库中保存不同类型的文件,和在数据库中保存图片是一样的。就是向数据库以byte形式存入

然后就是写入数据库,代码如下:

FileInfo fi = new FileInfo( txtFileName.Text );// Replace with your file name if ( fi.Exists { byte[] bData = null;
int nNewFileID = 0;
// Read file data into buffer
using ( FileStream fs = fi.OpenRead() ) {
bData = new byte[fi.Length];
int nReadLength = fs.Read( bData,0, (int)(fi.Length) );
}
// Add file info into DB
string strQuery = "INSERT INTO FileInfo "
+ " ( FileName, FullName, FileData ) "
+ " VALUES "
+ " ( @FileName, @FullName, @FileData ) "
+ " SELECT @@IDENTITY AS 'Identity'";
SqlCommand sqlComm = new SqlCommand( strQuery, sqlConn );
sqlComm.Parameters.Add( "@FileName", fi.Name );
sqlComm.Parameters.Add( "@FullName", fi.FullName );
sqlComm.Parameters.Add( "@FileData", bData ); // Get new file ID
SqlDataReader sqlReader = sqlComm.ExecuteReader();
if( sqlReader.Read() )
{
nNewFileID = int.Parse(sqlReader.GetValue(0).ToString());
} sqlReader.Close(); sqlComm.Dispose();
if( nNewFileID > 0 ) { // Add new item in list view
ListViewItem itmNew = lsvFileInfo.Items.Add( fi.Name );
itmNew.Tag = nNewFileID; } }
4.而读出的代码如下:
// Get new file name
string strFullName = dlgFBSave.SelectedPath;
if( strFullName[strFullName.Length - 1] != '//' )
strFullName += @"/";
strFullName += lsvFileInfo.SelectedItems[0].Text;
string strQuery = "SELECT FileData FROM FileInfo "
+ " WHERE FileID = " + lsvFileInfo.SelectedItems[0].Tag.ToString();
SqlDataAdapter sqlDAdapter = new SqlDataAdapter(strQuery,sqlConn);
DataSet sqlRecordSet = new DataSet();
byte[] bData = null;
//Get file data from DB
try
{
sqlDAdapter.Fill( sqlRecordSet, "FileInfo" );
foreach( DataRow dr in sqlRecordSet.Tables["FileInfo"].Rows)
{
if( dr["FileData"] != DBNull.Value )
bData = ( byte[] )dr["FileData"];
}
}
catch(SqlException sqlErr)
{
MessageBox.Show( sqlErr.Message );
}
catch
{
MessageBox.Show( "Failed to read data from DB!" );
}
sqlRecordSet.Dispose();
sqlDAdapter.Dispose();

if( bData != null )
{
// Save file
FileInfo fi = new FileInfo( strFullName );
if( !fi.Exists )
{
//Create the file.
using (FileStream fs = fi.Create())
{
fs.Write( bData, 0, bData.Length);
}
}
else
{
//Create the file.
using (FileStream fs = fi.OpenWrite())
{
fs.Write( bData, 0, bData.Length);
}
}
}

怎么将图片和文字同时存入数据库的一个字段内?
答:1 可以用base64,把图片转换成二进制储存 2 百度贴吧是这样干的:上传图片、在文本编辑框里写路径,数据库里存的是html 图片自然就是标签了

如何将图像文件存入到数据库中
答:2.从SQLServer数据库读取Image类型的数据,并转换成bytes[]或Image图像文件 //要使用要加载usingSystem.Data.SqlClient命名空间 //将数据库中的Image类型转换成byte[]publicbyte[]SetImage(reader){ return(byte[])reader["Image"];//Image为数据库中存放Image类型字段 } //将byte[]转换成Image图像...

将图片储存在MySQL数据库中的几种方法
答:通常对用户上传的图片需要保存到数据库中。解决方法一般有两种:1、将图片保存的路径存储到数据库;2、将图片以二进制数据流的形式直接写入数据库字段中。以下为具体方法:一、保存图片的上传路径到数据库:string uppath="";//用于保存图片上传路径//获取上传图片的文件名string fileFullname = this....

如何像数据库中保存图片?
答:(C#代码)数据表{PictureID int indetity(1,1),PictureData varbinary(MAX)}保存图像byte[] picData = FileUpload1.FileBytes;//获取上传控件中图片二进制数据picID = AddPicture(FileUpload1.FileName.ToString(), picData);//保存图像二进制数据到数据库 SqlDataReader sdr = GetPicture(picID);/...

数据库中存储的是什么
答:储存的是数据以及数据之间的联系。数据库是按照数据结构来组织、存储和管理数据的仓库,其实简单来说数据库中存储的是结构化的数据,它们可以是数字,字符串,文本,图像,甚至是二进制文件。数据库中的数据按照一定的结构组织,可以方便地检索和更新,而且可以在多台计算机之间共享。数据库中存储的数据需要...

在数据库中储存的是
答:数据。数据库是一个用于存储、管理和检索数据的系统,能够组织和结构化大量的数据,并提供高效的访问和操作方法,数据库可以存储各种类型的数据,包括文本、数字、图像、音频等,通过数据库管理系统,用户可以创建表、插入数据、查询数据、更新数据以及删除数据等操作,数据库的设计和优化可以提高数据的可靠性...

C#将richtextBox里的内容(图片文字)存入数据库
答:可以考虑将richtextBox里的内容在服务器端保存成一个文档,例如保存为WORD文档,WORD文档是可以同时存文字和图片的。数据库里只放地址。如果你非要把文字和图片都保存在数据库里,那就要看你用的是什么数据库了,用SQL或者ORACL或许还行,MYSQL也还可以。不过,即便是能够保存如此大的数据,读取起来也不...

...如果把richtextbox中的文字图片保存到数据库(access)中。_百度...
答:把你要保存的那个值序列化,保存到文件中,然后以二进制读取出来保存到数据库对应的二进制字段中去

数据库图片能用longtext类型吗
答:可以使用 longtext 类型来存储图片数据,但不建议这么做。这是因为 longtext 类型主要用于存储文本数据,而图片数据通常以字节流的方式存储在文件或数据库中,使用 longtext 类型进行存储会影响数据的读取和处理效率。对于存储图片数据,通常建议使用 BLOB类型,BLOB 类型可以存储二进制数据,包括图片、音频、...

数据库能不能存放图像或声音?
答:但是数据库并不是随意地将数据进行存放,是有一定的规则的,否则查询的效率会很低。当今世界是一个充满着数据的互联网世界,充斥着大量的数据。即这个互联网世界就是数据世界。数据的来源有很多,比如出行记录、消费记录、浏览的网页、发送的消息等等。除了文本类型的数据,图像、音乐、声音都是数据。