12、数据库应用的自动迁移与包装:原理、方法与工具实践

数据库应用的自动迁移与包装:原理、方法与工具实践

1. 模式转换的可逆性

在模式转换中,当前列出的转换与以往有所不同,主要体现在两个方面:
- 删除节点和边时需指定恢复查询 delNode delEdge 转换现在要求为删除的节点或边指定恢复查询。
- 添加、删除和重命名的条件 :添加和删除转换仅在要添加(删除)的构造在模式中不存在(存在)时才成功,同样,构造的重命名必须使用新名称。

这些改变使得可以自动推导出原始模型的反向转换。对于每个原始转换 t ,若 t(⟨S, I, ExtS,I⟩) ≠ φ ,则存在反向原始转换 t⁻¹ ,使得 t⁻¹(t(⟨S, I, ExtS,I⟩)) = ⟨S, I, ExtS,I⟩ 。以下是各原始转换及其反向转换的列表:
| 转换 (t) | 反向转换 (t⁻¹) |
| — | — |
| renameNode ⟨from, to⟩c | renameNode ⟨to, from⟩ |
| renameEdge ⟨⟨from, schemes⟩, to⟩c | renameEdge ⟨⟨to, schemes⟩, from⟩ |
| addConstraint q c | delConstraint q |
| delConstraint q c | addConstraint q |
| addNode ⟨n, q⟩c | delNode ⟨n, q⟩ |
| delNode ⟨n, q⟩c | addNode ⟨n, q⟩ |
| addEdge ⟨e, q⟩c | delEdge ⟨e, q⟩ |
| delEdge ⟨e, q⟩c | addEdge ⟨e, q⟩ |

对于复合转换,其反向复合转换是各原始转换反向转换的逆序组合。例如,在示例 1 中, T⁻¹S2,S1 = TS1,S2 ,而 T⁻¹S1,S2 TS2,S1 ,但倒数第二步中没有 dept = {maths, compsci} 这个条件。

2. 非等价模式之间的转换

即使两个数据库设计用于存储相同信息,它们也可能存在细微差异,并非完全等价。为此,定义了四个低级转换来处理这种情况:
- 扩展节点 ( extendNode n ) extendNode n = addNode ⟨n, void⟩
- 扩展边 ( extendEdge e ) extendEdge e = addEdge ⟨e, void⟩
- 收缩节点 ( contractNode n ) contractNode n = delNode ⟨n, void⟩
- 收缩边 ( contractEdge e ) contractEdge e = delEdge ⟨e, void⟩

如果复合转换 t 使得 S2 = t(S1) 包含 contractNode n contractEdge e 形式的转换,则可以认为 S1 相对于 n e 扩展了 S2 ;反之,如果包含 extendNode n extendEdge e 形式的转换,则 S2 相对于 n e 扩展了 S1 。对于这样的模式对,可能存在一些查询只能通过对两个模式进行连接操作来回答。

当对一组源模式应用预集成转换,消除它们之间的所有冲突(结构和基于约束的),并通过合并其节点、边和约束组件来集成这些模式时,得到的联合模式 Sf 具有以下属性:
- 最小性 :不存在 Sf 相对于所有源模式扩展的节点或边。
- 完整性 :不存在源模式相对于 Sf 扩展的节点或边。但在实际构建部分联合模式用于特定应用时,完整性属性通常不被实现。

3. 数据库的迁移与包装

当模式 S1 转换为等价的模式 S2 时,有两种情况:
- 数据库迁移 :将现有数据库应用从 S1 迁移到 S2 ,旧模式和扩展将过时,新模式和新扩展成为操作数据库。可以利用从 S1 S2 的转换自动完成以下操作:
- 数据迁移 :将与 S1 关联的数据库扩展迁移到与 S2 关联的新数据库扩展。
- 查询迁移 :将在 S1 上提出的查询迁移到在 S2 上提出的查询。
- 更新迁移 :将在 S1 上提出的更新迁移到在 S2 上提出的更新。
- 数据库包装 :用新的等价模式“包装”现有数据库,旧模式和扩展继续运行,但客户端可以通过新模式与之交互。可以利用从 S1 S2 的转换自动完成以下操作:
- 查询翻译 :将在 S2 上提出的查询翻译为在 S1 上提出的查询。
- 更新翻译 :将在 S2 上提出的更新翻译为在 S1 上提出的更新。

