在 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 到其他列值。
我必须在 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 到其他列值。