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