【深入理解TcaplusDB技术】详细介绍TDR表

相关概念

TDR(Tencent Data Representation)是腾讯推出的,进行游戏开发的基础组件,所有的组件都是基于TDR进行开发。DR数据表示组件以程序库、TDR工具的形式发布。TDR-API本质是相当于一套独立于数据结构的算法,常用API的功能涉及网络编解码、XML数据输入输出、数据可视化、对象关系映射、数据排序。TDR工具实现各种元数据格式之间的转换,并且可以根据XML格式的元数据描述生成C/C++数据结构定义头文件。TDR工具还能够生成实现指定功能的代码,目前支持生成C++\AS3\C#三种语言的代码,支持的功能包括网络编解码、XML数据输入输出、数据可视化。

协议描述与打解包

Tdr使用Xml来描述定义协议文件,可用tdr工具转换成对应的头文件和cpp文件。生成结构体,cmdID的定义和对应的打解包函数。生成之后的结构体和函数可以直接在程序中应用。Tdr支持生成C++\AS3\C#语言。因为游戏存在运营过程中动态更新,在实际的游戏协议应用中,最关注的是协议的兼容性问题,包括CS协议和SS协议的兼容性。Tdr通过版本号来进行协议兼容性的处理,新加字段需要增加对应的版本号,和整个tdr的版本号。Tdr打包的时候会打上对应的最大版本号和字段版本号。打包可以根据对方的版本号进行打包,解包的时候根据数据的版本号进行解包。支持高版本对低版本的兼容。

  <struct name="users" version="1" primarykey="user_id,username,role_id" splittablekey="user_id" desc="user table">
    <entry name="user_id" type="uint64" desc="user id"/>
    <entry name="username" type="string" size="64" desc="login username"/>
    <entry name="role_id" type="int32" desc="a user can have multiple roles"/>
 
    <entry name="level" type="int32" defaultvalue="1" desc="role's level"/>
    <entry name="role_name" type="string" size="1024" desc="role's name" version="100"/>
    <entry name="last_login_time" type="string" size="64" defaultvalue="" desc="user login timestamp" version="101"/>
    <entry name="last_logout_time" type="string" size="64" defaultvalue="" desc="user logout timestamp" version="102"/>
 
    <index name="index1" column="user_id"/>
  struct>

例如以上的协议中,后面几个字段都是新增字段,需要严格按照版本号递增,除了修改具体结构中的版本号之外,还需要修改整体的版本号。

<metalib name="tcaplus_tb" tagsetversion="1" version="1">

这样tdr打包的数据中就有了具体的整体版本号信息和字段版本号信息。可以做到高版本兼容低版本,但是低版本无法兼容高版本。在实际的上线版本运营中,新增字段必须严格按照版本号升级,要注意具体新增字段和总版本号的同步更新。同时又存在cs协议和ss协议,所以新增字段的时候修改点比较多,检查版本号的步骤比较繁琐,需要人工保证。

文件结构

XML文件头

标准的XML文件头如下:


前期为了减少字符编码问题带来的影响,先使用GBK作为字符编码。长期来讲,应使用UTF-8作为字符编码,以支持多语言和可移植性。
目前暂时先使用:


metalib

一个XML文件只能有一个根元素(Root Element)。对于元数据描述用途的文档,根元素是metalib。表明该XML文件的内容是一个元数据描述集合。

示例