3.1 数据迁移

当模式 S1 转换为等价的模式 S2 并希望自动迁移 S1 的当前扩展到 S2 时,若 S1 S2 的转换是单个原始转换,只需考虑添加新节点或边的情况:
- 添加节点 ( addNode ⟨n, q⟩) :通过对 S1 的扩展评估查询 q 来填充新节点 n
- 添加边 ( addEdge ⟨e, q⟩) :同样通过对 S1 的扩展评估查询 q 来填充新边 e

对于复合转换,每次应用 addNode addEdge 转换时都会生成新的扩展。例如,若 S1 通过示例 1 中的 TS1,S2 转换为 S2 ,则可以使用 TS1,S2 的第一步和第二步中指定的查询自动推导 ExtS2,I

ExtS2,I(dept) = {maths, compsci}
ExtS2,I(⟨Null, person, dept⟩) = {⟨x, maths⟩| x ∈ExtS1,I(mathematician)} ∪
{⟨x, compsci⟩| x ∈ExtS1,I(compScientist)}
3.2 查询和更新迁移

假设模式 S1 转换为等价的模式 S2 S1 的扩展已迁移到 S2 ,可以自动将在 S1 上提出的查询迁移到在 S2 上提出的查询。若 S1 S2 的转换是单个原始转换,迁移查询 q1 到等价查询 q2 时,只需考虑应用重命名和用恢复查询替换删除的节点或边的出现:
- 重命名节点 ( renameNode ⟨from, to⟩) q2 = [from/to]q1
- 重命名边 ( renameEdge ⟨⟨from, schemes⟩, to⟩) q2 = [⟨from, schems⟩/⟨to, schemes⟩]q1
- 删除节点 ( delNode ⟨n, q⟩) q2 = [n/q]q1
- 删除边 ( delEdge ⟨e, q⟩) q2 = [e/q]q1

对于复合转换,依次应用上述替换以获得最终迁移的查询 q2 。对于在 S1 上提出的更新 u1 ,其形式为 insert q n insert q e delete q n delete q e ,可以使用与查询迁移相同的替换来获得在 S2 上提出的等价更新 u2 。但只有当 S1 S2 的可更新视图时, u2 才是明确的,否则需要解决与视图更新相关的常见问题。

例如,在 S1 上的查询 compScientist ∪ mathematician 返回在计算机科学或数学部门工作的人员,通过 TS1,S2 转换后的等价查询为:

{x | ⟨x, compsci⟩∈⟨Null, person, dept⟩} ∪ {x | ⟨x, maths⟩∈⟨Null, person, dept⟩}

S1 上的更新 insert Bob mathematician 转换为在 S2 上的更新为:

insert Bob {x | ⟨x, maths⟩∈⟨Null, person, dept⟩}

这个更新明确表示应将元组 ⟨Bob, maths⟩ 添加到 ⟨Null, person, dept⟩ 的扩展中。

3.3 查询和更新翻译

若模式 S1 转换为等价的模式 S2 ,但 S1 的扩展未迁移到 S2 ,则可以自动将在 S2 上提出的查询和更新翻译为在 S1 上提出的查询和更新。首先,自动推导从 S2 S1 的反向转换,然后使用与查询迁移相同的方法,但参考反向转换。若 S2 S1 的可更新视图,则翻译后的更新是明确的。

4. 原型 ER 模式转换工具

考虑一个支持二元关系和泛化层次结构的简单 ER 建模语言,其原始转换包括:
- 重命名 renameE (重命名实体类)、 renameA (重命名属性)、 renameR (重命名关系)。
- 添加 addE (添加实体类)、 addA (添加属性)、 addR (添加关系)、 addG (添加泛化层次结构)。
- 删除 delE/A/R/G (删除相应构造)。

