前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS标准库中常用数据结构和算法之KV数据库

iOS标准库中常用数据结构和算法之KV数据库

作者头像
欧阳大哥2013
发布2019-05-06 17:28:38
7590
发布2019-05-06 17:28:38
举报

对于结构化数据的存储一般我们使用关系型数据库,而对于基于key-value类型的数据存储则不适合用关系型数据库。因此iOS系统也内置了一套基于key-value存储的文件数据库:ndbm。

功能: 一套基于key-value形式存储的数据库。 头文件: #include <ndbm.h> 平台: BSD Unix

1.创建、打开、关闭

功能: 数据库文件的创建、打开、关闭。 函数签名

代码语言:javascript
复制
//数据库文件的创建或者打开
DBM * dbm_open(const char *file, int open_flags, mode_t file_mode);
//数据库文件的关闭
void  dbm_close(DBM *db);

参数: file:[in] 指定数据库的文件名,系统在打开和创建时会在内部自动添加.db的后缀名称,因此我们不需要指定后缀扩展名部分。 open_flags: [in] 文件的打开属性,一般传递O_RDWR | O_CREAT 表明读写以及不存在时创建。 file_mode:[in] 文件的访问权限模式,一般设置为0660。 db:[in] 用于执行数据库关闭的句柄,这个句柄是由数据库文件打开所返回的。 return:[out] 数据库创建成功时返回的数据库句柄指针,数据库句柄指针是一个DBM类型的数据,这个类型对我们透明,也不需要我们去关心, 当打开失败时返回NULL。

2.添加

功能:将某个key-value键值对添加到数据库中。系统并没有对key-value的内容做限制,但是在进行添加处理时必须要转化为如下定义的结构体:

代码语言:javascript
复制
typedef struct {
    void *dptr;    //内存数据的地址
    size_t dsize;  //内存数据的尺寸。
} datum;

函数签名

代码语言:javascript
复制
int dbm_store(DBM *db, datum key, datum content, int store_mode);

参数: db: [in] 数据库句柄。 key:[in] 要插入的key部分的内容。 content:[in] 要插入的value部分的内容。 store_mode:[in] 插入的模式,可以指定为DBM_INSERT或DBM_REPLACE。当指定为DBM_INSERT时表明是插入,如果此时数据库中存在对应的key时则此次操作会返回失败;当指定为DBM_REPLACE时则当不存在时会执行添加处理,而当对应的key存在时就会执行替换处理。 return:[out] 当添加成功时返回0,当返回1时表明插入一个已经存在的key,当返回-1时表明插入失败。

删除

功能: 从数据库中删除某个key-value键值对。 函数签名:

代码语言:javascript
复制
 int dbm_delete(DBM *db, datum key);

参数: db: [in] 数据库句柄。 key:[in] 要删除的键。 return:[out] 如果返回0则删除成功,返回1则表明不存在指定的key,返回-1则是其他错误。

查询

功能: 根据指定的key从数据库中查找对应的value值。 函数签名:

代码语言:javascript
复制
 datum dbm_fetch(DBM *db, datum key);

参数 db:[in] 数据库句柄。 key:[in] 查找指定的key return:[out] 系统返回一个结构体datum, 存储返回的value值。如果key没有对应的value 值, 那么返回的datum中的dptr的值将是NULL。我们不需要对返回的值进行内存释放,也不能对返回的值的内容进行修改。

遍历

功能:系统提供了两个遍历的函数,分别是获取整个数据库中最开始的key值,以及获取下一个有效的key值的函数. 函数签名:

代码语言:javascript
复制
//获取第一个存储的key值。
 datum dbm_firstkey(DBM *db);

//获取下一个存储的key值。
 datum dbm_nextkey(DBM *db);

参数: db:[in]数据库句柄 return: 返回对应的key值,如果没有key值那么返回的结构体中的dptr的值将是NULL。

描述: 你可以通过这两个函数来依次遍历整个数据库中的key值,然后再结合dbm_fetch来获取对应的value。需要注意的是如果某次遍历期间中执行了插入或者删除操作则应该要重新进行遍历,否则得到的结果未可知。

示例代码:

代码语言:javascript
复制
//遍历函数
void traversendbm(DBM *dbm)
{
    printf("start:-------------\n");

    datum key = dbm_firstkey(dbm);
    while (key.dptr != NULL)
    {
        datum val = dbm_fetch(dbm, key);
        if (val.dptr != NULL)
        {
            printf("key=%s, val=%s\n",key.dptr, val.dptr);
        }
        
        key = dbm_nextkey(dbm);
    }
    
    printf("end:-------------\n");
}

void main()
{
    DBM *dbm = dbm_open("/Users/apple/testdb", O_RDWR | O_CREAT, 0660);
    
    datum key1,val1,key2,val2;
    key1.dptr = "aa";
    key1.dsize = 3;
    key2.dptr = "bb";
    key2.dsize = 3;
    val1.dptr = "vvv1";
    val1.dsize = 5;
    val2.dptr = "vvv2";
    val2.dsize = 5;
    
    //添加
    if (dbm_store(dbm, key1, val1, DBM_INSERT) < 0)
    {
        printf ("insert error:%d\n", dbm_error(dbm));
    }
    
    if (dbm_store(dbm, key2, val2, DBM_INSERT) < 0)
    {
        printf ("insert error:%d\n", dbm_error(dbm));
    }
    
    traversendbm(dbm);
    
    //替换
    val1.dptr = "vvv3";
    val1.dsize = 5;
    if (dbm_store(dbm, key1, val1, DBM_REPLACE) < 0)
    {
        printf ("insert error:%d\n", dbm_error(dbm));
    }
    
    traversendbm(dbm);
    
    //删除
    int ret1 = dbm_delete(dbm, key1);  
   
    trandbm(dbm);
    
     //关闭 
    dbm_close(dbm);
}

在iOS系统的内部实现中所有的添加或者删除操作如果不执行dbm_close的话那么都不会实际保存到磁盘文件中。但是其他的Unix系统则会执行磁盘保存操作,这里再次鄙视一下iOS的实现。但是另外一个原因可能是为了性能上的考虑吧,因此如果你在iOS系统中使用这套API则要记得在合适的时候执行数据库关闭处理。

有一些Unix系统中对key-value的长度限制为1024而有些系统则没有这个限制。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.04.21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.创建、打开、关闭
  • 2.添加
  • 删除
  • 查询
  • 遍历
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档