Cassandra:select 仅最新行
Cassandra: select only latest rows
我与以下 table 一起工作:
CREATE TABLE IF NOT EXISTS lp_registry.domain (
ownerid text,
name1st text,
name2nd text,
name3rd text,
registrar text,
registered timestamp,
expiration timestamp,
updated timestamp,
technologies list<text>,
techversions list<text>,
ssl boolean,
PRIMARY KEY (
(name1st, name2nd, name3rd),
registrar, ownerid, registered, expiration, updated
)
);
Table 不会更新,只会添加新行。每次爬虫检查域时,都会添加新行。
我正在表演这个select:
SELECT * FROM lp_registry.domain WHERE
registrar = 'REG-WEDOS' AND
ownerid = 'FORPSI-JAF-S497436'
ALLOW FILTERING;
但我想要的结果只是每个唯一 "name3rd.name2nd.name1st" 具有最新 'updated' 值的行。
如果我在标准 SQL 数据库中,我会使用带 MAX 或 GROUP BY 的嵌套 select。但是,Cassandra (MAX(), DISTINCT and group by in Cassandra) 不支持此功能。但是我应该在 CQL 中做什么?
应修改整个架构。 SELECT
你正在做的,从你的应用程序的角度来看显然是一个重要的,不应该要求 ALLOW FILTERING
:你应该对你的数据进行非规范化并创建一个 table 其中 registrar
和ownerid
是分区键。
在那个非规范化结构中,updated
应该是一个分区键,用 DESC
排序。那么查询将是
SELECT * FROM lp_registry.domain WHERE registrar='XXX' AND ownerid='YYY' LIMIT 10;
正如您所说的那样,行已插入但从未更新,在您的应用程序中插入新数据应该不会很复杂,如果有必要,多个非规范化 tables。
为您的 table 结构提供了更多详细信息和示例。
扩展到 (这是一个很好的建议,并将其视为接受的答案)你会得到一个 table 结构,大致如下:
CREATE TABLE IF NOT EXISTS lp_registry.domain (
ownerid text,
name1st text,
name2nd text,
name3rd text,
registrar text,
registered timestamp,
expiration timestamp,
updated timestamp,
technologies list<text>,
techversions list<text>,
ssl boolean,
PRIMARY KEY ((registrar, ownerid), updated, name1st, name2nd, name3rd)
) WITH CLUSTERING ORDER BY (updated desc);
选择数据时,它将 return 行包含您正在查询的注册商和所有者 ID 分区中最新的 updated
值。
此查询将非常快,因为您的数据将由注册商、所有者 ID 和行按更新降序排列在磁盘上。
这是 cassandra 的一个关键概念,因为您的数据是根据您的查询方式组织的。您在查询中失去了灵活性,但您会感到欣慰table 您将获得出色的性能,因为您正在按组织方式检索数据。这就是为什么根据查询对数据进行非规范化至关重要。
如果您想检索最近更新的 所有 数据,事情就会变得复杂。这个问题不容易用 cassandra 解决,除非所有东西都共享同一个分区,它有自己的一组问题 ()。
我与以下 table 一起工作:
CREATE TABLE IF NOT EXISTS lp_registry.domain (
ownerid text,
name1st text,
name2nd text,
name3rd text,
registrar text,
registered timestamp,
expiration timestamp,
updated timestamp,
technologies list<text>,
techversions list<text>,
ssl boolean,
PRIMARY KEY (
(name1st, name2nd, name3rd),
registrar, ownerid, registered, expiration, updated
)
);
Table 不会更新,只会添加新行。每次爬虫检查域时,都会添加新行。
我正在表演这个select:
SELECT * FROM lp_registry.domain WHERE
registrar = 'REG-WEDOS' AND
ownerid = 'FORPSI-JAF-S497436'
ALLOW FILTERING;
但我想要的结果只是每个唯一 "name3rd.name2nd.name1st" 具有最新 'updated' 值的行。
如果我在标准 SQL 数据库中,我会使用带 MAX 或 GROUP BY 的嵌套 select。但是,Cassandra (MAX(), DISTINCT and group by in Cassandra) 不支持此功能。但是我应该在 CQL 中做什么?
应修改整个架构。 SELECT
你正在做的,从你的应用程序的角度来看显然是一个重要的,不应该要求 ALLOW FILTERING
:你应该对你的数据进行非规范化并创建一个 table 其中 registrar
和ownerid
是分区键。
在那个非规范化结构中,updated
应该是一个分区键,用 DESC
排序。那么查询将是
SELECT * FROM lp_registry.domain WHERE registrar='XXX' AND ownerid='YYY' LIMIT 10;
正如您所说的那样,行已插入但从未更新,在您的应用程序中插入新数据应该不会很复杂,如果有必要,多个非规范化 tables。
扩展到
CREATE TABLE IF NOT EXISTS lp_registry.domain (
ownerid text,
name1st text,
name2nd text,
name3rd text,
registrar text,
registered timestamp,
expiration timestamp,
updated timestamp,
technologies list<text>,
techversions list<text>,
ssl boolean,
PRIMARY KEY ((registrar, ownerid), updated, name1st, name2nd, name3rd)
) WITH CLUSTERING ORDER BY (updated desc);
选择数据时,它将 return 行包含您正在查询的注册商和所有者 ID 分区中最新的 updated
值。
此查询将非常快,因为您的数据将由注册商、所有者 ID 和行按更新降序排列在磁盘上。
这是 cassandra 的一个关键概念,因为您的数据是根据您的查询方式组织的。您在查询中失去了灵活性,但您会感到欣慰table 您将获得出色的性能,因为您正在按组织方式检索数据。这就是为什么根据查询对数据进行非规范化至关重要。
如果您想检索最近更新的 所有 数据,事情就会变得复杂。这个问题不容易用 cassandra 解决,除非所有东西都共享同一个分区,它有自己的一组问题 (