如何为卡桑德拉的许多记录的重复信息建模
How to model for repeated information on many records on cassandra
我有一个非常巨大的 table,其中包含数千亿条记录,我想在此 table 中添加一个字段,其中相同的值将针对数百万条记录重复。我不知道如何在 cassandra 中有效地建模。请允许我详细说明:
我有一个通用的 table:
CREATE TABLE readings (
key int,
key2 int,
time timestamp,
name text,
PRIMARY KEY ((key, key2) time)
)
这个 table 有超过 700.000.000 条记录。
我想在此 table 中创建一个名为 source
的字段。该字段指示从何处获取记录(因为软件有多种方式接收 reading
table 上的信息)。该字段的一个可能值是 "XML: path\to\file.xml"
或 "Direct import from the X database"
甚至 "Manually added"
,我希望这是一个描述性字段,专门用于允许以后在我们只想操作的数据库中进行维护来自给定来源的记录。
我想 运行 现在不能的查询是:
readings
table 上的哪些记录来自给定来源?
- 给定记录的来源是什么?
一个解决方案是我创建一个 table 例如:
CREATE TABLE readings_per_source(
source text,
key int,
key2 int,
time timestamp,
PRIMARY KEY (source, key, key2, time)
)
这将允许我执行第一个查询,但也意味着我将在我的数据库中创建 700.000.000 多条包含大量信息的新记录,这将占用大量不必要的存储空间 space 因为数以千万计的这些记录对于 source
具有相同的值。
如果这是一个关系环境,我会在 readings
table 上创建一个 source_id
字段,并在 [=22] 上创建一个 source
table =] 和 name
字段,这意味着只为 readings
table 上的每一行存储一个额外的整数和一个新的 table ,其中包含与不同来源一样多的记录.
如何在 cassandra 中对其进行建模?
http://www.datastax.com/2015/03/how-to-do-joins-in-apache-cassandra-and-datastax-enterprise 是一篇关于如何在 Cassandra 中连接表的非常好的文章。
规范化数据将始终比非规范化(平面)数据占用更少的存储空间(前提是相关数据大于用于将表连接在一起的键)但需要在查询期间需要更多计算能力的连接.
总要权衡取舍。还有一个关于完全规范化数据的状态的权衡,一个例子是更改地址的客户。在完全规范化的模式中,一旦地址发生变化,客户的所有发票,过去和现在都会显示新地址。这并不总是可取的。
通常需要部分规范化以提供记录的历史状态,在这些记录中显示给定时间的数据状态很重要,例如发票。在这种情况下,您会在创建发票时在发票上存储客户地址数据的副本。
这对于定价和税收也尤为重要。您希望 price/tax 与发票一起存储,以便您可以显示客户在创建发票时支付的金额,因此当会计按月、按年和超出数字运行时,给定发票上的价格在该日期是正确的在发票上,即使产品的价格可能已经改变。否则你会有一场会计噩梦!
在决定如何 normalize/de-normalize 架构时,需要考虑的不仅仅是存储 space。
抱歉乱说...
您的架构
CREATE TABLE readings_per_source(
source text,
key int,
key2 int,
time timestamp,
PRIMARY KEY (source, key, key2, time)
)
是一个非常糟糕的主意,因为 source
是分区键,您可以有数百万条记录共享 相同的 来源,例如有一个非常非常宽的分区 --> hot spots
对于您的第二个查询,What is the source of a given record?
如果您使用记录主键 (key, key2) 访问数据,这是否很简单。 source
列可以作为常规列添加到 table
对于第一个查询 Which records on the readings table were gotten from a given source?
它比较棘手。这里的想法是获取具有相同来源的所有记录。
您是否意识到此查询可能 return 数千万条记录?
如果这是你想要做的,有一个解决方案,使用新的 SASI 二级索引(阅读我的 blog post 了解所有详细信息)并在 source
列上创建索引
CREATE TABLE readings (
key int,
key2 int,
time timestamp,
name text,
source text,
PRIMARY KEY ((key, key2), time)
)
CREATE CUSTOM INDEX source_idx ON readings(source)
USING 'org.apache.cassandra.index.sasi.SASIIndex'
WITH OPTIONS = {
'mode': 'PREFIX',
'analyzer_class': 'org.apache.cassandra.index.sasi.analyzer.NonTokenizingAnalyzer',
'case_sensitive': 'false'
};
然后要获取具有相同来源的所有记录,请使用 server-side paging 驱动程序(或任何其他 Datastax 驱动程序)的 Java 功能
我有一个非常巨大的 table,其中包含数千亿条记录,我想在此 table 中添加一个字段,其中相同的值将针对数百万条记录重复。我不知道如何在 cassandra 中有效地建模。请允许我详细说明:
我有一个通用的 table:
CREATE TABLE readings (
key int,
key2 int,
time timestamp,
name text,
PRIMARY KEY ((key, key2) time)
)
这个 table 有超过 700.000.000 条记录。
我想在此 table 中创建一个名为 source
的字段。该字段指示从何处获取记录(因为软件有多种方式接收 reading
table 上的信息)。该字段的一个可能值是 "XML: path\to\file.xml"
或 "Direct import from the X database"
甚至 "Manually added"
,我希望这是一个描述性字段,专门用于允许以后在我们只想操作的数据库中进行维护来自给定来源的记录。
我想 运行 现在不能的查询是:
readings
table 上的哪些记录来自给定来源?- 给定记录的来源是什么?
一个解决方案是我创建一个 table 例如:
CREATE TABLE readings_per_source(
source text,
key int,
key2 int,
time timestamp,
PRIMARY KEY (source, key, key2, time)
)
这将允许我执行第一个查询,但也意味着我将在我的数据库中创建 700.000.000 多条包含大量信息的新记录,这将占用大量不必要的存储空间 space 因为数以千万计的这些记录对于 source
具有相同的值。
如果这是一个关系环境,我会在 readings
table 上创建一个 source_id
字段,并在 [=22] 上创建一个 source
table =] 和 name
字段,这意味着只为 readings
table 上的每一行存储一个额外的整数和一个新的 table ,其中包含与不同来源一样多的记录.
如何在 cassandra 中对其进行建模?
http://www.datastax.com/2015/03/how-to-do-joins-in-apache-cassandra-and-datastax-enterprise 是一篇关于如何在 Cassandra 中连接表的非常好的文章。
规范化数据将始终比非规范化(平面)数据占用更少的存储空间(前提是相关数据大于用于将表连接在一起的键)但需要在查询期间需要更多计算能力的连接.
总要权衡取舍。还有一个关于完全规范化数据的状态的权衡,一个例子是更改地址的客户。在完全规范化的模式中,一旦地址发生变化,客户的所有发票,过去和现在都会显示新地址。这并不总是可取的。
通常需要部分规范化以提供记录的历史状态,在这些记录中显示给定时间的数据状态很重要,例如发票。在这种情况下,您会在创建发票时在发票上存储客户地址数据的副本。
这对于定价和税收也尤为重要。您希望 price/tax 与发票一起存储,以便您可以显示客户在创建发票时支付的金额,因此当会计按月、按年和超出数字运行时,给定发票上的价格在该日期是正确的在发票上,即使产品的价格可能已经改变。否则你会有一场会计噩梦!
在决定如何 normalize/de-normalize 架构时,需要考虑的不仅仅是存储 space。
抱歉乱说...
您的架构
CREATE TABLE readings_per_source(
source text,
key int,
key2 int,
time timestamp,
PRIMARY KEY (source, key, key2, time)
)
是一个非常糟糕的主意,因为 source
是分区键,您可以有数百万条记录共享 相同的 来源,例如有一个非常非常宽的分区 --> hot spots
对于您的第二个查询,What is the source of a given record?
如果您使用记录主键 (key, key2) 访问数据,这是否很简单。 source
列可以作为常规列添加到 table
对于第一个查询 Which records on the readings table were gotten from a given source?
它比较棘手。这里的想法是获取具有相同来源的所有记录。
您是否意识到此查询可能 return 数千万条记录?
如果这是你想要做的,有一个解决方案,使用新的 SASI 二级索引(阅读我的 blog post 了解所有详细信息)并在 source
列上创建索引
CREATE TABLE readings (
key int,
key2 int,
time timestamp,
name text,
source text,
PRIMARY KEY ((key, key2), time)
)
CREATE CUSTOM INDEX source_idx ON readings(source)
USING 'org.apache.cassandra.index.sasi.SASIIndex'
WITH OPTIONS = {
'mode': 'PREFIX',
'analyzer_class': 'org.apache.cassandra.index.sasi.analyzer.NonTokenizingAnalyzer',
'case_sensitive': 'false'
};
然后要获取具有相同来源的所有记录,请使用 server-side paging 驱动程序(或任何其他 Datastax 驱动程序)的 Java 功能