cassandra的key-value模型
1.它基于key-value模型
cassandra的数据库由ColumnFamilies组成,一个ColumnFamily是一个key-value键值对的集合。若和关系型数据库类比,ColumnFamily相当于表,而里面的key-value键值对相当于表里的一条记录。
2.它的key-value模型有多层嵌套
ColumnFamily里的每条记录都是一个key-value对,value部分存放的是无限制的Columns。每个Column都有一个Column Name和value,因此Column实际也是一个key-value对。但Column的value部分已经是最基本的数据存储单元,不能再向下嵌套了。在这种嵌套下,ColumnFamily的每条记录都包含一个key和一个由Columns组成的value(至少有一个Column),也就是说ColumnFamily的value只是一个中间人,实际存储数据的是value里的Columns。如下图所示。
上面所说的是双层嵌套,还有一种三层嵌套。在这种情况下,ColumnFamily每条记录的value部分不是Columns,而是一种被称为SuperColumn的结构。SuperColumn的key是SuperColumn name,它的value部分可以存储多个Columns,如下图所示:
这样就有以下三种嵌套:
ColumnFamily: key - value(SuperColumn)
SuperColumn: key(SuperColumn name) - value(Column)
Column: key(Column name) - value
SuperColumn里不能再存储SuperColumn,因此cassandra的嵌套最多为三层。
3. ColumnFamily
ColumnFamily是一个可以包含无数个Row的结构,又因为Row的value部分是Columns或SuperColumns,因此ColumnFamily实际是Columns和SuperColumns的容器。ColumnFamily对应关系型数据库里的“表”。下面给出ColumnFamily和Row的一个简单示例(使用Column):
User={//这是一个ColumnFamily,名字是User
zhangsan:{//这是一个Row,Row的key是zhangsan
//下面的value可以有无限制的Columns,这里有两个
username:"zhangsan",
email:"zhangsan@163.com",
},//这个Row结束了
lisi:{//这是第二个Row,Row的key是lisi
//value部分,依然是Columns,lisi有三个
username:"lisi",
email:"lisi@163.com",
phone:"123456"
},//Row结束
}
又如下图所示:
在这个层面没有设计模式的要求,Row没有预先定义它们应该包含的Columns列表,就如上面的示例,李四可以随意的多一个phone的Column。一个Row可能有成千上万个Columns而另一个Row可能只有一个Column。cassandra在这一点上有无法比拟的灵活性。
4. 属性为Super的ColumnFamily
上面的示例是一个type为标准的(Standard)ColumnFamily,另外也有Super的ColumnFamily,这取决于我们创建ColumnFamily时的定义。顾名思义,一个类型为Super的ColumnFamily的Row存储的不是Columns,而是SuperColumns。在这种情况下,一个Row的value部分有若干个SuperColumns,一个SuperColumns的value部分又有若干个Columns。如下图所示:
为什么要有SuperColumn呢?SuperColumn提供了比普通Column多一级的一对多关系。Column只能让一个key存储一组相关联的Columns,而这个能让一个key存储多组相关联的Columns。
这里给出一个应用:假设我们提供一种网上地址本的服务,用户可以在这保存他的朋友们的地址,而地址又是由不同的属性如邮编、街道、城市等组成。这时候我们可以采用SuperColumn。对于ColumnFamily,它的key使用的是用户自己的名字,value部分是若干SuperColumns。每个SuperColumns的name部分是用户某个朋友的名字,value部分是若干Columns,存储地址的各个属性。下面是示例:
AddressBook={//这是一个SuperColumnFamily,名字是AddressBook
zhangsan:{//这是一个Row,key是zhangsan,张三的地址本
//下面是Row的Value部分,可以有任意个SuperColumns
lisi:{//这是SuperColumn的name
//下面是Columns,表示地址
street:"XiTuCheng road",
zip:"410083",
city:"BeiJing"
},
wangwu:{//另一个SuperColumn
street:"XiTuCheng road",
zip:"410083",
city:"BeiJing"
},
zhaoliu:{//SuperColumn
street:"XiTuCheng road",
zip:"410083",
city:"BeiJing"
},
.......
}//end the row of zhangsan
lisi:{//这是另一个Row,key是lisi,李四的地址本
wangwu:{//SuperColumn
street:"XiTuCheng road",
zip:"410083",
city:"BeiJing"
},
zhangsan:{//SuperColumn
street:"XiTuCheng road",
zip:"410083",
city:"BeiJing"
},
.......
}
}