Jerrylou's Notes

NoSQL数据库Cassandra数据模型

使用NoSQL存储数据和关系型数据库不一样,关系型数据库是行进行组织数据的。取而代之,应该把它想象成事一个有序的map结构。考虑它是一个map中嵌入另一个map:外部map的key为row key,内部map的key为column key,两个map的key都是有序的。

  • 区分频次大的查询和频次小的查询,有些查询可能只被查询几千次,其它可能被查询数十亿次;
  • 还要考虑哪些查询对数据延迟是敏感的。确保你的模型优先满足查询频次大的查询和重要查询。
  • 反范式化来提升查询性能

示例

是关于电子商务系统的一个功能,一个user可以喜欢多个item,同时一个item可以被多个user所喜爱,在关系型数据库中这个关系是通过many-to-many实现的。

用户表

UserIDNameEmail
u1jerryloujerrylou@gmail.com
u2gunsluogunsluo@gmail.com

Item表

ItemIDTitleDesc
i1mac promac book
i2ipadmac tablet

关系表

IDUserIDItemIDTimestamp
1u1i11512099720
2u1i21512109720
3u2i11512119720

关联表查询

  • 通过user id获取user
  • 通过item id获取item
  • 获取指定user喜欢的所有item
  • 查看指定item被那些user所喜爱

按照关系数据库模型设计数据模型

用户表

Row Key(UserID)Column Family
NameEmail
u1jerryloujerrylou@gmail.com
u2gunsluogunsluo@gmail.com

Item表

Row Key(ItemID)Column Family
TitleDesc
i1mac promac book
i2ipadmac tablet

关系表

Row Key(ID)Column Family
UserIDItemIDTimestamp
1u1i11512099720
2u1i21512109720
3u2i11512119720

这个模型支持通过user id查询user和通过item id查询item。但无法简单查询某个user喜爱的所有item或者某个item被那些user所喜爱。

范式化实体,并将它们反范式化到自定义索引
无法查询的原因是按关系表的进行设计。实体用户表和Item表设计同上。关系表修改为:

User_By_Item表(CF)

Row Key(ItemID)Column Family
u1u2
i1jerrylougunsluo
i2jerrylou

Item_By_User表(CF)

Row Key(UserID)Column Family
i1i2
u1mac proipad
u2mac pro
  • 通过所给item id,获取具体item信息(title, desc等等),并一同查询喜欢这个item的user name(反范式)
  • 通过所给的user id,获取具体user信息,并一同查询user喜欢的所有item titile(反范式)

使用composite column
之前忽略了timestamp,使用timestamp和userid【或ItemID】合并为一个composite column key,这样就可以按时间进行排序了。

User_By_Item表(CF)

Row Key(ItemID)Column Family
1512099720|u11512109720|u11512119720|u2
i1jerrylougunsluo
i2gunsluo

Item_By_User表(CF)

Row Key(UserID)Column Family
1512099720|i11512109720|i21512119720|i1
u1mac proipad
u2mac pro

按照具体的查询需求设计数据模型。