数据库模式
结构定义
对于 C 语言项目,数据库结构是在 SmartEDB 数据定义语言(DDL)中指定的,该语言用于识别数据库、定义每个数据类、其元素、与其他数据类的关系以及数据访问方法。DDL 的语法、关键字和预处理器的设计类似于 C 语言的元素,以简化学习和理解。
无论打算从 C、C++、Java、Python 或 C# API 访问,还是从嵌入式 SQL 语句访问,数据库结构都是使用 SmartEDB 数据定义语言在文本文件(通常扩展名是.mco
)中定义的。
然后运行 DDL 编译器 mcocomp
以生成两个头文件(<数据库名称>.h
和 <数据库名称>.c
),这些文件将被包含在 C 或 C++应用程序的源代码和项目中。这些生成的文件构成了应用程序内用于管理数据库对象的特定于应用程序的生成 API。
例如,以下文件 schema.mco
将定义一个简单的数据库 c_apidb,其中包含一个单一的类 Person:
declare database c_apidb;
class Person
{
string name;
string address;
string position;
unsigned<4> salary;
float rating;
autoid_t<Person> manager;
autoid[1000];
tree<name> pk;
};
在此可以看到,SmartEDB DDL 使用类 C 的语法来定义数据库类中字段的类型和名称。请查看 DDL 页面以获取 DDL 语法的完整定义。
编译结构
结构文件由 SmartEDB 安装目录中 SmartEDB/host/bin 目录下的 mcocomp 实用程序进行编译。
例如,当从包含 schema.mco
的目录运行以下命令时,将编译上述定义的示例结构:
SmartEDB/host/bin/mcocomp schema.mco
如果结构定义在语法上是正确的,mcocomp 将输出如下内容:
SmartEDB Data Definition Language Processor version 7.0 (Build 1792)
Copyright (c) 2024 SmartEDB. All Rights Reserved.
Compiled successfully: Mon Jan 23 15:40:42 2017
生成的.h 和.c 文件也必须包含在 SmartEDB SQL应用程序中——即使对 SmartEDB 数据库的所有访问都仅通过 SQL 进行。
以下示例 DDL 规范说明了许多数据类型和声明。(请在此处查看 DDL语法的详细描述,并在 SDK 示例中的 schema.mco
文件中查看其他示例。)
#define int1 signed<1>
#define int2 signed<2>
#define int4 signed<4>
#define uint4 unsigned<4>
#define uint2 unsigned<2>
#define uint1 unsigned<1>
struct SampleStruct
{
uint2 s1;
char<20> s2;
};
struct BigStruct
{
string str;
uint2 u2;
uint4 u4;
vector <SampleStruct> vss;
};
declare database simple;
/* 声明一个对象标识符(OID)——方括号内为预计的类实例数量 */
declare OID SampleStruct[20000];
/*
* “compact”关键字:包括开销在内的总对象大小小于64K。
* 不计算类中嵌入的blob(s)字段的大小
*/
compact class SampleClass {
uint1 a = 0;
uint2 b;
uint4 c;
ref d;
/* 可以由任何类型构成 */
vector <uint2> numbers;
vector <SampleStruct> ss;
/* 字符串长度限制为 64K */
string str;
/* blobs 数量不限 */
blob blo;
/* 可选结构,该值可能缺失 */
optional BigStruct big_struct;
/* voluntary 可以在运行时启动和删除
* unique 独一无二的
* tree 基于树的索引(支持排序顺序)
* hash 基于哈希的索引
*/
voluntary unique tree< a,b,ss.s2> SAM;
/* 对于哈希索引,估计的类实例数量用方括号括起来。 */
hash <a> AAAA[10000];
hash <ss.s2> SSS2[10000];
hash <numbers> NNNN[10000];
/* 可以为 NEW 和 DELETE 操作以及类对象或任何字段的 UPDATE 定义事件。*/
event <new> new;
event <delete> delete;
event <a update> update;
/* 为这个类声明一个autoid和oid(内部管理的散列索引) */
autoid;
oid;
/* 意味着这些对象可以按顺序进行扫描*/
list;
};
数据库字典
在本例中,
- 生成的头文件
c_apidb.h
包含了结构中定义的每个类、字段和索引的结构体、类型定义和函数原型定义。 - 源代码文件
c_apidb.c
包含了头文件中定义的函数的实现。这些函数大多数会调用带有前缀mco_w
的底层函数。但get_dictionary()
的名称由数据库名称后跟后缀_get_dictionary(void)
组成。编译时,此函数包含了结构的二进制形式,当使用参数_get_dictionary()
调用数据库打开函数mco_db_open_dev()
时,运行时会加载该结构。此二进制字典在内部被运行时用于所有数据库访问。
持久数据库
对于持久数据库应用程序,结构在 SmartEDB 数据定义语言(DDL)中的指定方式与内存数据库完全相同,只是对于将存储在持久介质上的所有类都声明为持久的。例如:
persistent class Record
{
unsigned<4> key;
unsigned<4> value;
unique tree<key> tkey;
};
如果结构中的所有类都是持久的,另一种选择是在使用 mcocomp
编译结构时使用 -persistent
选项。例如:
mcocomp -persistent schema.mco