数据存取

数据存取

通过一组定义好的接口操作数据库,这些接口及其实现主要定义在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 查看本文章

采用二进制存储的数据的问题

主要有两个问题:

  1. 如果结构体(二进制数据)长度变小了,那么数据库中的数据就会不够拷贝。

  2. 如果结构体(二进制数据)中间插入了其他的数据成员,那么数据库中的数据就会错误拷贝。

两种问题都是严重的错误,前者通常会无法正确初始化(角色无法登陆),后者则会造成数据错乱。

所以我们对于二进制存储的数据,只能往后追加内容。如果预感将来将会扩展内容,那么应该适当预留一些数据成员,并将其初始化为0。如下:

struct SomeParam
{
    SomeParam() { this->Reset(); }
    void Reset()
    {
        active_flag = 0;
        reserve = 0;
    }

    unsigned short active_flag;
    unsigned short reserve;
};

猜你喜欢

转载自blog.csdn.net/jonWei/article/details/82319342