在一些地方,我们建议根据我们要对它们执行的查询来设计我们的Cassandra表。在this article by DataScale中他们说明了这一点:
事实是,拥有许多具有类似数据的类似表格在Cassandra中是件好事。将主键限制为您将要搜索的内容。如果您计划使用类似但不同的标准搜索数据,请将其设为单独的表。以不同方式存储相同数据没有缺点。重复数据是您在Cassandra的朋友。
[...]
如果您需要在14个不同的表中存储相同的数据,则将其写出14次。多次写入没有障碍。
我已经理解了这一点,现在我的问题是:只要我有一张现有的表,比如说
CREATE TABLE invoices (
id_invoice int PRIMARY KEY,
year int,
id_client int,
type_invoice text
)
但我希望按年份和类型进行查询,所以我想要像
这样的内容CREATE TABLE invoices_yr (
id_invoice int,
year int,
id_client int,
type_invoice text,
PRIMARY KEY (type_invoice, year)
)
以id_invoice
作为分区键,year
作为群集键,将数据从一个表复制到另一个表的首选方法稍后优化查询?
我的Cassandra版本:
user@cqlsh> show version;
[cqlsh 5.0.1 | Cassandra 3.5.0 | CQL spec 3.4.0 | Native protocol v4]
答案 0 :(得分:10)
您可以使用cqlsh COPY命令:
要将发票数据复制到csv文件,请使用:
COPY invoices(id_invoice, year, id_client, type_invoice) TO 'invoices.csv';
并从csv文件复制回您案例中的表invoices_yr使用:
COPY invoices_yr(id_invoice, year, id_client, type_invoice) FROM 'invoices.csv';
如果您有大量数据,您可以使用sstable编写器和sstableloader来更快地加载数据。 http://www.datastax.com/dev/blog/using-the-cassandra-bulk-loader-updated
答案 1 :(得分:8)
为了回应关于COPY命令的说法,对于这样的事情来说这是一个很好的解决方案。
但是,我不同意批量装载机的说法,因为它使用起来非常困难。具体来说,因为您需要在每个节点上运行它(而COPY只需要在单个节点上运行)。
为了帮助大型数据集进行COPY缩放,您可以使用PAGETIMEOUT
和PAGESIZE
参数。
COPY invoices(id_invoice, year, id_client, type_invoice)
TO 'invoices.csv' WITH PAGETIMEOUT=40 AND PAGESIZE=20;
适当地使用这些参数,我使用COPY成功导出/导入了3.7亿行。
有关详细信息,请查看标题为New options and better performance in cqlsh copy。
的文章答案 2 :(得分:3)
使用COPY命令(请参阅示例的其他答案)或Spark来迁移数据的替代方法是创建物化视图以便为您执行非规范化。
CREATE MATERIALIZED VIEW invoices_yr AS
SELECT * FROM invoices
WHERE id_client IS NOT NULL AND type_invoice IS NOT NULL AND id_client IS NOT NULL
PRIMARY KEY ((type_invoice), year, id_client)
WITH CLUSTERING ORDER BY (year DESC)
Cassandra会为你填补表格,所以你不必自己迁移。 3.5注意维修不能很好地工作(见CASSANDRA-12888)。