首页 > 解决方案 > 在 Cassandra 中,为什么不允许从使用紧凑存储定义的表中删除列?

问题描述

根据此处的 datastx 文档,我们无法从使用 COMPACT STORAGE 选项定义的表中删除列。这是什么原因?

标签: cassandracql3cassandra-cli

解决方案


这可以追溯到 CQL3 的原始实现,并进行了更改以允许它在原始的基于 Thrift 的存储引擎之上抽象出“类似 SQL”的宽行结构。最终,管理模式归结为底层结构是table还是column_family

例如,我将使用旧安装的 Apache Cassandra (2.1.19) 创建两个表:

CREATE TABLE student (
  studentid TEXT PRIMARY KEY,
  fname TEXT,
  name TEXT);

CREATE TABLE studentcomp (
  studentid TEXT PRIMARY KEY,
  fname TEXT,
  name TEXT)
WITH COMPACT STORAGE;

我将在每个表中插入一行:

INSERT INTO student (studentid, fname, lname) VALUES ('janderson','Jordy','Anderson');
INSERT INTO studentcomp (studentid, fname, lname) VALUES ('janderson','Jordy','Anderson');

然后我将使用旧的 cassandra-cli 工具查看表格:

[default@stackoverflow] list student;
Using default limit of 100
Using default cell limit of 100
-------------------
RowKey: janderson
=> (name=, value=, timestamp=1599248215128672)
=> (name=fname, value=4a6f726479, timestamp=1599248215128672)
=> (name=lname, value=416e646572736f6e, timestamp=1599248215128672)

[default@stackoverflow] list studentcomp;
Using default limit of 100
Using default cell limit of 100
-------------------
RowKey: janderson
=> (name=fname, value=Jordy, timestamp=1599248302715066)
=> (name=lname, value=Anderson, timestamp=1599248302715066)

您在第一个结果中看到空/“ghost”列值吗?该空列值是 CQL3 在列值和表元数据之间的链接。如果它不存在,则不能使用 CQL 来管理表的列。

用于类型转换的比较器是通过 Thrift 真正公开的所有内容。这种元数据控制/暴露的缺乏使得 Cassandra 在 CQL 之前的日子里被认为是“无模式的”。如果我describe studentcomp从 cassandra-cli 中运行 a,我可以看到使用的比较器(验证类):

Column Metadata:
  Column Name: lname
    Validation Class: org.apache.cassandra.db.marshal.UTF8Type
  Column Name: fname
    Validation Class: org.apache.cassandra.db.marshal.UTF8Type

但如果我尝试describe student,我会看到:

WARNING: CQL3 tables are intentionally omitted from 'describe' output.
See https://issues.apache.org/jira/browse/CASSANDRA-4377 for details.

Sorry, no Keyspace nor (non-CQL3) ColumnFamily was found with name: student (if this is a CQL3 table, you should use cqlsh instead)

基本上,表和列族是强制进入同一个存储桶的不同实体。添加WITH COMPACT STORAGE本质上使表成为列族。随之而来的是在访问比较器之外缺乏任何模式管理(添加或删除列)。

编辑 20200905

我们可以以某种方式/某种方式(hack)从表中删除列吗?

也许可以做到这一点。Sylvain Lebresne 写了A Thrift to CQL3 升级指南,它将为您提供一些必要的细节。我还建议通读上面提到的 Jira 票证 ( CASSANDRA-4377 ),因为它涵盖了许多使这变得困难的深入技术挑战。


推荐阅读