这是一个tdr建表的例子:


 
<metalib name="tcaplus_tb" tagsetversion="1" version="1">
 
  <struct name="TestInfo" version="1" desc="" >
		<entry name="d"          type="uint64" />  
		<entry name="test"       type="uint64" />  
  struct>

 <struct name="TableInfo" version="1" desc="" >
		<entry name="c"          	type="TestInfo" />  
		<entry name="test"          type="uint64" />  
		<entry name="string_array" 	type="string"  size="100" />
		<entry name="binary"       	type="tinyint" />
	struct>

  <struct name="simple_struct" version="4">
    <entry name="c_int8" type="int8" defaultvalue="-1"/>
    <entry name="c_uint8" type="uint8" defaultvalue="2"/>
    <entry name="c_int16" type="int16" defaultvalue="-3"/>
    <entry name="c_uint16" type="uint16" defaultvalue="4"/>
    <entry name="c_int32" type="int32" defaultvalue="-5"/>
    <entry name="c_uint32" type="uint32" defaultvalue="6"/>
    <entry name="c_int64" type="int64" defaultvalue="-7"/>
    <entry name="c_uint64" type="uint64" defaultvalue="8"/>
  struct>

  <union name="union_type" version="1">
		<entry name="Id"      	type="int32"  id="0" defaultvalue="0"	 desc="id" />
		<entry name="Name"      type="string"  id="1" size="64" defaultvalue="hello" desc="name" />
	union>

  <struct name="struct_type" version="1">
		<entry name="x"         type="int32"  defaultvalue="0" 	desc="x" />
		<entry name="y"			type="int32"  defaultvalue="0"	desc="y" />
		<entry name="score"          type="double" defaultvalue="1.11" version="2" />  
		<entry name="rank"          type="uint8" defaultvalue="1" version="3" />  
		<entry name="title"          type="string" size="48" desc="title" />  
		<entry name="level2_struct" type="struct_nested" version="2" />
	struct>

  <struct name="table_list" version="1"  primarykey="uin,name,key1" splittablekey="uin"  customattr2="TableType=LIST;ListNum=100;DataProtocolType=PLAIN">
		<entry name="uin" type="uint64" desc="QQ"/>
		<entry name="name" type="string" size="255" desc="Name"/>
		<entry name="key1" type="uint8" desc="key4"/>
		<entry name="level"    type="int32"   defaultvalue="1" />
   	<entry name="count"    type="uint8"   defaultvalue="0" />
		<entry name="array_count"  type="uint32"  defaultvalue="1" /> 
		<entry name="items"    type="uint64" count="10" refer="array_count"/>
		<entry name="c_int8" type="int8" defaultvalue="-1"/>
		<entry name="c_uint8" type="uint8" defaultvalue="2"/>
		<entry name="c_int16" type="int16" defaultvalue="-3"/>
		<entry name="c_uint16" type="uint16" defaultvalue="4"/>
		<entry name="c_int32" type="int32" defaultvalue="-5"/>
		<entry name="c_uint32" type="uint32" defaultvalue="6"/>
		<entry name="c_int64" type="int64" defaultvalue="-7"/>
		<entry name="c_uint64" type="uint64"/>
		<entry name="c_float" type="float" defaultvalue="1.23456789" version="2"/>
		<entry name="c_double" type="double" defaultvalue="9.87654321" version="3" />
		<entry name="c_string" type="string" size="200" version="3" />
		<entry name="c_string_128K" type="string" size="VALUE_128KB_SIZE" defaultvalue="123456789"/>
		<entry name="c_string_256K" type="string" size="VALUE_256KB_SIZE" defaultvalue="123456789"/>
		<entry name="c_binary" type="tinyint"  count="10" refer="array_count" />
		<entry name="binary" type="tinyint"  version="5"/>
    <entry name="selector" type="short" />
		<entry name="single_struct" type="struct_type"/>
		<entry name="simple_struct" type="simple_struct" version="4"/>
		<entry name="single_union_selector" type="int8" defaultvalue="0" />
		<entry name="single_union" type="union_type" select="single_union_selector" />
		<entry name="array"        type="TableInfo" count="3" refer="array_count"/>
		<entry name="c_union"  type="union_type" select="selector"/>
		<entry name="union_array" type="union_type"  count="3" select="selector" refer="array_count"/>
	  <entry name="c_struct" type="struct_type"/>
		<entry name="struct_array" type="struct_type"  count="3" refer="array_count"/>		
    <index name="index1" column="uin"/>
		<index name="index2" column="uin,name"/>
	struct>
	
metalib>

说明:

  • 元素metalib是xml文件的根元素。
  • 包含属性primarykey的struct元素定义一个表;否则,它只是一个普通的结构体。
  • 每次修改表结构时,版本属性值需要相应地加1,初始版本始终为1。
  • primarykey属性指定主键字段;对于generic表,您最多可以指定8个主键字段,对于list表,则可以指定7个。
  • splittablekey属性等效于分片键(shard key),TcaplusDB表被拆分存储到多个存储节点。 splittablekey必须是主键字段之一,一个好的splittablekey应该具有高度分散性,这意味着值的范围很广,建议选用字符串类型。
  • desc属性包含当前元素的描述。
  • entry元素定义一个字段。支持的值类型包括int32,string,char,int64,double,short等。
  • index元素定义一个索引,该索引必须包含splittablekey。由于可以使用主键查询表,因此索引不应与主键属性相同。

【深入理解TcaplusDB技术】详细介绍TDR表_第1张图片

另外,您可以使用union创建嵌套类型。

  • union元素包含原始类型的集合,例如整数和字符串,可以将Union也可以作为自定义类型来引用。
  • Macro标签用于定义常量。
<union name="union_type" version="1">
		<entry name="Id"      	type="int32"  id="0" defaultvalue="0"	 desc="id" />
		<entry name="Name"      type="string"  id="1" size="64" defaultvalue="hello" desc="name" />
union>
  • 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="following_action_list" version="1" primarykey="game,myuin",  customattr2="TableType=SORTLIST;ListNum=1023;SortFieldNum=1;SortRule=DESC">
   <entry name="TimeStamp"      type="uint32"   desc="单位为分钟" />
   <entry name="time"           type="uint32"   customattr2="sort1"  desc="时间"/>
struct>

接下来会对示例中提到的相关属性进行详细描述。


【深入理解TcaplusDB技术】详细介绍TDR表_第2张图片

TcaplusDB是腾讯出品的分布式NoSQL数据库,存储和调度的代码完全自研。具备缓存+落地融合架构、PB级存储、毫秒级时延、无损水平扩展和复杂数据结构等特性。同时具备丰富的生态、便捷的迁移、极低的运维成本和五个九高可用等特点。客户覆盖游戏、互联网、政务、金融、制造和物联网等领域。

你可能感兴趣的:(TcaplusDB,数据库,nosql,tcaplusdb,腾讯云)