基于Cassandra表的查询和主键唯一性

时间:2016-02-22 11:08:15

标签: cassandra primary-key cql

我已阅读here表格,如:

CREATE TABLE user_by_company (
    company text,
    username text,
    email text,
    PRIMARY KEY (company)
);

我们可以创建一个表格:

HttpURLConnection

为了支持公司的查询。但是第二个表的主键唯一性呢?

2 个答案:

答案 0 :(得分:1)

我认为博客中存在拼写错误(您提到的链接)。表格结构正确为user_by_company,因此存在唯一性问题。

支持拼写错误理论:

  

在这种情况下,在公司字段中创建二级索引   用户表可能是一个解决方案,因为它具有低得多的基数   而不是用户的电子邮件,但让我们在考虑性能的情况下解决它。   辅助索引总是比专用表方法慢。

这是博客中提到的用于按公司查询用户的行。 如果要将公司定义为主键或主键的一部分,则不需要创建二级索引。

答案 1 :(得分:1)

修改表的PRIMARY KEY定义并添加username作为聚类键:

CREATE TABLE user_by_company (
    company text,
    username text,
    email text,
    PRIMARY KEY (company,username)
);

这将强制执行唯一性,并返回特定公司的所有用户名。此外,您的结果集将按username的升序排序。

  

数据将按公司名称在节点上进行分区。如果一家公司有很多用户,而另一家公司的用户较少,该怎么办?数据将以非平衡的方式进行分区

这是你必须自己解决的平衡。 Cassandra中的PRIMARY KEY定义是数据分布和查询灵活性之间的交换。除非company的基数非常低(如个位数),否则您不必担心在群集中创建热点。

此外,如果某个特定公司变得太大,您可以使用称为“bucketing”的建模技术。如果我打算“删除”您的user_by_company表,我会首先添加一个company_bucket列,并将其作为附加(复合)分区键:

CREATE TABLE user_by_company (
    company text,
    company_bucket text,
    username text,
    email text,
    PRIMARY KEY ((company,company_bucket),username)
);

至于什么放入那个桶,这取决于你。也许这个特定的公司有东西方位置,所以这样的东西可能会起作用:

INSERT INTO user_by_company (company,company_bucket,username,email)
  VALUES ('Acme','West','Jayne','jcobb@serenity.com');

这里的缺点是,每当查询该表时,您都必须提供company_bucket。但如果一家公司变得太大,这是一个可以帮助你的解决方案。