数据存取
通过一组定义好的接口操作数据库,这些接口及其实现主要定义在dataaccess/datalayer
目录下。
数据表分类
数据库的表可以分成两类,一类是缓存的,一类是非缓存的。缓存的表通过fastdb接口来操作,非缓存的表通过mysql API操作。但我们会使用统一的接口操作。
这些接口定义在DBCommand。
对于缓存的表,也分成两类,一类是启动时加载进缓存,一类是运行时加载进缓存。运行时加载进缓存的典型例子就是role表。启动时加载进缓存的表通常是全局数据表。
为什么role表不是启动时加载进缓存的表?
默认情况下,所有的表都是缓存的表,且都是运行时加载的,因此,对于不是这样的表,我们必须在配置中列出来。这个配置在commonconfig.xml。
我们要确保在操作缓存的表前,相应的数据已经加入到缓存中了,如果没有,则会造成严重的错误。不过这个工作基本不需要我们考虑,因为已经做好了。
二进制数据的存储
为什么存储字段长度要大于二进制数据长度的2倍?
我们必须把二进制数据转换成一个字符串来存储,这是因为接口的限制,参见文件dataadapter.h。
转换的方法是:
// 将二进制数据转换成16进制字符串
// 注意,hex_buff 的空间必须2倍length以上
void BinToHex(const char *data, int length, char *hex_buff);
// 将16进制字符串转换回二进制数据
// 注意,data必须 1/2的length以上
void HexToBin(const char *hex_buff, int length, char *data);
所以hex_buff至少要是data的两倍以上也是由于接口的限制。
扫描二维码关注公众号,回复:
3031263 查看本文章
采用二进制存储的数据的问题
主要有两个问题:
如果结构体(二进制数据)长度变小了,那么数据库中的数据就会不够拷贝。
如果结构体(二进制数据)中间插入了其他的数据成员,那么数据库中的数据就会错误拷贝。
两种问题都是严重的错误,前者通常会无法正确初始化(角色无法登陆),后者则会造成数据错乱。
所以我们对于二进制存储的数据,只能往后追加内容。如果预感将来将会扩展内容,那么应该适当预留一些数据成员,并将其初始化为0。如下:
struct SomeParam
{
SomeParam() { this->Reset(); }
void Reset()
{
active_flag = 0;
reserve = 0;
}
unsigned short active_flag;
unsigned short reserve;
};