基于Cassandra表的查询和主键唯一性
我读过这样一张表:基于Cassandra表的查询和主键唯一性,cassandra,primary-key,cql,Cassandra,Primary Key,Cql,我读过这样一张表: CREATE TABLE user ( username text, password text, email text, company text, PRIMARY KEY (username) ); 我们可以创建如下表: CREATE TABLE user_by_company ( company text, username text, email text, PRIMARY KEY (compa
CREATE TABLE user (
username text,
password text,
email text,
company text,
PRIMARY KEY (username)
);
我们可以创建如下表:
CREATE TABLE user_by_company (
company text,
username text,
email text,
PRIMARY KEY (company)
);
以支持公司的查询。但是第二个表的主键唯一性呢?我认为博客(您提到的链接)中有输入错误。您对表格结构的理解是正确的,因为公司将出现唯一性问题 为了支持打字错误理论: 在本例中,在 用户表可以是一个解决方案,因为它的基数要低得多 而不是用户的电子邮件,但让我们考虑性能来解决它。 二级索引总是比专用表方法慢 这是博客中提到的按公司查询用户的行。
如果要将公司定义为主键或主键的一部分,则不需要创建辅助索引。修改表的主键定义,并将
用户名添加为群集键:
CREATE TABLE user_by_company (
company text,
username text,
email text,
PRIMARY KEY (company,username)
);
这将强制执行唯一性,并返回特定公司的所有用户名。此外,您的结果集将按username
按升序排序
数据将按节点上的公司名称进行分区。如果一家公司的用户多,而另一家公司的用户少怎么办。数据将以非平衡方式进行分区
这是你必须自己解决的平衡。Cassandra中的主键定义是数据分布和查询灵活性之间的取舍。除非公司的基数非常低(比如个位数),否则您不必担心在集群中创建热点
此外,如果某个特定公司变得太大,您可以使用一种称为“bucketing”的建模技术。如果我要按公司对您的user\u
表进行“bucket”,我会首先添加一个company\u 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\u bucket
。但是,如果一家公司变得太大,这是一个可以帮助您的解决方案。我想您想要的是主键(公司,用户名)
不是一个好主意,因为数据将通过节点上的公司名称进行分区。如果一家公司的用户多,而另一家公司的用户少怎么办。数据将以非平衡方式进行分区,那么您的查询模式是什么?您可以在分区键中同时包含公司和用户名。或者电子邮件。这实际上取决于您的查询模式。