SQLite3用于序列化目的

时间:2009-10-11 20:12:42

标签: c++ sql serialization

过去几天我一直在修补SQLite3,它似乎是一个不错的数据库,但我想知道它用于序列化。

我需要序列化一组链接到另一个表的键/值对,这就是我到目前为止这样做的方式。

首先会有项目表:

CREATE TABLE items (id INTEGER PRIMARY KEY, details);

 | id | details |
-+----+---------+
 |  1 | 'test'  |
-+----+---------+
 |  2 | 'hello' |
-+----+---------+
 |  3 | 'abc'   |
-+----+---------+

然后会有每个项目的表格:

CREATE TABLE itemkv## (key TEXT, value);  -- where ## is an 'id' field in TABLE items

 | key | value |
-+-----+-------+
 |'abc'|'hello'|
-+-----+-------+
 |'def'|'world'|
-+-----+-------+
 |'ghi'| 90001 |
-+-----+-------+

这个工作正常,直到我注意到每个表都有一个千字节的开销。如果我只处理一些项目,这是可以接受的,但我需要一个可以扩展的系统。

不可否认,这是我第一次使用与SQL相关的任何东西,所以也许我不知道应该使用什么表,但是我找不到任何“子”的概念。表“或”struct“数据类型。从理论上讲,我可以将键/值对转换为类似的字符串,“abc | hello \ ndef | world \ nghi | 90001”并将其存储在一列中,但这让我想知道是否会破坏使用数据库的目的首先,如果我要将我的结构转换成可以轻松存储在平面文件中的东西。

我欢迎任何人提出任何建议,包括更适合此类序列化目的的不同库的建议。

4 个答案:

答案 0 :(得分:2)

您可以在创建数据库之前,或在创建第一个表之前,或在执行PRAGMA page_size = 512;语句之前尝试VACUUM。 (手册有点矛盾,也取决于sqlite3版本。)

我认为以高速率动态创建表格也很少见。你正在规范你的模式是好的,但是列可以依赖主键,而重复组是标准化程度较低的标志,外键在合理的模式中重复是正常的。也就是说,我认为您很可能只需要一个键/值对表,其中一列标识客户端实例。

请记住,平面文件也有分配单元开销。观察创建单字节文件时会发生什么:

$ cat > /tmp/one

$ ls -l /tmp/one
-rw-r--r-- 1 ross ross 1 2009-10-11 13:18 /tmp/one
$ du -h /tmp/one
4.0K    /tmp/one
$ 

根据ls(1)它是一个字节,根据du(1)它是4K。

答案 1 :(得分:1)

不要为每件物品制作一张桌子。那是错的。类似于在程序中为每个项目编写一个类。为所有项目创建一个表,或者可能存储所有项目的公共部分,其他表格使用辅助信息引用它。帮自己一个忙,阅读数据库规范化规则。

通常,应修复数据库中的表,方法与修复C ++程序中的类相同。

答案 2 :(得分:0)

为什么不将外键存储到items表中?

Create Table ItemsVK (ID integer primary key, ItemID integer, Key Text, value Text)

答案 3 :(得分:0)

如果它只是序列化,即一次性保存到磁盘然后从磁盘进行一次性恢复,则可以使用JSON(recommend C++ libraries列表)。

只需序列化数据结构:

[
  {'id':1,'details':'test','items':{'abc':'hello','def':'world','ghi':'90001'}},
  ...
]

如果要保存一些字节,可以省略iddetailsitems键并改为保存列表:(如果是瓶颈):

[
  [1,'test', {'abc':'hello','def':'world','ghi':'90001'}],
  ...
]