在 Cassandra 中存储带有空组件的 CQL 元组是否合法 3.x

Is it legit to store CQL tuples with null components in Cassandra 3.x

我必须在 Cassandra 中存储协议​​缓冲区结构 3.x。它在 .proto 文件中定义为:

message Attribute
{
    required string key = 1;
    oneof value {
        int64 integerValue = 2;
        float floatValue = 3;
        string stringValue = 4;
    }
}

存储多个Attributes我在想这个CQL定义。

CREATE TABLE ... attributes: map<text, tuple<int, float, text> ...

并且在每个元组中,3 个组件中的 2 个实际上是 null。我还没有测试过这种语法,但是使用这种方法有什么缺点吗?也许有更好的方法,即用户定义类型?

让我们试试这个。我将从一个简单的 table 开始,其中包含一个 map<text,tuple<int,float,text> 类型的 valuemap 列,如上所示:

CREATE TABLE tupleTest (
  key text,
  value text, 
  valuemap map<text, FROZEN<tuple<int,float,text>>>,
  PRIMARY KEY (key));

我会INSERT一些数据:

INSERT INTO tupletest (key,value,valuemap) VALUES ('1','A',{'a':(0,0.0,'hi')});
INSERT INTO tupletest (key,value,valuemap) VALUES ('2','B',{'b':(0,null,'hi')});
INSERT INTO tupletest (key,value,valuemap) VALUES ('3','C',{'c':(null,null,'hi')});

然后我会SELECT它,只是为了看看:

aploetz@cqlsh:Whosebug> SELECT * FROM tupletest ;

 key | value | valuemap
-----+-------+---------------------------
   3 |     C | {'c': (None, None, 'hi')}
   2 |     B |    {'b': (0, None, 'hi')}
   1 |     A |       {'a': (0, 0, 'hi')}

(3 rows)

关于显式 INSERT 将 NULL 值输入 Cassandra 的主要担忧是,在 "normal" 列中,它们实际上会创建墓碑。但是由于我们没有将整个列设置为 NULL,而只是将元组中的一个元素(嵌套在映射中)设置为 NULL,因此情况并非如此。事实上,它们显示为 None。当我查看底层 SSTables 时,我也看不到已写入墓碑的证据。

通常,我会说明确地 INSERT 将 NULL 写入 Cassandra 是一个非常糟糕的想法。但在这种情况下,它不会给您带来任何问题。现在,至于这是否被认为是 "legit" 或一个好的做法......好吧,我的数据建模感觉不赞成。我会找到另一种方法来表示元组类型中缺少值,因为有人(跟随您的开发人员)可以看到这一点并将其解释为 "ok" 明确地 INSERT NULLs 到其他列值。