在 Cassandra 中处理一对多
Dealing with one-to-many in Cassandra
给定以下简化域模型:
火车之旅
- id uuid
- 列车名称字符串(一天内唯一)
- 旅行日期
- ...
旅程站点
- 站uuid
- 到达时间戳
- 出发时间戳
- ...
与此关系:
- 1 趟火车旅程有 n 个旅程站
与此查询要求:
- 给定车站的所有火车旅程,包括所有旅程车站,在给定时间范围内出发。
应该如何在 Cassandra 中为这个查询建模?
我在想类似的事情:
CREATE TABLE departures_by_station (
date_of_yourney date,
train_name varchar,
station uuid,
arrival timestamp,
departure timestamp,
primary key((date_of_journey, station), train_name, departure)
);
SELECT * from departures_by_station
WHERE date_of_journey = '2018-01-02' AND station = 'Paris' AND departure ...;
这将不起作用,因为它会导致部分火车旅行 - 除了请求的旅行站外,所有旅行站都丢失了。
更糟糕的是,到达和离开时间可能会经常更改。我无法使用新的出发时间更新此 table,因为它是一个聚类键。
任何想法或提示如何解决这个问题?我想我在这里遗漏了一些基本的东西,但我对 nosql 世界还很陌生。
首先,它可能不是最佳解决方案(需要对分区大小等进行一些计算)。如果你可以使用 TTL 使 "old" 数据过期,那么我想过这样的事情:
CREATE TABLE departures_by_station (
station uuid,
departure timestamp,
train_name varchar,
arrival timestamp,
statitions list<uuid>
primary key(station, departure, train_name)
);
在这种情况下,您将拥有所谓的 "wide" 分区 - 每个旅程站一个分区,并且因为您将出发地作为聚类键,所以您可以对其进行范围搜索。但是,如果您使大量数据过期,那么您需要经常对表执行 "repairing" 以消除墓碑(删除标记),因为这可能会影响读取性能。
此外,为了避免进行多次查找,您需要将沿途所有站点的信息放入每一行 - 我将其写为 list<uuid>
,但它可以更好地建模为用户定义的类型,因此您可以包括站名和其他信息。
您的代码还应该为特定列车沿途的每个车站生成一个条目。
P.S。我建议参加 DataStax Academy 上的 DS220(数据建模)课程。
给定以下简化域模型:
火车之旅
- id uuid
- 列车名称字符串(一天内唯一)
- 旅行日期
- ...
旅程站点
- 站uuid
- 到达时间戳
- 出发时间戳
- ...
与此关系:
- 1 趟火车旅程有 n 个旅程站
与此查询要求:
- 给定车站的所有火车旅程,包括所有旅程车站,在给定时间范围内出发。
应该如何在 Cassandra 中为这个查询建模?
我在想类似的事情:
CREATE TABLE departures_by_station (
date_of_yourney date,
train_name varchar,
station uuid,
arrival timestamp,
departure timestamp,
primary key((date_of_journey, station), train_name, departure)
);
SELECT * from departures_by_station
WHERE date_of_journey = '2018-01-02' AND station = 'Paris' AND departure ...;
这将不起作用,因为它会导致部分火车旅行 - 除了请求的旅行站外,所有旅行站都丢失了。 更糟糕的是,到达和离开时间可能会经常更改。我无法使用新的出发时间更新此 table,因为它是一个聚类键。
任何想法或提示如何解决这个问题?我想我在这里遗漏了一些基本的东西,但我对 nosql 世界还很陌生。
首先,它可能不是最佳解决方案(需要对分区大小等进行一些计算)。如果你可以使用 TTL 使 "old" 数据过期,那么我想过这样的事情:
CREATE TABLE departures_by_station (
station uuid,
departure timestamp,
train_name varchar,
arrival timestamp,
statitions list<uuid>
primary key(station, departure, train_name)
);
在这种情况下,您将拥有所谓的 "wide" 分区 - 每个旅程站一个分区,并且因为您将出发地作为聚类键,所以您可以对其进行范围搜索。但是,如果您使大量数据过期,那么您需要经常对表执行 "repairing" 以消除墓碑(删除标记),因为这可能会影响读取性能。
此外,为了避免进行多次查找,您需要将沿途所有站点的信息放入每一行 - 我将其写为 list<uuid>
,但它可以更好地建模为用户定义的类型,因此您可以包括站名和其他信息。
您的代码还应该为特定列车沿途的每个车站生成一个条目。
P.S。我建议参加 DataStax Academy 上的 DS220(数据建模)课程。