Copyright © Cryville 2022-2023.
本文档使用软件 Prince(Copyright © 2002 - 2022 YesLogic Pty. Ltd.)在非商业授权下生成,仅限非商业用途。“非商业用途”指文档的制作不收取任何的费用、不属于货币交易系统的一部分(包括但不限于发票和收据)且没有生成其它收入(包括但不限于订阅费用、广告和销售收入)。
本文档使用 jQuery(Copyright © OpenJS Foundation and other contributors | jquery.org/license)生成部分模板化内容。
本文档对 Cryville 元数据库框架(CMDF)第二版做出定义。
本文档目前为草稿状态,文内所有描述的稳定性没有保证。
草稿存档时间:
现如今的主流数据库大多使用表格的结构储存数据。通常,这样的一个表格里,一列相当于应用层面下某个数据结构的一个字段定义,一行相当于一个实例,一个单元格相当于实例上某个字段的值。一个表格中,每一列表示的属性及其数据类型是由开发者预定义的。一般情况下,用户的操作只会影响表格中行(记录)的增删及行内某列数据的更新,而不会影响到列本身的定义。这种结构符合直觉,毕竟表格中每一列的定义需要与程序中的数据结构的每个字段相对应,而只有开发者能够定义这些数据结构。这样的结构也使数据库能够拥有较高的性能。
在本团队(Cryville)开发的另一个项目中,我们遇到了数据结构会频繁变化,有时甚至可以由用户的操作修改的情况,即用户的操作可以在数据结构中更新、插入或删除字段。在主流数据库中,这样的操作一般由开发者完成,并且有两种方式:第一种是更新原有的表,直接新建一列,这种方式开销非常大,且十分耗时;第二种是新建一个主键与原表相同的表,这种方式会使一个数据结构对应多个表,会降低数据库的可维护性。
基于以上的背景,我们决定探索一种新的更加灵活的数据库结构。
为了让用户的操作能够修改数据结构,我们在数据库层面假定一个新的概念,将应用层面中数据结构的字段本身和字段的值统一到这个概念中。由于实例的增删也是依据用户的操作完成的,我们也将实例本身统一到这个概念中。现在,字段、实例和实例中字段的值三者在数据库层面中处于同一地位。我们把这个概念称为“元子”。
元子之间需要有一种表示其相互关系的方式。参考字段、实例和实例中字段的值这三者,我们用一个三元组表示一个形如“A 的 B 是 C”的关系。对于形如“A 是 B”这样看似由两个元子就能构成的关系,我们引入一个特殊的、语义为“存在”的元子,将这类型的关系表示为“A 的存在是 B”。
关于字段的数据类型,上层系统(即数据库实现或应用层系统)自行决定是否对数据进行类型处理。
下文的“CMDF”指代本文档所描述的数据库框架。
在本文档中,对于“必须”“不得”“应当”“不应”“可以”这些关键词,当且仅当以粗体出现时,需要按照 BCP 14 [RFC2119] [RFC8174] 中的描述解读。
元子(meton)是数据库中的一个抽象数据对象。
meton 的词源为 met-(“元”;“自身的”)+ -on(“子”;表示单位物体或概念的后缀)。
三个元子 、 和 间可以组成一个称为正关系(forward relation)的三元组,记作 ,语义为“ 的 是 ”。此时元子 和元子 构成一个正元子对(forward meton pair),记作 。
每个正关系 必须有且仅有一个称为逆关系(backward relation)的三元组,记为 ,语义为“ 是 的 ”。元子 和元子 构成一个逆元子对(backward meton pair),记作 。
正关系和逆关系统称为关系(relation)。正元子对和逆元子对统称为元子对(meton pair)。元子对中第一个元子称为键元(key meton),第二个元子称为值元(value meton),键元和值元均不得为空。
每个元子上都附属一个由若干个元子对组成的集合,称为元子对集(meton pair set),用于记录由该元子引申向其它元子的关系。对于一个正关系 ,其正元子对 记录在元子 的元子对集上。对于一个逆关系 ,其逆元子对 记录在元子 的元子对集上。一个元子的元子对集中不得含有两个键元和值元均相同的正元子对,也不得含有两个键元和值元均相同的逆元子对。或者说,一个数据库中不得含有相同的正关系或相同的逆关系。
在下面的示例中,一对大括号 {} 及其里面的内容表示一个元子,大括号前加注该元子的标识符方便辨识(实际的数据结构中没有这样的标识符)。
Student {
}
大括号中,键元: 值元; 表示当前元子有一个由键元和值元组成的正元子对。~键元: 值元; 表示当前元子有一个由键元和值元组成的逆元子对。
Name {
}
Student_Lime {
Name: Name_Lime;
}
Name_Lime {
~Name: Student_Lime;
}
除非特别声明,之后的示例将沿用这种标记。
一个数据库中,必须存在且仅存在一个元子 ,使得正关系 存在。称这个元子 为系词元子(copula meton),其语义为“存在”。
由于每个正关系有且只有一个逆关系,所以一个数据库中,存在且仅存在系词元子 ,使得逆关系 存在。
在示例中,用下划线 _ 表示系词元子。
_ {
_: _;
~_: _;
}
除非特别声明,之后的示例将沿用这种标记。
关于系词元子的语义,可参考这个示例。
_ {
_: _;
~_: _;
~_: Student;
~_: Name;
}
Student {
_: _;
~_: Student_Lime;
}
Student_Lime {
_: Student;
Name: Name_Lime;
}
Name {
_: _;
~_: Name_Lime;
}
Name_Lime {
_: Name;
~Name: Student_Lime;
}
每个元子有一个固定长度的元子标识(meton identifier),用于索引元子。
元子中可以容纳一段可变长度的、代表实际数据的二进制数据,称为摘要(summary)。
摘要中可以直接放入实际数据。如果元子只是作为抽象对象存在而不含任何实际数据,或者仅用元子标识就可以将其与其它元子区分,那么也可以将摘要留空。
元子的摘要用一对双引号 "摘要"; 括注,括注的内容仅作为实际摘要内容的提示,方便辨识元子,不一定是摘要中实际储存的数据。
Name_Lime {
"Lime";
~Name: Student_Lime;
}
除非特别声明,之后的示例将沿用这种标记。
一个 CMDF 实现必须支持读取数据库,但是可以选择是否支持写入数据库。对于这两种实现,本文档指定不同的业务需求。
一个 CMDF 实现必须实现以下业务:
一个支持写入的 CMDF 实现必须实现以下业务:
一个 CMDF 实现可以实现以下业务:
下文中所有对数据库的操作,都是通过数据库连接进行的。
令 为当前数据库中元子的总数。
一个 CMDF 实现必须实现以下业务:
一个支持写入的 CMDF 实现必须实现以下业务:
一个 CMDF 实现应当实现以下业务:
令 为元子的元子对集中元子对的总数。
一个 CMDF 实现必须实现以下业务:
一个支持写入的 CMDF 实现必须实现以下业务:
一个 CMDF 实现应当实现以下业务:
一个 CMDF 实现必须实现以下业务:
一个 CMDF 实现应当实现以下业务: