鸿蒙——分布式数据库

一、定义及作用

定义:看这个数据库发展史,不过多赘述

其作用:解决传统集中式数据库在大规模数据存储、高并发访问、高可用保障等场景下的瓶颈问题

二、具体介绍

键值类:

redis数据库

实现核心步骤

  • 创建实例(运行数据库的环境)
  • 配置数据库
  • 实现DDL操作

具体实现步骤为

创建实例

创建实例需要获取组件内的上下文,而不是使用全局变量

private CONFIG: distributedKVStore.KVManagerConfig;

constructor(context: common.Context) {

// 初始化KVManager配置:上下文(运行环境)+ 包名(应用标识)

this.CONFIG = {

context: context,

bundleName: this.bundleName

};

随:KV管理器配置项:存储上下文和应用包名

谁来管理数据库?当然是DBMS (数据库管理系统)啦,那我们就来配置这个让它来帮我们管理数据库,你能想到什么呢?安全,访问越级?需要备份,对的还有我们所谈论的数据库类型。

基操的一些对接:

private kvManager: distributedKVStore.KVManager | null = null;

随:KV管理器(DBMS核心):鸿蒙分布式KV的入口,负责创建/管理KV存储实例

private kvStore: distributedKVStore.SingleKVStore | null = null;

随: KV存储实例(具体数据库):真正用于增删改查的操作对象

private bundleName: string = 'com.example.mytest';

随:应用包名:需替换为实际应用的包名(用于隔离不同应用的KV存储)

管理数据库的具体配置(DBMS 管控参数)

const options: distributedKVStore.Options = {

createIfMissing: true, // 不存在则自动创建数据库

encrypt: false, // 不加密(可改为true开启数据加密,提升安全)

backup: false, // 不备份(可改为true开启数据容灾)

autoSync: true, // 开启分布式自动同步(核心特性:多设备数据同步)

kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION, // 单版本存储(适合简单数据)

securityLevel: distributedKVStore.SecurityLevel.S2 // 安全级别S2(中等安全)

};

初始化实例(创建 DBMS 核心:KVManager)

private async initKVManager(): Promise<boolean> {

// 防止重复创建,已存在,直接返回成功

if (this.kvManager) {

hilog.info(LOG_DOMAIN, LOG_TAG, 'KVManager 已存在,无需重复创建');

return true;

}

try {

// 异步创建KVManager(鸿蒙API:传入配置,创建DBMS)

this.kvManager = await distributedKVStore.createKVManager(this.CONFIG);

hilog.info(LOG_DOMAIN, LOG_TAG, '成功创建 KVManager 实例');

return true; // 创建成功返回true

} catch (err) {

// 捕获错误:转换为鸿蒙BusinessError,打印错误码和信息

const error = err as BusinessError;

hilog.error(LOG_DOMAIN,LOG_TAG, `创建 KVManager 失败,代码:{error.code},信息: {error.message}`);

return false; // 创建失败返回false

}

}

打开实例(创建具体数据库:KVStore)

private async openKVStore(): Promise<boolean> {

// 前置校验:KVManager未初始化,无法打开KVStore

if (!this.kvManager) {

hilog.error(LOG_DOMAIN, LOG_TAG, 'KVManager 未初始化,无法打开 KVStore');

return false;

}

// 防止重复打开:如果KVStore已存在,直接返回成功

if (this.kvStore) {

hilog.info(LOG_DOMAIN, LOG_TAG, 'KVStore 已存在,无需重复打开');

return true;

}

DDL操作()

1、添加/修改数据(PUT操作:键存在则修改,不存在则新增)

async putKVData(kvData: KVData): Promise<boolean> {

// 前置校验:KVStore未初始化则自动触发初始化

if (this.kvStore === null) {

const initOk = await this.getKVStore();

if (!initOk) {

hilog.error(LOG_DOMAIN, LOG_TAG, 'KVStore 初始化失败,无法添加/修改数据');

return false;

}

}

try {

// 异步添加/修改数据:传入键值对(非空断言:已提前校验kvStore非空)

await this.kvStore!.put(kvData.KEY, kvData.VALUE);

hilog.info(LOG_DOMAIN, LOG_TAG, `添加/修改数据成功:{kvData.KEY}={kvData.VALUE}`);

return true; // 操作成功返回true

} catch (err) {

const error = err as BusinessError;

hilog.error(

LOG_DOMAIN,

LOG_TAG,

`添加/修改数据失败,代码: {error.code},信息: {error.message}`

);

return false; // 操作失败返回false

}

}

2、查询数据(GET操作:根据键查询值)

async getKVData(KEY: string): Promise<string> {

// 前置校验:KVStore未初始化则自动触发初始化

if (this.kvStore === null) {

const initOk = await this.getKVStore();

if (!initOk) {

hilog.error(LOG_DOMAIN, LOG_TAG, 'KVStore 初始化失败,无法查询数据');

return '数据库实例不存在!';

}

}

try {

// 异步查询数据:根据键获取值

const data = await this.kvStore!.get(KEY);

// 处理结果:有数据则转为字符串,无数据则为空

const kvData = data ? String(data) : '';

hilog.info(LOG_DOMAIN, LOG_TAG, `查询数据成功:{KEY}={kvData}`);

return kvData; // 返回查询结果

} catch (err) {

const error = err as BusinessError;

hilog.error(

LOG_DOMAIN,

LOG_TAG,

`查询数据失败,代码: {error.code},信息: {error.message}`

);

return '查询失败!'; // 查询失败返回提示

}

}

3、删除数据(DELETE操作:根据键删除数据)

async delKVData(KEY: string): Promise<boolean> {

// 前置校验:KVStore未初始化则自动触发初始化

if (this.kvStore === null) {

const initOk = await this.getKVStore();

if (!initOk) {

hilog.error(LOG_DOMAIN, LOG_TAG, 'KVStore 初始化失败,无法删除数据');

return false;

}

}

try {

// 异步删除数据:根据键删除

await this.kvStore!.delete(KEY);

hilog.info(LOG_DOMAIN, LOG_TAG, `删除数据成功:${KEY}`);

return true; // 删除成功返回true

} catch (err) {

const error = err as BusinessError;

hilog.error(

LOG_DOMAIN,

LOG_TAG,

`删除数据失败,代码: {error.code},信息: {error.message}`

);

return false; // 删除失败返回false

}

}

用户交互层:

1、添加商品

Button('添加商品')

.fontSize(30).backgroundColor(Color.Gray).padding(20).margin(5)

.onClick(async () => { // 点击事件:标记为async,支持await调用异步方法

if (!this.db) return; // 前置校验:DB未初始化则不执行

// 步骤1:创建商品数据(编码0001,名称iphone 16 Pro,价格7999)

const productData = new ProductData('0001', 'iphone 16 Pro', 7999);

// 步骤2:转换为KV存储格式(键:record0001,值:序列化后的商品JSON)

const kvData: KVData = {

KEY: 'record' + productData.商品编码,

VALUE: JSON.stringify(productData)

};

// 步骤3:调用DB的添加方法

const putOk = await this.db.putKVData(kvData);

if (putOk) {

// 步骤4:查询添加结果并更新UI

const val = await this.db.getKVData(kvData.KEY);

this.message = `添加成功:${val}`;

} else {

this.message = '添加失败';

}

})

2、修改商品

Button('修改商品')

.fontSize(30).backgroundColor(Color.Gray).padding(20).margin(5)

.onClick(async () => {

if (!this.db) return;

// 创建新的商品数据(编码0001,名称改为华为70 Pro,价格6399)

const productData = new ProductData('0001', '华为 70 Pro', 6399);

const kvData: KVData = {

KEY: 'record' + productData.商品编码,

VALUE: JSON.stringify(productData)

};

// 调用DB的修改方法(PUT操作:键相同则覆盖)

const putOk = await this.db.putKVData(kvData);

if (putOk) {

const val = await this.db.getKVData(kvData.KEY);

this.message = `修改成功:${val}`;

} else {

this.message = '修改失败';

}

})

3、删除数据

仅在2的基础上替换掉修改即可

const key = 'record0001'; // 要删除的键

// 调用DB的删除方法

const delOk = await this.db.delKVData(key);

if (delOk) {

// 查询删除结果并更新UI

const val = await this.db.getKVData(key);

this.message = `删除成功,查询结果:${val || '无数据'}`;

} else {

this.message = '删除失败';

具体显示结果

Text(this.message)

总代码实现:

复制代码
import distributedKVStore from '@ohos.data.distributedKVStore';
import common from '@ohos.app.ability.common';
import hilog from '@ohos.hilog';
import { BusinessError } from '@ohos.base';

// 2. 商品数据类(支持中文命名)
class ProductData {
  商品编码: string;
  商品名称?: string;
  商品价格?: number;

  constructor(商品编码: string, 商品名称?: string, 商品价格?: number) {
    this.商品编码 = 商品编码;
    this.商品名称 = 商品名称;
    this.商品价格 = 商品价格;
  }
}

// 3. KV数据接口
interface KVData {
  KEY: string; // 键
  VALUE: string; // 值
}

// 4. 日志常量
const LOG_DOMAIN = 0x0000;
const LOG_TAG = 'DistributedDB';

// 5. 分布式DB管理类
class DistributedDB {
  private kvManager: distributedKVStore.KVManager | null = null;
  private kvStore: distributedKVStore.SingleKVStore | null = null;
  private CONFIG: distributedKVStore.KVManagerConfig;
  private bundleName: string = 'com.example.mytest'; // 替换为你的实际包名

  // 构造函数:接收组件上下文
  constructor(context: common.Context) {
    this.CONFIG = {
      context: context,
      bundleName: this.bundleName
    };
  }

  // 方法1:初始化 KVManager
  private async initKVManager(): Promise<boolean> {
    if (this.kvManager) {
      hilog.info(LOG_DOMAIN, LOG_TAG, 'KVManager 已存在,无需重复创建');
      return true;
    }
    try {
      this.kvManager = await distributedKVStore.createKVManager(this.CONFIG);
      hilog.info(LOG_DOMAIN, LOG_TAG, '成功创建 KVManager 实例');
      return true;
    } catch (err) {
      const error = err as BusinessError;
      hilog.error(LOG_DOMAIN,LOG_TAG, `创建 KVManager 失败,代码:${error.code},信息: ${error.message}`
      );
      return false;
    }
  }

  // 方法2:打开 KVStore
  private async openKVStore(): Promise<boolean> {
    if (!this.kvManager) {
      hilog.error(LOG_DOMAIN, LOG_TAG, 'KVManager 未初始化,无法打开 KVStore');
      return false;
    }
    if (this.kvStore) {
      hilog.info(LOG_DOMAIN, LOG_TAG, 'KVStore 已存在,无需重复打开');
      return true;
    }

    const options: distributedKVStore.Options = {
      createIfMissing: true,
      encrypt: false,
      backup: false,
      autoSync: true, // 开启分布式同步(核心)
      kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION,
      securityLevel: distributedKVStore.SecurityLevel.S2
    };

    try {
      this.kvStore = await this.kvManager.getKVStore('product_store', options); // 自定义 storeId
      hilog.info(LOG_DOMAIN, LOG_TAG, '成功打开分布式 KVStore');
      return true;
    } catch (err) {
      const error = err as BusinessError;
      hilog.error(
        LOG_DOMAIN,
        LOG_TAG,
        `打开 KVStore 失败,代码:${error.code},信息: ${error.message}`
      );
      return false;
    }
  }

  // 方法3:对外暴露的初始化入口(原缺失的 getKVStore 方法)
  async getKVStore(): Promise<boolean> {
    const managerOk = await this.initKVManager();
    if (!managerOk) return false;
    const storeOk = await this.openKVStore();
    return storeOk;
  }

  // 方法4:添加/修改数据
  async putKVData(kvData: KVData): Promise<boolean> {
    // 确保 KVStore 已初始化
    if (this.kvStore === null) {
      const initOk = await this.getKVStore();
      if (!initOk) {
        hilog.error(LOG_DOMAIN, LOG_TAG, 'KVStore 初始化失败,无法添加/修改数据');
        return false;
      }
    }

    try {
      await this.kvStore!.put(kvData.KEY, kvData.VALUE); // ! 非空断言(已提前校验)
      hilog.info(LOG_DOMAIN, LOG_TAG, `添加/修改数据成功:${kvData.KEY}=${kvData.VALUE}`);
      return true;
    } catch (err) {
      const error = err as BusinessError;
      hilog.error(
        LOG_DOMAIN,
        LOG_TAG,
        `添加/修改数据失败,代码: ${error.code},信息: ${error.message}`
      );
      return false;
    }
  }

  // 方法5:查询数据
  async getKVData(KEY: string): Promise<string> {
    if (this.kvStore === null) {
      const initOk = await this.getKVStore();
      if (!initOk) {
        hilog.error(LOG_DOMAIN, LOG_TAG, 'KVStore 初始化失败,无法查询数据');
        return '数据库实例不存在!';
      }
    }

    try {
      const data = await this.kvStore!.get(KEY); // 统一用 await 写法,避免 .then 嵌套
      const kvData = data ? String(data) : '';
      hilog.info(LOG_DOMAIN, LOG_TAG, `查询数据成功:${KEY}=${kvData}`);
      return kvData;
    } catch (err) {
      const error = err as BusinessError;
      hilog.error(
        LOG_DOMAIN,
        LOG_TAG,
        `查询数据失败,代码: ${error.code},信息: ${error.message}`
      );
      return '查询失败!';
    }
  }

  // 方法6:删除数据
  async delKVData(KEY: string): Promise<boolean> {
    if (this.kvStore === null) {
      const initOk = await this.getKVStore();
      if (!initOk) {
        hilog.error(LOG_DOMAIN, LOG_TAG, 'KVStore 初始化失败,无法删除数据');
        return false;
      }
    }

    try {
      await this.kvStore!.delete(KEY);
      hilog.info(LOG_DOMAIN, LOG_TAG, `删除数据成功:${KEY}`);
      return true;
    } catch (err) {
      const error = err as BusinessError;
      hilog.error(
        LOG_DOMAIN,
        LOG_TAG,
        `删除数据失败,代码: ${error.code},信息: ${error.message}`
      );
      return false;
    }
  }
}

// 6. 主组件
@Entry
@Component
struct Index {
  @State message: string = '请操作按钮测试';
  private db: DistributedDB | null = null; // 先声明,后初始化

  // 组件生命周期:初始化 DB 实例
  async aboutToAppear() {
    // 正确获取组件上下文
    const context = getContext(this) as common.Context;
    // 实例化 DistributedDB,传入上下文
    this.db = new DistributedDB(context);
    // 初始化 KV 存储
    const initOk = await this.db.getKVStore();
    if (initOk) {
      hilog.info(LOG_DOMAIN, LOG_TAG, '分布式DB初始化成功');
    } else {
      this.message = '分布式DB初始化失败';
    }
  }

  build() {
    Row() {
      Column() {
        Text('商品管理').fontSize(40).fontWeight(FontWeight.Bold).margin(20)

        // 添加商品按钮
        Button('添加商品')
          .fontSize(30)
          .backgroundColor(Color.Gray)
          .padding(20)
          .margin(5)
          .onClick(async () => { // 标记为 async,支持 await
            if (!this.db) return;
            const productData = new ProductData('0001', 'iphone 16 Pro', 7999);
            const kvData: KVData = {
              KEY: 'record' + productData.商品编码,
              VALUE: JSON.stringify(productData)
            };
            // 执行添加操作
            const putOk = await this.db.putKVData(kvData);
            if (putOk) {
              // 查询并展示结果
              const val = await this.db.getKVData(kvData.KEY);
              this.message = `添加成功:${val}`;
            } else {
              this.message = '添加失败';
            }
          })

        // 修改商品按钮
        Button('修改商品')
          .fontSize(30)
          .backgroundColor(Color.Gray)
          .padding(20)
          .margin(5)
          .onClick(async () => {
            if (!this.db) return;
            const productData = new ProductData('0001', '华为 70 Pro', 6399);
            const kvData: KVData = {
              KEY: 'record' + productData.商品编码,
              VALUE: JSON.stringify(productData)
            };
            const putOk = await this.db.putKVData(kvData);
            if (putOk) {
              const val = await this.db.getKVData(kvData.KEY);
              this.message = `修改成功:${val}`;
            } else {
              this.message = '修改失败';
            }
          })

        // 删除商品按钮
        Button('删除商品')
          .fontSize(30)
          .backgroundColor(Color.Gray)
          .padding(20)
          .margin(5)
          .onClick(async () => {
            if (!this.db) return;
            const key = 'record0001';
            const delOk = await this.db.delKVData(key);
            if (delOk) {
              const val = await this.db.getKVData(key);
              this.message = `删除成功,查询结果:${ val || '无数据'}`;
            } else {
              this.message = '删除失败';
            }
          })

        // 结果展示
        Text(this.message).fontSize(25).fontWeight(FontWeight.Bold)
          .margin(20).textAlign(TextAlign.Center).width('80%')
      }
      .alignItems(HorizontalAlign.Center).justifyContent(FlexAlign.Center).width('100%')
    }
    .height('100%')
    .width('100%')
  }
}
相关推荐
李广坤18 小时前
MySQL 大表字段变更实践(改名 + 改类型 + 改长度)
数据库
初次攀爬者2 天前
ZooKeeper 实现分布式锁的两种方式
分布式·后端·zookeeper
爱可生开源社区2 天前
2026 年,优秀的 DBA 需要具备哪些素质?
数据库·人工智能·dba
随逸1772 天前
《从零搭建NestJS项目》
数据库·typescript
加号33 天前
windows系统下mysql多源数据库同步部署
数据库·windows·mysql
シ風箏3 天前
MySQL【部署 04】Docker部署 MySQL8.0.32 版本(网盘镜像及启动命令分享)
数据库·mysql·docker
李慕婉学姐3 天前
Springboot智慧社区系统设计与开发6n99s526(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端
百锦再3 天前
Django实现接口token检测的实现方案
数据库·python·django·sqlite·flask·fastapi·pip
tryCbest3 天前
数据库SQL学习
数据库·sql
jnrjian3 天前
ORA-01017 查找机器名 用户名 以及library cache lock 参数含义
数据库·oracle