我对sqlite中的BLOB有以下问题:
我问这个是因为我想知道我是否应该实现在其他列中设置BLOBs大小的触发器,如果我可以动态获取大小而没有sqlite读取BLOB的性能损失。
答案 0 :(得分:4)
来自消息来源:
** In an SQLite index record, the serial type is stored directly before
** the blob of data that it corresponds to. In a table record, all serial
** types are stored at the start of the record, and the blobs of data at
** the end. Hence these functions allow the caller to handle the
** serial-type and data blob seperately.
**
** The following table describes the various storage classes for data:
**
** serial type bytes of data type
** -------------- --------------- ---------------
** 0 0 NULL
** 1 1 signed integer
** 2 2 signed integer
** 3 3 signed integer
** 4 4 signed integer
** 5 6 signed integer
** 6 8 signed integer
** 7 8 IEEE float
** 8 0 Integer constant 0
** 9 0 Integer constant 1
** 10,11 reserved for expansion
** N>=12 and even (N-12)/2 BLOB
** N>=13 and odd (N-13)/2 text
换句话说,blob大小在序列中,它的长度只是“(serial_type-12)/ 2”。
此序列存储在实际blob之前,因此您无需读取blob即可获得其大小
调用sqlite3_blob_open然后调用sqlite3_blob_bytes来获取此值。
答案 1 :(得分:0)
如果您有权访问raw c api sqlite3_blob_bytes,则可以为您完成工作。如果没有,请提供其他信息。
答案 2 :(得分:-1)
在测试数据库中写入1byte和10GB blob。如果两个blob的length()
花费相同的时间,则可能会访问blob的长度。否则可能会读取blob。
OR:下载源代码并通过它进行调试:http://www.sqlite.org/download.html。这些是一些相关的部分:
/*
** Implementation of the length() function
*/
static void lengthFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
int len;
assert( argc==1 );
UNUSED_PARAMETER(argc);
switch( sqlite3_value_type(argv[0]) ){
case SQLITE_BLOB:
case SQLITE_INTEGER:
case SQLITE_FLOAT: {
sqlite3_result_int(context, sqlite3_value_bytes(argv[0]));
break;
}
case SQLITE_TEXT: {
const unsigned char *z = sqlite3_value_text(argv[0]);
if( z==0 ) return;
len = 0;
while( *z ){
len++;
SQLITE_SKIP_UTF8(z);
}
sqlite3_result_int(context, len);
break;
}
default: {
sqlite3_result_null(context);
break;
}
}
}
然后
/*
** Return the number of bytes in the sqlite3_value object assuming
** that it uses the encoding "enc"
*/
SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value *pVal, u8 enc){
Mem *p = (Mem*)pVal;
if( (p->flags & MEM_Blob)!=0 || sqlite3ValueText(pVal, enc) ){
if( p->flags & MEM_Zero ){
return p->n + p->u.nZero;
}else{
return p->n;
}
}
return 0;
}
您可以看到文本数据的长度是即时计算的。那个blob ......好吧,我在C中不够流利......: - )