这些转换的定义可以参考相关文献。实例、模型、模式等价和 s - d/i - d 转换的概念自然地扩展到 ER 模式。如果 ER 模式 S 可以通过 s - d 转换转换为 S′ ,反之亦然,则 S S′ 是 u - 等价的;如果可以通过带有条件 f 的 i - d 转换实现双向转换,则 S S′ 相对于 f 是 c - 等价的。

在这个更高语义级别上,迁移和包装的处理方式与低级框架相同。对于数据迁移,通过 addE addA addR 转换创建的新构造通过评估提供的查询来填充;对于查询和更新迁移,应用重命名并替换删除的实体、属性或关系的出现;对于查询和更新翻译,使用相同的技术但参考反向转换。

4.1 原型 ER 模式集成工具

实现了一个原型 ER 模式集成工具,提供了以下一组原始 ER 模式转换:

addEntity(Ss,Sn,Scheme,CSs,CSn,Query)
delEntity(Sn,Ss,Scheme,CSn,CSs,Query)
addRelationship(Ss,Sn,Scheme,Card,CSs,CSn,Query)
delRelationship(Sn,Ss,Scheme,Card,CSn,CSs,Query)
addAttribute(Ss,Sn,Scheme,Card,CSs,CSn,Query)
delAttribute(Sn,Ss,Scheme,Card,CSn,CSs,Query)
addGeneralisation(Ss,Sn,Scheme,CSn)
delGeneralisation(Sn,Ss,CSn,Scheme)

这些转换的参数含义如下:
- Scheme :标识主题构造,有以下几种形式:
- [ent,Name,E] :表示名为 Name 的实体类型。
- [att,EName,AName,E,A] :表示实体类型 EName 的属性 AName
- [rel,E1Name,RName,E2Name,E1,E2] :表示实体 E1Name E2Name 之间的关系 RName
- [gen,GenType,Super,SubList] :表示超实体类型 Super 和子实体类型列表 SubList 之间的泛化。
- 当方案中出现匿名自由变量时,可以缩写方案,传递方案时可以省略其第一个组件。
- Ss 和 Sn Ss 是转换的主题模式, Sn 是非主题模式。对于添加转换, Sn 是输入模式, Ss 是输出模式;对于删除转换,反之亦然。
- Card :是一对基数约束 [C1,C2] C1 C2 可以是 [1,1] [1,n] 等。
- CSn 和 CSs :分别是对 Sn Ss 施加的约束,必须满足这些约束转换才能成功。该工具允许用户在输入和输出模式上都提供约束,使模式之间的转换具有双向性。
- Query :是对非主题模式的查询表达式,定义主题构造的扩展。其语法为:

Query ::= Scheme | Predicate | [or,Query,Query] |
[and,Query,Query] | [implies,Query,Query] | [not,Query]
Predicate ::= [eq,Atom,Atom] | [less,Atom,Atom]
4.2 等价模式之间的转换

当两个模式之间的一系列转换不涉及收缩或扩展转换时,这些转换建立了模式之间的等价关系。以下是将模式 s1 转换为 s2 的示例:
1. 添加男性实体类型

addEntity(s1a,s1,[male,EV],[],[],[att,person,sex,EV,m])

在正向转换中,性别属性不为 m 的人不会被分类为男性;在反向转换中,男性实体的实例会使对应人的性别属性值为 m
2. 添加女性实体类型

addEntity(s1b,s1a,[female,EV],[],[],[att,person,sex,EV,f])
  1. 添加泛化关系
addGeneralisation(s1c,s1b,[total,person,[male,female]],
[implies,[att,person,sex, ,AV],[or,[eq,AV,m],[eq,AV,f]]])
  1. 删除冗余的性别属性
delAttribute(s4,s1c,[person,sex,EV,AV],[[1,1],[1,n]],[],[],
[or,[and,[ent,male,EV],[eq,AV,m]],
[and,[ent,female,EV],[eq,AV,f]]])

此时, s1 已转换为中间模式 s4 。这四个步骤实现了属性和泛化层次结构之间的著名等价关系。
5. 添加 dname 属性到 person

addAttribute(s2c,s4,[person,dname,X,Y],[[1,1],[1,n]],[],[],
[rel,person,worksin,dept,X,Y])
  1. 删除冗余的 worksin 关系
