使用 Cassandra 进行数据建模

Data modeling with Cassandra

我无法获得 Cassandra 的数据建模方式,主要是因为这是我第一次使用非关系数据库。我现在不确定如何制作我的模型。基本上我的模型由星系、恒星、星云、行星和卫星组成。一个星系可以拥有所有这些,所以它是一个 N:M 关系。据我所知,这个想法是用所有这些组件制作一个 table ,或者至少这就是我对 Cassandra 的数据建模策略和非规范化思想的理解。

虽然我觉得这不对,但我不确定该怎么做。

一种看待这个问题的方法是根据您尝试建模的实体之间的关系。例如,星系有恒星,恒星有行星,行星有卫星;它们都具有某些特征(以天为单位的轨道周期,以公里为单位的半径)。你可以模拟类似这样的:

CREATE TABLE galaxyobjects (
  galaxy text,
  star text,
  planet text,
  moon text,
  spectralclass text,
  radiuskm double,
  orbitalperioddays double,
  PRIMARY KEY ((galaxy, star), planet, moon)
);

当然,光谱 class 实际上只适用于 star 列,但在非规范化模型中,您会在每一行看到它。

插入一些数据后,我的 table 可能如下所示:

aploetz@cqlsh:Whosebug> SELECT * FROM galaxyobjects;

 galaxy    | star       | planet      | moon   | orbitalperioddays | radiuskm | spectralclass
-----------+------------+-------------+--------+-------------------+----------+---------------
 Milky Way | Kepler-186 | Kepler-186f |    n/a |          129.9459 |     7072 |            M1
 Milky Way |        Sun |       Earth |   Moon |              27.3 |   3474.8 |            G2
 Milky Way |        Sun |       Earth |    n/a |           365.256 |     6371 |            G2
 Milky Way |        Sun |     Jupiter | Europa |             3.551 |   1560.8 |            G2
 Milky Way |        Sun |     Jupiter |     Io |              1.77 |   1821.6 |            G2
 Milky Way |        Sun |     Jupiter |    n/a |           4332.59 |    71492 |            G2

(6 rows)

现在,如果我想查询木星及其卫星:

aploetz@cqlsh:Whosebug> SELECT * FROM galaxyobjects 
    WHERE galaxy='Milky Way' AND star='Sun' and planet='Jupiter';

 galaxy    | star | planet  | moon   | orbitalperioddays | radiuskm | spectralclass
-----------+------+---------+--------+-------------------+----------+---------------
 Milky Way |  Sun | Jupiter | Europa |             3.551 |   1560.8 |            G2
 Milky Way |  Sun | Jupiter |     Io |              1.77 |   1821.6 |            G2
 Milky Way |  Sun | Jupiter |    n/a |           4332.59 |    71492 |            G2

(3 rows)

备注:

  • 我指定 galaxystar 作为分区键。由于 Cassandra 每个分区最多有 20 亿列,而一个星系肯定可以有数十亿个物体在其中运行,我认为额外的 star 分区是必要的。请注意,在此模型中,您必须在每个查询中同时指定 galaxystar
  • 我想您可以扩展分区键以包含 planet,但是您将无法查询 star 的行星。
  • 在此模型中,planetmoon 是聚类键,因此不需要在每个查询中指定它们。但是你不能跳过它们,所以你不能指定(在你的 WHERE 子句中)一个 moon 而不指定一个 planet.
  • 我的数据建模感觉不太喜欢在单独查询行星(没有月亮)时使用 n/a 作为聚类键。所以也许有更好的方法来建模。也许卫星的集合会更合适?