【问题标题】:How do you serialize a struct and store it in a MySQL database?如何序列化结构并将其存储在 MySQL 数据库中?
【发布时间】:2011-04-09 20:14:01
【问题描述】:

我将 C++ 用于在线游戏服务器项目,我需要将一些结构作为二进制 blob 存储在 MySQL 数据库中。我正在使用 RakNet 进行网络连接,并尝试使用它的 BitStream 类来序列化数据,但我不知道如何正确操作。我的问题是,如何将结构转换为字节流,您可以通过插入/更新查询将其传递到 MySQL 数据库 blob 中?我正在使用 MySQL 服务器下载附带的 MySQL C 库。

【问题讨论】:

  • 为什么要这样做? dbase 表中的列可以存储结构中字段的值。
  • 我正在为我的游戏服务器试验一个“动作”系统,其中一个实体可以有一个名为“可用”的组件,该组件链接到一个“动作”。我希望动作的类型和参数位于一个表中,参数是一个 blob,因为每个动作的参数都不同。虽然这可能不是一个好方法,但正如我所说,我正在尝试,我喜欢尝试并从中学习。

标签: c++ mysql struct serialization


【解决方案1】:

首先,我不建议对 C++ 结构进行序列化。允许编译器在成员之间插入填充,并且还有其他问题,例如字节序和类型的位宽。

首选方法是分别编写每个字段,最好以人类可读的形式,例如 ASCII 或 Unicode。这允许将来添加、删除或更改字段,而对数据库的更改最少。

也就是说,使用查询将数据发送到 MySQL 数据库。我建议每个类都支持以字符串形式获取其 SQL 数据类型和属性以及其 SQL 值的方法。这将使数据库 I/O 更加通用。

我正在使用 MySQL 下载附带的 C++ 库。我建议您也使用它们,因为您使用的是 C++。

我已将我的数据库包设计为使用访问者设计模式。其中一个访问者是写入数据库的对象。

最好使用准备好的语句插入二进制大对象 (BLOB)。见:MySql Connector prepared statement only transfers 64 bytes

【讨论】:

  • 我是否可以通过将每个字段转换为 (char*) 并将它们连接在一起来分别序列化每个字段?
  • 顺便说一句,这里别提char *,这会让人们感到不安。请改用std::string。我的字段类为它们的返回一个std::string,所以我可以把它放到一个SQL语句字符串中。
【解决方案2】:

如果你的结构中没有指针,你可以直接将它存储为一个 blob,类似于:

void insertBlob(MYSQL *conn, MyStruct *myData)
{
    char myDataEscaped[2 * sizeof(MyStruct) + 1];
    char query[100 + 2 * sizeof(MyStruct) + 1];
    int queryLen;

    mysql_real_escape_string(conn, myDataEscaped, myData, sizeof(MyStruct)); 
    queryLen = snprintf(query, sizeof(query), 
                       "INSERT INTO my_table (id, blobdata) VALUES (NULL, '%s')",
                       myDataEscaped);

    mysql_real_query(conn, query, queryLen);
}

如果您的结构中有指针(指向其他结构或字符串),那么您必须单独拉出每个字段并对其进行序列化,或者创建一个没有指针的新结构来存储数据(只是不要存储指针值本身,因为当您反序列化数据时它们将毫无意义)。有一些libraries mentioned here 可能会有所帮助。

【讨论】:

  • 'myData' 变量是否应该在 mysql_real_escape_string 函数中转换为 (char*)?
  • 完全有可能,我没有通过编译器运行它。 (我的回答灵感来自this example)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-12
  • 1970-01-01
  • 2014-06-18
  • 2018-03-06
  • 1970-01-01
相关资源
最近更新 更多