delRelationship(s2b,s2c,[person,worksin,dept,X,Y],
[[1,1],[1,n]],[],[],[att,person,dname,X,Y])
  1. 删除 dept 上的冗余 dname 属性
delAttribute(s2a,s2b,[dept,dname,X,Y],[[1,1],[1,n]],
[implies,[att,dept,dname,X,Y],[eq,X,Y]],[],
[att,person,dname,X,Y])
  1. 删除 dept :通过一系列操作,最终完成了从 s1 s2 的转换。

通过以上步骤和工具,我们可以实现数据库模式的转换、迁移和包装,提高数据库应用的灵活性和适应性。

graph LR
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;

    A(s1):::process -->|addEntity| B(s1a):::process
    B -->|addEntity| C(s1b):::process
    C -->|addGeneralisation| D(s1c):::process
    D -->|delAttribute| E(s4):::process
    E -->|addAttribute| F(s2c):::process
    F -->|delRelationship| G(s2b):::process
    G -->|delAttribute| H(s2a):::process
    H -->|delEntity| I(s2):::process

这个流程图展示了从模式 s1 s2 的转换过程,有助于直观理解整个转换步骤的顺序和逻辑。

5. 模式转换的实际应用案例分析

为了更深入地理解上述模式转换、迁移和包装的概念,我们通过一个实际的案例来进一步说明。假设我们有一个学校管理系统,最初的数据库模式 S1 主要用于记录学生的基本信息、课程信息以及学生与课程的选课关系。随着学校业务的发展,需要对系统进行升级,新的数据库模式 S2 增加了学生成绩管理和教师信息管理的功能。

5.1 数据迁移过程

在这个案例中,我们首先要将 S1 的数据迁移到 S2 。由于 S2 是在 S1 的基础上进行扩展的,我们可以利用之前提到的数据迁移方法。
- 添加新实体 :在 S2 中添加了 teacher 实体和 grade 实体。对于 teacher 实体,我们可以通过一个查询从学校的人事系统中获取教师的基本信息来填充。假设查询为 q_teacher ,则使用 addEntity(S2, S1, [teacher, T], [], [], q_teacher) 来添加 teacher 实体。对于 grade 实体,我们需要根据学生的选课信息和考试成绩来填充,查询为 q_grade ,使用 addEntity(S2, S1, [grade, G], [], [], q_grade)
- 更新扩展 :在添加新实体后,我们需要更新 S2 的扩展。例如,对于 student 实体和 course 实体,虽然它们在 S1 S2 中都存在,但可能需要根据新的业务规则进行一些调整。比如,在 S2 中,学生的选课信息可能需要关联到具体的教师,我们可以通过对 S1 中的选课信息和新添加的 teacher 实体进行关联查询来更新 S2 中的选课信息。

5.2 查询和更新迁移

在数据迁移完成后,我们需要将在 S1 上的查询和更新迁移到 S2
- 查询迁移 :假设在 S1 中有一个查询 q1 用于查询所有选修了某门课程的学生,其形式为 [student, S] WHERE [rel, student, selects, course, S, C] AND [course, C, course_name, 'Math'] 。在 S2 中,由于选课信息关联到了教师,我们需要对查询进行迁移。根据之前提到的查询迁移方法,我们需要考虑重命名和替换删除的节点或边的情况。在这个例子中,可能没有删除的节点或边,但可能需要对查询进行一些扩展,以关联到新的 teacher 实体。迁移后的查询 q2 可能为 [student, S] WHERE [rel, student, selects, course, S, C] AND [course, C, course_name, 'Math'] AND [rel, course, taught_by, teacher, C, T]
- 更新迁移 :假设在 S1 中有一个更新 u1 用于添加一个新的学生选课记录,其形式为 insert [student, 'John'] [rel, student, selects, course, 'John', 'Math'] 。在 S2 中,由于选课信息关联到了教师,我们需要对更新进行迁移。迁移后的更新 u2 可能为 insert [student, 'John'] [rel, student, selects, course, 'John', 'Math'] AND [rel, course, taught_by, teacher, 'Math', 'Mr. Smith']

5.3 查询和更新翻译

