目前我正在开发时间序列数据领域的解决方案。在这些数据中,我们有:ID,值和时间戳。 所以它来了:值可能是boolean,float或string类型。我考虑三种方法:
a)对于每个数据类型一个不同的表,将boolean类型的所有传感器值放入表中,将string类型的所有传感器值转换为另一个。明显的缺点是你必须知道在哪里寻找某个传感器。
b)描述数据类型加上字符串类型的所有值的元列。明显的缺点是数据转换,例如用于计算MAX,AVG等。
c)有三列不同类型但只有一列将具有每条记录的值。缺点是每100毫秒发射500000个传感器......充足的未使用空间。
由于我的知识有限,任何帮助都表示赞赏。
答案 0 :(得分:3)
每100毫秒发射500000个传感器
首先,要确保正确分区,以确保不超过每个分区20亿个列的限制。
CREATE TABLE sensorData (
stationID uuid,
datebucket text,
recorded timeuuid,
intValue bigint,
strValue text,
blnValue boolean,
PRIMARY KEY ((stationID,datebucket),recorded));
每100毫秒有50万,这是每秒5亿。因此,您需要将datebucket
设置得非常精细......直到第二个。接下来我将插入一些数据:
stationid | datebucket | recorded | blnvalue | intvalue | strvalue
--------------------------------------+---------------------+--------------------------------------+----------+----------+----------
8b466f1d-8d6b-46fa-9f5b-8c4eb51aa40c | 2015-04-22T14:54:29 | 6338df40-e929-11e4-88c8-21b264d4c94d | null | 59 | null
8b466f1d-8d6b-46fa-9f5b-8c4eb51aa40c | 2015-04-22T14:54:29 | 633e0f60-e929-11e4-88c8-21b264d4c94d | null | null | CD
8b466f1d-8d6b-46fa-9f5b-8c4eb51aa40c | 2015-04-22T14:54:29 | 6342f160-e929-11e4-88c8-21b264d4c94d | True | null | null
3221b1d7-13b4-40d4-b41c-8d885c63494f | 2015-04-22T14:56:19 | a48bbdf0-e929-11e4-88c8-21b264d4c94d | False | null | null
......充足的未使用空间。
你可能会感到惊讶。使用上面SELECT *
的 CQL 输出,似乎整个地方都有null
个值。但请注意当我们使用cassandra-cli
工具查看数据存储方式时会发生什么:
RowKey: 3221b1d7-13b4-40d4-b41c-8d885c63494f:2015-04-22T14\:56\:19
=> (name=a48bbdf0-e929-11e4-88c8-21b264d4c94d:, value=, timestamp=1429733297352000)
=> (name=a48bbdf0-e929-11e4-88c8-21b264d4c94d:blnvalue, value=00, timestamp=1429733297352000)
如您所见,为stationid=3221b1d7-13b4-40d4-b41c-8d885c63494f AND datebucket='2015-04-22T14:56:19'
显示blnValue
的值00
(false)的CQL行存储的数据(上图)。但另请注意,intValue
和strValue
不存在。 Cassandra不像RDBMS那样强制null
值。
明显的缺点是数据转换,例如用于计算MAX,AVG等。
也许您已经知道这一点,但我确实想提一下Cassandra CQL不包含MAX
,AVG
或任何其他数据聚合函数的定义。您可能需要执行该客户端,或者实现Apache-Spark来执行OLAP类型的查询。
请务必阅读Patrick McFadin的Getting Started With Time Series Data Modeling。它包含了如何解决这样的时间序列问题的好建议。