我有一个 Cassandra 客户表,用于保存客户列表。每个客户都有一个地址,它是标准字段的列表:
{
CustomerName: "",
etc...,
Address: {
street: "",
city: "",
province: "",
etc...
}
}
我的问题是,如果此表中有 100 万个客户,并且我使用用户定义的数据类型 Address 来保存 Customers 表中每个客户的地址信息,这种模型的含义是什么,特别是在磁盘空间方面。这会非常昂贵吗?我应该使用地址用户定义的数据类型还是扁平化地址信息,甚至使用单独的表?
基本上,在这种情况下,Cassandra 会将地址实例序列化为 Blob,该 Blob 存储为单列,作为客户表的一部分。我手头没有任何关于序列化将在磁盘或 CPU 使用率上增加多少的数字,但它可能不会对您的用例产生很大的影响。您应该测试这两种情况以确定。
编辑:我还应该提到的另一个方面:将 UDT 作为单个 blob 处理意味着要替换任何更新的完整 UDT。这比更新单个列的效率要低,并且是导致不一致的潜在原因。在并发更新的情况下,两个写入可能会覆盖彼此的更改。请参阅CASSANDRA-7423。
使用 Cassandra 5,在我们的测试场景中,我们比较了带/不带 UDT 的表模式。 UDT 版本:
所以我确实认为差异可能足够大。 不过,我也建议您为自己进行基准测试,因为您的里程可能会有很大差异。
为了完整起见,这里是我们比较的架构规范:
CREATE KEYSPACE smmv
WITH replication = {'class': 'NetworkTopologyStrategy', 'xxx': '3'}
AND durable_writes = true;
CREATE TABLE smmv.sm1 (
meter_id uuid,
year tinyint,
time timestamp,
sensor_value1 bigint,
... same for 2-11
sensor_value12 bigint,
PRIMARY KEY ((meter_id, year), time)
) WITH CLUSTERING ORDER BY (time ASC)
create type smmv.mv_udt (
v1 bigint,
... same for 2-11
v12 bigint
);
create table smmv.udt1 (
meter_id UUID,
year tinyint,
time timestamp,
measurement FROZEN<mv_udt>,
PRIMARY KEY ((meter_id, year), time)