如果在某些情况下,我们仍然需要在旧模式 S1 上进行查询和更新,但客户端使用的是新模式 S2 ,则需要进行查询和更新翻译。
- 查询翻译 :假设在 S2 上有一个查询 q3 用于查询某个教师所教授的所有学生,其形式为 [student, S] WHERE [rel, student, selects, course, S, C] AND [rel, course, taught_by, teacher, C, 'Mr. Smith'] 。我们需要将这个查询翻译到 S1 上。首先,我们推导出从 S2 S1 的反向转换,然后根据反向转换进行查询翻译。由于 S1 中没有 teacher 实体和 taught_by 关系,我们需要将这些信息进行适当的处理。翻译后的查询 q4 可能需要根据 S1 中的选课信息和课程信息进行一些聚合和筛选操作,以模拟 S2 中的查询结果。
- 更新翻译 :假设在 S2 上有一个更新 u3 用于更新某个教师所教授课程的学生成绩,其形式为 update [grade, G] SET [grade, G, score, 90] WHERE [rel, student, selects, course, S, C] AND [rel, course, taught_by, teacher, C, 'Mr. Smith'] AND [rel, student, has_grade, grade, S, G] 。我们需要将这个更新翻译到 S1 上。同样,根据反向转换,我们需要将 S2 中的 teacher 实体和 taught_by 关系等信息进行处理,以适应 S1 的模式。

6. 模式转换工具的优势与挑战
6.1 优势
  • 提高开发效率 :通过自动推导反向转换和进行数据迁移、查询和更新的迁移与翻译,大大减少了开发人员手动编写代码的工作量。例如,在上述学校管理系统的升级案例中,如果没有模式转换工具,开发人员需要手动编写大量的 SQL 语句来完成数据迁移和查询更新的转换,而使用工具可以自动完成这些任务,提高了开发效率。
  • 保证数据一致性 :在模式转换过程中,工具可以根据预先定义的规则和约束来进行操作,确保数据在迁移和转换过程中的一致性。例如,在添加新实体和关系时,工具可以根据提供的查询和约束条件来正确地填充数据,避免了手动操作可能带来的数据不一致问题。
  • 增强系统的灵活性 :模式转换工具使得数据库系统可以更容易地适应业务的变化。当业务需求发生变化时,我们可以通过修改模式转换规则来实现数据库模式的升级和调整,而不需要对整个系统进行大规模的重构。
6.2 挑战
  • 规则定义的复杂性 :在使用模式转换工具时,需要准确地定义各种转换规则,包括添加、删除、重命名等操作的条件和查询。对于复杂的数据库模式和业务规则,规则的定义可能会非常复杂,需要开发人员具备较高的专业知识和经验。
  • 性能问题 :在进行数据迁移和查询更新的迁移与翻译时,可能会涉及到大量的数据处理和查询操作,这可能会导致性能问题。例如,在大规模的数据迁移过程中,可能会占用大量的系统资源,影响系统的正常运行。
  • 兼容性问题 :不同的数据库系统可能具有不同的语法和特性,模式转换工具需要考虑这些兼容性问题。例如,在将一个基于 MySQL 的数据库模式转换到 PostgreSQL 时,需要对查询和更新语句进行适当的调整,以确保在新的数据库系统中能够正常运行。
7. 总结与展望

通过对数据库应用的自动迁移与包装的研究,我们了解了模式转换的可逆性、非等价模式之间的转换方法、数据库的迁移与包装技术以及原型 ER 模式转换工具的使用。这些技术和方法为数据库系统的升级和维护提供了有效的手段,提高了系统的灵活性和适应性。

在未来,我们可以进一步研究和改进这些技术,以应对更复杂的数据库应用场景。例如,开发更加智能的模式转换工具,能够自动识别数据库模式的变化并生成相应的转换规则;研究如何在分布式数据库环境下进行高效的模式转换和数据迁移;探索如何将模式转换技术与人工智能和机器学习相结合,实现数据库系统的自动优化和调整。

graph LR
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;

    A(当前数据库模式):::process -->|业务需求变化| B(新的数据库模式需求):::process
    B -->|模式转换工具| C(模式转换):::process
    C -->|数据迁移| D(新数据库系统):::process
    D -->|查询和更新迁移/翻译| E(系统正常运行):::process
    E -->|持续监控和优化| F(系统稳定性和性能提升):::process

