- 主题:如何写一个函数能够序列化任意结构
明白了,除了根据表定义生成数据结构,带正反序列化到某种指定结构化的文档或数据格式,
你的另一个研究点在于从数据库里拖出一块内存,像解析流一样,或先分行,再把每行分成字段(根据每个成员变量的描述,即字节长度),这样一大块内存(查询结果)就变成了多个C的结构体。
只考虑字节长度是不够的,还要考虑对齐问题。这用C语言来做描述挺合适。我的应用数据库不是重点,没考虑这个。不过好奇,每种数据库查询结果,内存块里各行的各字段,对齐是一样的吗?应该也需要实战调试到稳定吧。
sqlite里,查询结果,访问某行的每一列时,有类似getColumn(i)的操作,我没考虑自己解析二进制流算偏移的问题,不擅长,也不喜欢。看你的描述,这是你“绑定1000行”、提高插入查询速度的关键。
第一范式有意思。规范的表设计不应该嵌套。我这里原始的程序存储不是用数据库,是xml,所以我生成的结构体还要支持嵌套。方案就是让生成的结构体统一继承自某个模板类CRTP<P> + enable_if<std::is_base_of>
听了你的描述,感觉到语言确实会影响人的思维和方案的选定。我弄的那套东西,因为一些原因,还用C#改写了一遍,语言原生支持反射,就太简单了。
【 在 ylh0315 的大作中提到: 】
: C的实现是有什么高级的地方吗?
: 不是成员变量指针,相反,成员是指针类型的,除了char,其他的还处理不了。这个设计是基于关系数据库的第一范式,每个成员都是简单类型。
: 每张表生成一个结构体和模板。不带任何函数。
: ...................
--
修改:DoorWay FROM 61.185.187.*
FROM 61.185.187.*
你这个handle是?base也是自己算的吗?
假设查询结果返回1000条记录,怎么遍历这1000条记录,这1000条记录在内存里表示,各个数据库都一样?
不考虑你的结构体,想明白数据库结果集的内存表示。
【 在 ylh0315 的大作中提到: 】
: 介绍一下SQL。
: 在C语言里,SQL语句不过就是一个字符串。而数据是个内存地址。
: 这中间需要一个绑定的过程,就是通知数据库接口,SQL里的变量在哪里找。
: ...................
--
FROM 113.137.205.*
嗯,能理解这个场景。
供应商拿java写的SRM 在市场上已经卖N套,赚得盆满钵满,用起来规模大了发现性能问题搞不定,找到C++来解决。这不是一个正一个逆。
不知道该说c++有绝活,还是应用面狭窄。这话说起来不好听,但我也想不到其他合适的
【 在 ylh0315 (ylh0315) 的大作中提到: 】
: 哪个正,哪个逆,不好说。
: 实际上,一个程序员接受的任务,多数情况是处理一个数据库的问题。
: 数据库已经有了,处理方面性能有问题,才会找到Cer解决。
: 【 在 StephenLee 的大作中提到: 】
--
FROM 124.160.219.*
抱歉我以为楼主的SRM是供应链系统呢,原来还有别的含义,我狭隘了
【 在 StephenLee (薛定谔的猫) 的大作中提到: 】
: 嗯,能理解这个场景。
: 供应商拿java写的SRM 在市场上已经卖N套,赚得盆满钵满,用起来规模大了发现性能问题搞不定,找到C++来解决。这不是一个正一个逆。
: 不知道该说c++有绝活,还是应用面狭窄。这话说起来不好听,但我也想不到其他合适的
:
--
FROM 124.160.219.*
是。
由struct生成模板比较困难,由表结构生成结构和模板比较容易。整个方案是在学习了JAVA的HIBNATE后设计的。
【 在 StephenLee 的大作中提到: 】
: 你这个只适合搞逆向的事情,比如你说的SRM系统。自动化生成你的模板,前提是数据库schema是定义好的。
: ORM一般是正向来干的,用户代码定义结构体,编译自动生成数据库访问相关代码,运行时自动建表
--
FROM 221.218.61.*
整个方案考虑了字节对齐。
每个数据库类型都有c类型对应,按照c类型的对齐规则。
这个设计允许结构套结构,但是不允许套结构指针。
【 在 DoorWay 的大作中提到: 】
: 明白了,除了根据表定义生成数据结构,带正反序列化到某种指定结构化的文档或数据格式,
: 你的另一个研究点在于从数据库里拖出一块内存,像解析流一样,或先分行,再把每行分成字段(根据每个成员变量的描述,即字节长度),这样一大块内存(查询结果)就变成了多个C的结构体。
: 只考虑字节长度是不够的,还要考虑对齐问题。这用C语言来做描述挺合适。我的应用数据库不是重点,没考虑这个。不过好奇,每种数据库查询结果,内存块里各行的各字段,对齐是一样的吗?应该也需要实战调试到稳定吧。
: ...................
--
修改:ylh1969 FROM 221.218.61.*
FROM 221.218.61.*
1000条记录用结构数组表示。
每条记录一个结构,一个数组一个结果集。
int loadfile(char *tablename,FILE *ifd,char *buf,int buflen,char dlmt)
{
char *p,tabn[512];
OAD oad;
int ret;
int n,num;
INT8 now;
T_SQL_Connect *SQL_Connect;
struct batch_data *bp;
char *recs=NULL;
int rec_siz;
ret=get_DB_connect(&SQL_Connect,0);
if(ret) return -1;
// ShowLog(5,"loadfile:entry dlmt=0X%02X",dlmt&255);
now=now_usec();
ret=DAU_init(&_DAU,SQL_Connect,tablename,0,0);//按照tablename表结构,生成模板和数据结构。
if(ret) {
ShowLog(1,"loadfile:DAU_init tabname=%s,ret=%d",tablename,ret);
return -1;
}
rec_siz=DAU_RecSize(&_DAU);//求出struct的尺寸。
。。。。。。。。。
for(rows=0;!ferror(ifd);) {
if(!recs) {
recs=malloc(BATCH_NUM*rec_siz);//分配数组,用完由thread释放
p=recs;
}
if(!fgets(buf,buflen,ifd)) break;
TRIM(buf);
if(!*buf) continue;
pkg_dispack(p,buf,_DAU.srm.tp,dlmt);//用buf的数据填充这个结构
p+=rec_siz;
if(BATCH_NUM == ++n) {
ret=put_to_thread(n,recs);//发射到线程池进行多线程批量插入。
recs=NULL;
n=0;
}
}
}
if(n) {
ret=put_to_thread(n,recs);
n=0;
} else if(recs) free(recs);
【 在 DoorWay 的大作中提到: 】
: 你这个handle是?base也是自己算的吗?
: 假设查询结果返回1000条记录,怎么遍历这1000条记录,这1000条记录在内存里表示,各个数据库都一样?
: 不考虑你的结构体,想明白数据库结果集的内存表示。
--
修改:ylh1969 FROM 221.218.61.*
FROM 221.218.61.*
【 在 DoorWay 的大作中提到: 】
: 你这个handle是?base也是自己算的吗?
: 假设查询结果返回1000条记录,怎么遍历这1000条记录,这1000条记录在内存里表示,各个数据库都一样?
: 不考虑你的结构体,想明白数据库结果集的内存表示。
base和offset的计算是系统的基本功能,一切在此基础之上。
--
FROM 221.218.61.*
【 在 DoorWay 的大作中提到: 】
: 换了一种数据库,你这也方案也得改改生成那部分代码,生成新表的“模板”,对吧?
目前支持ORACLE,DB2,MYSQL。
其他数据库需要重新写数据库接口部分。
hanle叫做DAU,Data Access Unit。其中分为2部分,一个是映象器,就是结构和模板,一个是访问器,包括数据库句柄,游标,绑定区。。。。。。
不同的数据库,访问器需要修改,外部使用的应用程序不需要修改。
--
FROM 221.218.61.*
【 在 Bernstein 的大作中提到: 】
: 那没必要弄成结构,这种处理也没什么意义,因为效率较低
:
必须弄成结构。不然,数据库的批量插入,M行N列,没办法弄通用的批量绑定。
--
FROM 221.218.61.*