2016-05-31 36 views
1

我有一个拥有数百亿记录的巨大表格,我的意思是在这张表中添加一个字段,其中相同的值将为数百万条记录重复。我不知道如何有效地在cassandra中建模。请允许我阐述:如何建模cassandra上多条记录的重复信息

我有一个通用的表:

CREATE TABLE readings (
    key int, 
    key2 int, 
    time timestamp, 
    name text, 
    PRIMARY KEY ((key, key2) time) 
) 

此表有700.000.000+记录。 我想在此表中创建一个名为source的字段。该字段指示记录的来源(因为该软件有许多方法可以接收reading表中的信息)。这个字段的一个可能的值是"XML: path\to\file.xml""Direct import from the X database"或甚至"Manually added",我希望这是一个描述性字段,专门用于在数据库中进行后期维护,我们只想操作来自给定源的记录。

我想运行,我不能现在的疑问:

  • readings表,记录是从给定源得到?
  • 给定记录的来源是什么?

一个解决方案是为我创建一个表,如:

CREATE TABLE readings_per_source(
    source text, 
    key int, 
    key2 int, 
    time timestamp, 
    PRIMARY KEY (source, key, key2, time) 
) 

这将允许我执行第一查询,但也意味着我将创建700.000.000+新纪录在我的数据库中有很多信息,这会占用大量不必要的存储空间,因为数以百万计的这些记录具有相同的值source

如果这是一个关系型的环境,我会在readings表和sourceid (PK)name领域创造source_id场,这将意味着存储有关readings表的每一行和新表只是一个额外的整数有不同来源的记录数量很多。

我们如何在cassandra中对此进行建模?

回答

2

你的架构

CREATE TABLE readings_per_source(
    source text, 
    key int, 
    key2 int, 
    time timestamp, 
    PRIMARY KEY (source, key, key2, time) 
) 

是一个非常糟糕的主意,因为source是分区键,你可以有百万条记录例如共享相同源具有非常非常宽的分区 - >热点

对于你第二查询,What is the source of a given record?是它相当微不足道如果访问使用该记录的主键(键,KEY2)中的数据。 source列可以作为正常列添加到表中

对于第一个查询Which records on the readings table were gotten from a given source?它是更棘手的。这里的想法是获取所有具有相同来源的记录。

您是否意识到此查询可能会返回数千万条记录

如果这是你想要做什么,有一个解决方案,使用新的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' 
}; 

然后读取所有具有相同源记录,使用Java驱动程序(或任何其他Datastax驱动程序)

+0

是的,我知道这个查询可能会返回很多记录,而这也是一种目的。它可能是一个问题吗?我的意思是用单个查询返回数百万条记录。此外,我曾想过创建某种索引,但不知道如何去做,您的答案会有很大帮助。但有一个问题仍然存在:简单地添加列并以非标准化的方式重复该值,是否会导致过度使用存储? –

+0

此外,我使用python驱动程序,并且我发现驱动程序已经对大量查询的结果进行了分页,是否需要配置与它已有的内容不同的内容? –

+0

“一个问题仍然存在:只需添加列并以非标准化的方式重复该值,是否不会导致过度使用存储? - >理论上是的,在实践中,如果启用了磁盘压缩(默认情况下),它应该有助于节省空间。 – doanduyhai

1

http://www.datastax.com/2015/03/how-to-do-joins-in-apache-cassandra-and-datastax-enterprise是一篇关于如何在Cassandra中加入表格的不错文章。

规格化的数据总是占用比非标准化(平面)数据更少的存储空间(假定相关数据大于用于将表连接在一起的键),但需要在查询期间需要更多功能的连接。

总是有一个权衡。还有一种与完全标准化的数据有关的状态的折衷,其中一个例子是改变地址的客户。在完全标准化的模式中,一旦地址发生变化,客户,过去和现在的所有发票都会显示新地址。这并不总是可取的。

通常需要进行部分规范化处理,以在记录中提供历史状态,以便在给定时间显示数据的状态,例如在发票上。在这种情况下,您需要在发票创建时在发票上存储客户地址数据的副本。

这对定价和税收也特别重要。您希望发票上存储的价格/税额可以显示客户在创建发票时支付了什么,因此,当会计每月运行一次,每年和超出一个给定发票上的价格对于发票,即使产品的价格可能已经改变。否则,你有一个会计噩梦!

在决定如何规范化/规范化模式时,还有很多需要考虑的事情比简单的存储空间还要多。

对不起,散漫......

+0

其实我并不想寻找一种方法来连接表的server-side paging功能是我想要的东西,而无需重复模式的问题到其他资源如spark或ODBC conn ectors。我的问题确实有一些理论基调,所以你的散漫已经被原谅。非常翔实的你的答案,我会考虑到它。谢谢! –

相关问题