主键 primarykey
primarykey属性指明此元素对应数据库表的主键,其取值为以当前元素为父元素的特定子元数据成员名串,如果有多个成员组成表的主键,则成员名之间用逗号(‘,’)隔开。
约束:
作为主键的成员不能为复合数据类型,只能是基本内置数据类型。作为主键的成员其取值不能为NULL。
<struct name="GameItem" primarykey="gameid,itemid"><entry name="gameid" type="uint" /><entry name="itemid" type="uint" /><entry name="buytime" type="datetime" /><entry name="validtime" type="datetime" /></struct>
根据上面的描述,GameItem的数据表使用gameid和itemid两个成员作为主键。
分表属性(分表因子) splittablekey
splittablekey属性指明计算当前结构与具体数据表映射关系的数据源,其取值为以当前元素为父元素的特定子元数据成员。
约束:
作为此成员不能为复合数据类型,只能是基本内置数据类型(void类型除外)。
<struct name="GameItem" primarykey="gameid,itemid" splittablekey="gameid"><entry name="gameid" type="uint" /><entry name="itemid" type="uint" /><entry name="buytime" type="datetime" /><entry name="validtime" type="datetime" /></struct>
本地索引 index
基于TcaplusDB主键字段建立的索引,在建表时随表一起建立,并且一旦表创建后,就不能再增加、修改和删除本地索引了,删除表的时候,本地索引会一并删除。
本地索引是实时索引,当插入或者删除数据时,会同时更新索引数据。本地索引的字段必须包含在主键字段中,并且字段中还必须包含分表因子,因此,查询时最终只会落到一个数据分片上进行查询。本地索引只支持等值查询。一个表可以建立多个本地索引,查询时必须包含某一个本地索引的全部字段。目前只有generic表支持本地索引。
<struct name="PLAYERONLINECNT" version="1" primarykey="TimeStamp,GameSvrID,GameAppID" splittablekey="TimeStamp"><entry name="TimeStamp" type="uint32"desc="单位为分钟" /><entry name="GameSvrID" type="string"size="64" /><entry name="GameAppID" type="string"size="64" desc="gameapp id" /><index name="index_1" column="TimeStamp"/><index name="index_2" column="TimeStamp, GameSvrID"/><index name="index_3" column="TimeStamp, GameAppID"/></struct>
如上文所示,index的name不可以重复,且必须按照index_i的规则依次递增,且不同的index必须拥有不同的column。
通用属性
这里的通用属性是指除了根元素外,所有的非根元素都可以具有的属性。对于那些不通用的属性,在描述相关的元素的时候统一进行描述。但是对于include元素,通用属性中只有name属性才有意义。
id
id属性表明了该元素的唯一标识,在DR提供的API中可以利用此id来查找、定位特定的元素。
id的取值可以是一个字面量的数字,也可以是一个Macro的名字(对于非Macro类型的元素)。
约束:
同一父元素下的所有子元素的id属性值不能重复。metalib元素的id属性只能是一个字面量的数字,不可以是Macro名字。struc/union元素的id属性值只能是0或者正整数。
name
name属性提供该元素的字符类型标识。在DR提供的API中可以利用此Name来查找、定位特定的元素。
约束:
同一父元素下的所有子元素的Name属性的值除后面描述的特例外是不可重复的。name属性的属性值区分大小写,即name="net"与name="NET"认为是不同的属性值。元数据描述的所有元素必须包含name属性。
cname
cname属性提供该元素的中文标识名。通过提供有意义的中文名,可以对元素的意义有更好的理解。(目前已知的应用领域是从Excel表中读取数据生成所需的内存结构)。
version
版本属性指明了该元素被引入时该元数据描述库的版本号。该版本号在打包、解包的时候提供裁减的依据。version的取值可以是一个字面量的数字,也可以是一个Macro的名字(对于非Macro类型的元素)。
约束:
metalib,struct,union元素必须包含version属性。对于struct和union元素,其version属性指明其基准版本号,即该版本号表明该元素加入到metalib时的库版本号。
Metalib,struct,union,entry元素的version属性的约束:metalib元素必须指定version属性,此属性指明该元数据描述库的当前版本,称为库版本。库版本号的变化反映了整个元数据描述库的变化情况,只要库发生了变化,库版本号就必须同步保持变化。库版本号永远只能增加,不能减少。每个struc和union元数据都必须包含version属性,此属性表明该Meta创建时的库版本号,称为元数据基准版本号(MetaBaseVersion)。每个元数据成员有自己的当前版本号,该版本号表明该MetaMember被添加时的库版本号,即该版本号表明了该元数据成员是在那个库版本中被引入的。当一个MetaMember没有定义其版本号时,缺省继承它所在的元数据的基准版本号。一个元数据(Meta)的当前版本号,此版本号为其成员中当前版本号的最大值。
desc
描述信息。对该元素的一些简要描述,表明该元素的用途、意义等等。
metalib元素
Metalib元素只能包含如下子元素:include, macro, macrosgroup, struct, union。
Metalib元素除可以包含以上描述的id,name,version属性外,还可以包含以下属性:tagsetversion。
name
只有name属性值相同的XML描述文件才能放在一起生成元数据描述库,除非其name属性为空串。Metalib的name属性类似于名字空间。
tagsetversion
此属性指明元数据描述使用的XML标签集的版本信息,通过此属性处理程序可以兼容使用不同版本元数据标签集定义的XML描述文件。
此属性的值为无符号整数,并且必须是递增的,每调整一次元数据描述XML标签集定义,必须使用新的版本号。
如果XML文件中,metaLib元素中没有包含此属性,则处理程序缺省按DR API支持的最新版本的标签定义进行解析。
约束:
本文档中元数据描述XML标签集tagsetversion值定义为1,即使用本文档中定义的标签生成的XML描述文件,其metaLib元素的tagsetversion属性值为1。
include元素
include元素必须是metalib元素的子元素。
include元素用于指示XML文件间的依赖关系。Include元素只需要定义file属性,但是建议定义name(通用)属性。定义全局唯一的name属性,有助于在tdr进行include元素规范性检测时,对不规范的地方提供详细的定位信息。在严格意义上,include不属于元数据库,include元素不影响元数据库的hash值,不受版本的约束,tdr不对include节点的name属性做唯一性检查。
当使用tdr的xml2h功能时,include元素被转换为头文件中的#include宏定义,file属性值对应的文件路径名中的xml后缀被直接替换为h。
例如,XML文件中的include元素
<include name="head" file="./head.xml">
对应头文件中的如下宏定义:
#include "./head.h"
当使用tdr的cplusplus功能时,include元素被转换为头文件中的#include宏定义,file属性值对应的文件路径名中的xml后缀被直接替换为h,并删除了路径中的目录信息。之所以删除路径中的目录信息,是因为对于cplusplus功能,tdr把所有的文件都生成在相同的目录中。
例如,XML文件中的include元素
<include name="head" file="../comm.xml">
对应头文件中的如下宏定义:
#include "comm.h"
对于XML文件中出现的多个include元素,tdr依次处理这些include元素。
file
file属性用于指明当前XML文件依赖的其他XML文件。如果XML文件中include元素的file属性值是当前XML文件路径本身或为””,则此include元素不起作用。
约束:
file属性的值(XML文件路径)指定的文件必须出现在(启动tdr工具时的)命令行指定的XML文件列表中。
macro元素
macro元素可以是metalib元素的子元素,也可以是macrosgoup元素的子元素。macro元素与C语言中的宏的意义类似,在实际的处理中也是映射到C语言的宏。Macro元素相对简单,只需要有name(通用)属性和value属性就可以了。
value
value属性用于指明该macro代表的值是多少(相比与C语言中宏的概念,name属性的值是宏的名字,value属性的值是宏的内容)。其取值可以是一个字面量的数字,也可以是一个之前已定义的Macro的名字。
约束:
目前value属性值是通过int数据类型来存储的,因此只能处理int数据类型值域范围里的数据。
macrosgroup元素
macrosgroup元素用于对macro元素进行分类,每一类macro元素组成一个宏定义组。Macrosgroup只需包含name和desc属性就可以了。
macrosgroup元素的子元素为macro元素,当然macro元素也可以不属于任何宏定义组。
约束:
macrosgroup元素必须指定name属性。macrosgroup的macro子元素的value属性值必须唯一,即value属性值相同的macro元素不能放入同一个macrosgroup元素下。
<macro name="MAX_BODY_LEN" value="32000" /><macrosgroup name=”MsgID” desc=”id of net message” ><macro name="CMD_LOGIN" value="0" /><macro name="CMD_LOGOUT" value="1" /></macrosgroup >
struct元素
struct元素必须是metalib元素的子元素,在tcaplus中一张表对应一个struct。
struct元素是DR中最复杂的元素,与C语言的struct概念类似。
size
size属性指明该struct的内存占用大小。如果不指明size属性,那么该struct的大小会通过计算成员的大小后自动得出该struct的大小。但是通过指定size属性,可以让该struct预占多一些空间,size属性指定的大小不能比自动计算出来的大小更小。
align
align属性对应于编译器的#pragma pack指令。利用align属性可以指定该struct内部所有成员的对齐大小。如果不指定align属性,缺省对齐大小为1。指定align属性会影响到该结构体的大小、每个成员的偏移。
customattr2
customattr2属性用于定义表格的属性,包括:
TableType:用于指定表格类型,如list或者sortlist,若不指定类型默认为generic表,且generic表无需添加customattr2属性,关于表格类型的说明请见 Generic表和List表。ListNum:用于定义list或者sortlist表中,单个key最多可以指向多少个value值,若超过该值可指定从头部或尾部删除老元素。SortFieldNum:用于sortlist表中,表示该表有多少个排序字段,每个排序字段需要用customattr2标识,如第一个为“sort1”,第二个“sort2”。SortRule:用于sortlist表中,表示该表的排序方式,如DESC表示降序,INSC升序。如果有多个排序字段,按照sort的序号进行排序,序号小的字段优先级更高。比如排序是降序:sort1不同时按sort1降序;sort1相同时按sort2降序,以此类推。
<struct name="table_Sortlist_single" primarykey="key, name" customattr2="TableType=SORTLIST;ListNum=1023;SortFieldNum=1;SortRule=DESC" version="5" desc="用于list表遍历测试, 需要4个shard, 建表list最大1023个元素" >...</struct>
entry子元素
entry对应的是元数据成员的概念,下面描述了entry元素可以包含的属性。
type属性
指明entry数据成员的数据类型;其取值为可以为基本内置数据类型,也可以为自定义的复合数据类型,在DR API中对type属性值不区分大小写。
约束:
自定义复合类型不支持后向引用。
<struct name="type1"></struct><struct name="type2"><entry name="item1" type="int" /><entry name="item2" type="float" /><entry name="item3" type="type1" /></struct>
size属性
size属性指明该元素的内存占用大小。如果不指明size属性,那么该元素的大小会通过计算成员的大小后自动得出该元素的大小。但是通过指定size属性,可以让该元素预占多一些空间,size属性指定的大小不能比自动计算出来的大小更小。
其取值为正整数或合法的宏定义。
约束:
对于自定义类型(union/struct)元素,entry本身设置的size属性将忽略,将以union/struct元素中定义的size属性为准。对于内置数据类型,目前只有string,wstring类型支持size属性,其他内置数据类型不支持size属性。
<struct name="type1" ><entry name="name" type="string" size="32" /><entry name="pass" type="string" size="32" /></struct>
count属性
count属性指明了当前元数据成员的个数(数组大小)。count可以是字面量的数字,也可以是一个Macro。
count属性如果不指定,缺省值为"1",取值范围为:>=1的整数,如果为0,表明该元数据成员的个数不确定,此时必须使用refer属性来指明可以用于确定数组大小的元数据成员。
约束:
count属性值为0的元素只能是一个元数据结构的最后一个成员。并且如果一个元数据里面包含有这样的元数据成员,该元数据就只能作为最后一个成员被包含在其他的元数据结构里。
<macro name="MAX_COUNT" value="100" /><struct name="type1"><entry name="item1" type="int" count="10" /><entry name="item2" type="float" count="MAX_COUNT" /><entry name="is_exist" type="int" /><entry name="item3" type="int" refer="is_exist" /><entry name="total" type="int" /><entry name="item4" type="int" count="0" refer="total" /></struct>
refer属性
refer属性通常指向该元数据结构中的另一个元数据成员。
当前元数据成员是数组时,refer属性指向的元素的值指明了该数据成员的实际大小。
当前元数据成员是单一元素时,refer属性指向的元素的值指明了该数据成员是否在实际数据中存在(用于处理Option的数据)。
取值为:该元素的直接父元素包含的特定子元素(不支持后向引用,值元素必须在当前元素之前)。
<struct name="type1"><entry name="item1" type="int" /><entry name="item2" type="float" count="10" refer="item1" /></struct>
扩展情况:有时候还需要引用跟当前元素不在同一层次的子元素,此时使用类似Path.Target的形式来指定。
<struct name="type1"><entry name="item1" type="int" /><entry name="item2" type="int" /></struct><struct name="type2"><entry name="head" type="type1" /><entry name="item4" type="float" count="10" refer="head.item1" /></struct>
约束:
refer属性所指元素的值必须小于等于此元素的count属性的值,以上例为例head.item1的值必须不大于10;当元素是单一元素时,count属性取默认值1,这时refer属性所指元素的值只能为1或0,取值为1时表示比元素存在,取值为0时表示此元素不存在。此元素的refer属性所指元素,不能同时被其它元素或父元素指定为sizeinfo或versionindicator属性。
defaultvalue属性
defaultvalue属性指明了如何对该元数据成员的值在没有显式定义时该怎么取值。
取值:合法的字符串,同时该串的内容应该跟该元数据成员的类型匹配。
如果不指定defaultvalue属性,则缺省值为0(同时对于数组不作填充处理)。
约束:
目前支持对内置数据类型设定缺省值,对于自定义复杂数据类型不支持设置缺省值。
<struct name="type1"><entry name="item1" type="int" count="100" defaultvalue="100" /><entry name="item2" type="date" defaultvalue="-11-03" /><entry name="item3" type="int"/></struct>
select属性
select属性和refer属性类似,通常指向该元数据结构中的另一个元数据成员。
select属性指明了如何选择union中数据成员的方法。通常是使用select属性指向的元素的值来决定union中到底使用哪个数据成员。
取值为:该元素的直接父元素包含的特定子元素(不支持后向引用,值元素必须在当前元素之前)。
<union name="type1"><entry name="item1" type="int" id="1" /><entry name="item2" type="int" id="2" /></union><struct name="type2"><entry name="selector" type="short" /><entry name="item3" type="type1" select="selector" /></struct>
customattr2属性
customattr2属性用于表示字段是否属于排序字段,比如排序是降序:sort1不同时按sort1降序;sort1相同时按sort2降序,以此类推。
<struct name="table_Sortlist_single" primarykey="key, name" customattr2="TableType=SORTLIST;ListNum=1023;SortFieldNum=1;SortRule=DESC" version="5" desc="用于list表遍历测试, 需要4个shard, 建表list最大1023个元素" ><entry name="key"type="uint32" desc="单个uint32作为KEY的时候, hashcode = key % 10000"/><entry name="name"type="int16" /><entry name="type_int16" type="int16" desc="type_int16" customattr2="sort1"/><entry name="type_int64" type="int64" desc="type_int64" customattr2="sort2"/></struct>
Union元素
union元素必须是metalib元素的子元素。
union元素与C语言中的union类似。在定义上,union元素和struct元素基本相同。union元素与struct元素的区别与C语言中union和struct的区别相同。
entry子元素
和struct元素一样,entry对应的也是元数据成员的概念。union中的entry子元素除了可以拥有struct中的entry子元素一样的属性外,还可以拥有另外两个额外的属性。
约束:
union中不能再包含有union类型的元数据成员。
minid 和 maxid 属性
通常使用ID属性来作为确定union中到底选择那个元数据成员的依据。但是在实际应用中,可能需要使用一个范围来对应一个元数据成员,这时候使用minid和maxid属性来表示。
当使用minid和maxid时,表示的意义是区间:[minid, maxid]。
当使用ID时,表示的意义是区间:[ID, ID]。
union类型的数据结构的子元素可以没有ID,此时表示该子元素是缺省的元素。当其他子元素都无法匹配的时候,该子元素匹配选择。
为了支持多重取值范围的情况,对于union类型的元数据结构的子元素的名字可以重复,但是这些同名的子元素的类型必需完全一致(对于这种情况,在编译的时候需要给出一些Info类型的提示)。
约束:
union元素的子元素,有且仅有一个可以没有ID属性。maxid,minid属性必须同时出现。如果同时出现了maxid,minid,id属性,则在union结构中选择成员时,以maxid和minid两个属性为准。
<union name="type1"><entry name="example" type="int" minid="1" maxid="100" /><entry name="example" type="int" id="108" /><entry name="example" type="int" minid="200" maxid="300" /><entry name="example" type="int" id="-99" /><entry name="item2" type="int" id="2" /></union>
则example子元素对应的选择器的取值范围可以是:{[1,100],[108,108],[200,300],[-99,-99]}。
TcaplusDB是腾讯出品的分布式NoSQL数据库,存储和调度的代码完全自研。具备缓存+落地融合架构、PB级存储、毫秒级时延、无损水平扩展和复杂数据结构等特性。同时具备丰富的生态、便捷的迁移、极低的运维成本和五个九高可用等特点。客户覆盖游戏、互联网、政务、金融、制造和物联网等领域。