这个流程图展示了从当前数据库模式到新数据库系统的整个升级过程,包括业务需求变化、模式转换、数据迁移、查询和更新迁移/翻译以及系统的持续监控和优化,体现了数据库应用自动迁移与包装技术在实际应用中的完整流程。

通过不断地研究和实践,我们相信数据库应用的自动迁移与包装技术将在未来的数据库管理和开发中发挥更加重要的作用,为企业和组织提供更加高效、稳定和灵活的数据库解决方案。

先展示下效果 https://pan.quark.cn/s/e81b877737c1 Node.js 是一种基于 Chrome V8 引擎的 JavaScript 执行环境,它使开发者能够在服务器端执行 JavaScript 编程,显著促进了全栈开发的应用普及。 在 Node.js 的开发流程中,`node_modules` 文件夹用于存储所有依赖的模块,随着项目的进展,该文件夹可能会变得异常庞大,其中包含了众多可能已不再需要的文件和文件夹,这不仅会消耗大量的硬盘空间,还可能减慢项目的加载时间。 `ModClean 2.0` 正是为了应对这一挑战而设计的工具。 `ModClean` 是一款用于清理 `node_modules` 的软件,其核心功能是移除那些不再被使用的文件和文件夹,从而确保项目的整洁性和运行效率。 `ModClean 2.0` 是此工具的改进版本,在原有功能上增加了更多特性,从而提高了清理工作的效率和精确度。 在 `ModClean 2.0` 中,用户可以设置清理规则,例如排除特定的模块或文件类型,以防止误删重要文件。 该工具通常会保留项目所依赖的核心模块,但会移除测试、文档、示例代码等非运行时必需的部分。 通过这种方式,`ModClean` 能够协助开发者优化项目结构,减少不必要的依赖,加快项目的构建速度。 使用 `ModClean` 的步骤大致如下:1. 需要先安装 `ModClean`,在项目的根目录中执行以下命令: ``` npm install modclean -g ```2. 创建配置文件 `.modcleanrc.json` 或 `.modcleanrc.js`,设定希望清理的规则。 比如,可能需要忽略 `LICENSE` 文件或整个 `docs`...
2026最新微信在线AI客服系统源码 微信客服AI系统是一款基于PHP开发的智能客服解决方案,完美集成企业微信客服,为企业提供7×24小时智能客服服务。系统支持文本对话、图片分析、视频分析等多种交互方式,并具备完善的对话管理、人工转接、咨询提醒等高级功能。 核心功能 ### 1.  智能AI客服 #### 自动回复 - **上下文理解**:系统自动保存用户对话历史,AI能够理解上下文,提供连贯的对话体验 - **个性化配置**:可自定义系统提示词、最大输出长度等AI参数 #### 产品知识库集成 - **公司信息**:支持配置公司简介、官网、竞争对手等信息 - **产品列表**:可添加多个产品,包括产品名称、配置、价格、适用人群、特点等 - **常见问题FAQ**:预设常见问题及答案,AI优先使用知识库内容回答 - **促销活动**:支持配置当前优惠活动,AI会自动向用户推荐 ### 2. 多媒体支持 #### 图片分析 - 支持用户发送图片,AI自动分析图片内容 - 可结合文字描述,提供更精准的分析结果 - 支持常见图片格式:JPG、PNG、GIF、WebP等 #### 视频分析 - 支持用户发送视频,AI自动分析视频内容 - 视频文件自动保存到服务器,提供公网访问 - 支持常见视频格式:MP4、等 ### 3.  人工客服转接 #### 关键词触发 - **自定义关键词**:可配置多个转人工触发关键词(如:人工、客服、转人工等) - **自动转接**:用户消息包含关键词时,自动转接给指定人工客服 - **友好提示**:转接前向用户发送提示消息,提升用户体验 #### 一键介入功能 - **后台管理**:管理员可在对话管理页面查看所有对话记录 - **快速转接**:点击"一键介入"按钮,立即将用户转接给人工客服
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值