在 Cassandra 中,为什么不允许从使用紧凑存储定义的表中删除列?

In Cassandra, why dropping a column from tables defined with compact storage not allowed?

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

这可以追溯到 CQL3 的原始实现,并进行了更改以允许它在原始 Thrift-based 之上抽象出一个“SQL-like”、“wide-row”结构存储引擎。最终,管理架构归结为底层结构是 table 还是 column_family.

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

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;

我将在每个 table:

中插入一行
INSERT INTO student (studentid, fname, lname) VALUES ('janderson','Jordy','Anderson');
INSERT INTO studentcomp (studentid, fname, lname) VALUES ('janderson','Jordy','Anderson');

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

[default@Whosebug] 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@Whosebug] 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)

您是否在第一个结果中看到空的/“幽灵”列值?该空列值是列值和 table 的元数据之间的 CQL3 link。如果不存在,则 CQL 不能用于管理 table 的列。

用于类型转换的比较器是真正通过 Thrift 公开的所有内容。缺少元数据 control/exposure 是 Cassandra 在 pre-CQL 时代被认为是“无模式”的原因。如果我 运行 来自 cassandra-cli 的 describe studentcomp,我可以看到使用的比较器(验证 class):

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)

基本上,tables 和列族是不同的实体,被迫放入同一个桶中。添加 WITH COMPACT STORAGE 实质上使 table 成为一个列族。 随之而来的是在访问比较器之外缺少任何模式管理(添加或删除列)。

编辑 20200905

Can we somehow / someway (hack) drop the columns from table?

可能能够做到这一点。 Sylvain Lebresne 写道 A Thrift to CQL3 Upgrade Guide which will have some necessary details for you. I also advise reading through the Jira ticket mentioned above (CASSANDRA-4377),因为它涵盖了许多 in-depth 技术挑战,使这变得困难。