MongoDB 的 terichdb schema
Mongodb 虽然是 schemaless (不需要 schema) 的文档数据库,但是,同一个表中的数据一般都有相同的结构,我们需要将这样的结构抽象出来,用以提高数据库的性能
terichdb 的数据有以下类型:
| DataType | Aliases | Description |
| Any | Not supportted, real type is stored as first byte of the data | |
| Nested | Not supportted | |
| Uint08 | uint8,byte,ubyte | |
| Sint08 | int8,sbyte | |
| Uint16 | ||
| Sint16 | int16 | |
| Uint32 | ||
| Sint32 | int32 | |
| Uint64 | ||
| Sint64 | int64 | |
| Uint128 | just support storing, not indexing | |
| Sint128 | int128 | |
| Float32 | float | |
| Float64 | double | |
| Float128 | just support storing, not indexing | |
| Decimal128 | ||
| Uuid | guid | 16 bytes(128 bits) binary |
| Fixed | Fixed length binary | |
| VarSint | Not supportted | |
| VarUint | ||
| StrZero | Zero ended string | |
| TwoStrZero | Special, now just for BSON RegEx type | |
| Binary | Prefixed by length(var_uint) in bytes | |
| CarBin | Cardinal Binary, prefixed by uint32 length |
从 mongodb 获取到bson数据后,根据一个bson文档中字段的类型,与 terich db 做如下转化
| MongoDB数据类型 | terichdb 数据类型 |
|---|---|
| Object | Nested |
| Bool | Uint08, |
| NumberInt | Sint32, |
| NumberLong
bsonTimestamp mongo::Date |
Sint64, |
| NumberDouble | Float64, |
| Decimal128 | Decimal128 |
| Oid | Fixed, // Fixed length binary |
| Code
String Symbol |
StrZero, // Zero ended string |
| RegEx | TwoStrZero, // Special, now just for BSON RegEx type |
| Array
BinData CodeWScope |
CarBin, // Cardinal Binary, prefixed by uint32 length |
| Undefined
jstNULL |
长度为0的Binary |
| MaxKey
MinKey |
无对应类型 |
这是一个 terich db 的 schema json 样例(tablename=headline):
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
{ "RowSchema": { "columns" : { "_id" : { "type": "fixed" , "uType": 16, "length": 12 }, "ts" : { "type": "sint32" , "uType": 16 }, "type" : { "type": "StrZero", "uType": 2 }, "id" : { "type": "StrZero", "uType": 2 }, "manual" : { "type": "uint08" , "uType": 8 }, "list" : { "type": "nested" , "uType": 4 }, "$$" : { "type": "CarBin" , "comment1": "bin data of the schema-less fields, must be the last field", "comment2": "schema-less fields may be many optional fields" } } }, "TableIndex" : [ { "fields": "_id", "ordered" : true, "unique" : true }, { "fields": "+ts,-type", "ordered" : true }, { "fields": "id" , "ordered" : true } ], "NestedSchemaSet": { "1": { "columns": { "date" : { "type": "sint64" , "uType": 9 }, "count" : { "type": "sint32" , "uType": 16 }, "title" : { "type": "StrZero", "uType": 2 }, "fromid" : { "type": "StrZero", "uType": 2 }, "docid" : { "type": "StrZero", "uType": 2 }, "source" : { "type": "StrZero", "uType": 2 }, "image" : { "type": "StrZero", "uType": 2 }, "tag" : { "type": "StrZero", "uType": 2 }, "is_news": { "type": "sint32" , "uType": 16 }, "dtype" : { "type": "sint32" , "uType": 16 }, "$$" : { "type": "carbin" } } } } } |
另一个样例(tablename=news):
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
{ "RowSchema": { "columns" : { "_id" : { "type": "StrZero", "uType": 2 }, "url" : { "type": "StrZero", "uType": 2 }, "fdts" : { "type": "sint32" , "uType": 16 }, "fi" : { "type": "sint32" , "uType": 16 }, "fts" : { "type": "sint32" , "uType": 16 }, "level" : { "type": "uint08" , "uType": 16 }, "score" : { "type": "float32", "uType": 1 }, "stat" : { "type": "sint32" , "uType": 16 }, "status" : { "type": "sint32" , "uType": 16 }, "ts" : { "type": "sint32" , "uType": 16 }, "type" : { "type": "sint32" , "uType": 16 }, "il" : { "type": "nested" , "uType": 3, "nested": { "columns": { "txt": { "type": "strzero", "uType": 2 }, "url": { "type": "strzero", "uType": 2 } } } }, "$$" : { "type": "CarBin" , "uType": 3 } } }, "TableIndex" : [ { "fields": "_id", "ordered" : true, "unique" : true }, { "fields": "ts" , "ordered" : true, "unique" : true } ] } |
说明:
- “mongoType” 是 mongodb bson 类型对应的整数编码,因为 terichdb 需要对接到多种数据库,mongoType是专为 mongodb 而设计(当然,还有一个 mysqlType)
- “type” 的名字不区分大小写,例如 “strzero” 和 “StrZero” 相同,都是以字符 ‘\0’ 结尾的字符串(C 语言字符串)
- MongoDB 的 Oid 是固定 12 个字节长度的二进制串,转化为 terichdb 类型时,是 Fixed,length=12
- TableIndex 中
- fields 表示索引的字段,可以是多字段联合索引,字段的顺序很重要
- 字段名前面的“+”,“-”号表示在该字段上是递增,还是递减,“+”表示递增,“-”表示递减,默认是“+”,可以省略,“-”不可省略
- Index 可以是 ordered,mongodb 的 index 都是 ordered,但是 terichdb 支持 “ordered”: false 的 index,此时是 hash index
- Index 可以是 unique的,默认是 非unique的,即可以有重复的 index key
- 名字为“$$”的字段,必须是一个schema的最后一个字段,类型必须是carbin,表示所有“其它”字段,当同一个表中难以抽象出固定的schema时,可以只将所有公共的字段抽象出来,其它字段扔进一个“自由”的二进制字段。
- NestedSchemaSet表示:mongodb 文档中的字段是Object或Array时,实际上是一个嵌套的“子文档”,子文档可以有内部结构,同一个表可以多个这样NestedSchema,每个NestedSchema有一个schema id,示例中“1”就是schema id,schema id必须是整数,从1开始编号。
- 当嵌套字段是 Array 时(tablename=headline),设置uType=4,不需其它额外说明
- 当嵌套字段是 Object 时,并且能抽象出一个共同的 schema 时,直接将 nested 写在里面,不需要生成 NesetdSchemaSet,样例2(tablename=news)就是这样。
- 当嵌套字段是 Object 时,但不能抽象出一个共同的 schema 时,需要生成 NesetdSchemaSet(没有相应样例),此时 terichdb 会根据 NesetdSchemaSet 中的 schemaId 解码。