详解Cassandra数据模型中的primary key

Primary key的基本使用方法

Primary key的基本使用方法同关系型数据库中的primary key基本相同,既用来作为某一行数据的主键。我们用一个最基本的Cassandra表来作为例子。这种最基本的表可以被称为“静态表”。示例如下:

CREATE TABLE users (
    user_id uuid,
    name varchar,
    description varchar,
    registered_data timestamp,
    PRIMARY KEY (user_id)
);

这个例子中的PRIMARY KEY定义是最简单的一种形式——仅指定某一列作为primary key,起到唯一地确定某一行数据记录的作用。在上面的例子中,也就是唯一地确定某一个userPRIMARY KEY()声明中的第一个参数一般被称作partition key。在Cassandra中,partition key除去唯一地确定某一行数据的作用之外,还起到排序数据及在分布式系统中确定数据的位置的作用(这一点在分布式系统中极其重要)。

当数据被插入一个Cassandra集群中时,第一个步骤是根据所采用的一致性哈希(consistent hash)算法得出数据partition key所对应的哈希值。这个哈希值被用来确定数据应当被放在集群中的哪一个结点以及数据的冗余备份应当被放在哪几个结点。Cassandra默认采用的哈希算法是Murmur3。一致性哈希算法的特点是可以接受任何输入,但总会输出位于固定范围内的(当前集群的结点有对应的)值。简而言之,某一特定的partition key总会对应集群中的某一特定的结点,而这个partition key对应的数据也总是应当在这个结点上被找到。

对于分布式系统而言,这一点极其重要。其原因是如果对某一特定数据,我们无法确定其所对应的结点位置的话,我们就总是需要遍历集群中的每一个结点才能找到需要的数据。对于小规模的集群,这样的操作可能还可以接受。但对于大规模的分布式数据库而言,这将会严重影响整个系统的效率。

Primary key的进阶使用方法

如果Cassandra的表的Primary KEY包含某一数据的多个列,我们称之为“动态表”。如下面的例子所示:

CREATE TABLE user_articles (
    user_id uuid,
    uploaded_date timestamp,
    article_id uuid,
    title test,
    abstract text,
    PRIMARY KEY (user_id, uploaded_date, article_id)
);

利用这个表我们可以满足对某一用户所发表的文章的查询。在这一例子中PRIMARY KEY()声明包含数据的多个列。与前文所述相同,声明中包含的第一列仍然是数据的partition key。其后所跟的所有的列都称为clustering column。这一点与关系型数据库非常不同。clustering column用来确定数据在partition内部的排列顺序,对上面的例子而言,也就是对于同一个user_id而言,其所对应的所有行的排列顺序。对于这个paimary key,我们的应当这样理解:

  • 第一个元素确定了partition key
  • 第二个元素确定了第一个clustering column,在这个例子中,也就是uploaded_dateuploaded_date是一个时间戳,也就是说,对于同一个partition key而言,数据将会根据时间升序排列。
  • 第三个元素确定了第二个clustering column,在这个例子中,也就是article_idarticle_id是一个uuid,能够唯一地确定某一篇文章。

在插入相应的数据之后,如果我们使用SELECT去查询,那么返回的数据应当是按照uploaded_date升序排列。对于时间相同的,会按照article_id升序排列。如下面的图片所示:

ASC date user_articles

调整clustering column排序的顺序

既然clustering column能够确定某一个partition内数据排列的顺序,调整这个排列的顺序在某些情况下可能会非常有用。调整这个排列的顺序有两种方法:

  1. SELECT执行的时候指定顺序

我们可以在使用SELECT进行查询的时候使用ORDER BY指定返回的结果的排列顺序。如下面的例子所示:

SELECT * 
FROM user_articles
WHERE user_id = 12345
ORDER BY uploaded_date DESC;

这个例子指定返回的对应于user_id = 12345的文章根据发表的时间降序排序,也就是说新文章考前,就文章靠后。

  1. 指定当前表在存储时候的默认排序顺序

如果我们总是进行某一特定排列顺序的数据查询,我们可以在使用CREATE创建表的schema的时候就为其指定clustering column排列的默认顺序,从而提高将来查询的效率。这一操作可以通过CLUSTERING ORDER BY实现。如下面的例子所示:

CREATE TABLE user_articles (
    user_id uuid,
    uploaded_date timestamp,
    article_id uuid,
    title test,
    abstract test,
    PRIMARY KEY (user_id, uploaded_date, article_id)
) WITH CLUSTERING ORDER BY (uploaded_date DESC, article_id ASC);

插入数据后表格如下面的图片所示:

DESC date user_articles

在这种情况下,根据uploaded_date进行降序排序的操作将会在数据插入时候就默认执行。我们可以看到这种提前根据将来使用需要进行提前优化的操作有可能起到非常好的效果,尤其是对于时序数据来说。比如如果我们想要查询用户最近发表的五篇文章,使用如下的语句就会非常高效地得到所需要的数据:

SELECT *
FROM user_articles
WHERE user_id = 12345
LIMIT 10;

总结

综上所述,我们可以发现在Cassandra中primary key是非常重要的。primary key不仅可以用来进行数据查询,而且被用来确定数据存储的结构。这一点在未来设计Cassandra的数据模型时候应当特别注意,从而可以针对未来可能的使用情况提前进行一些优化设计。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,302评论 5 470
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,232评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,337评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,977评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,920评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,194评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,638评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,319评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,455评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,379评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,426评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,106评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,696评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,786评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,996评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,467评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,043评论 2 341

推荐阅读更多精彩内容