通过 C# 更改 Cassandra 表的正确方法

Posted

技术标签:

【中文标题】通过 C# 更改 Cassandra 表的正确方法【英文标题】:A correct way to alter Cassandra table via C# 【发布时间】:2019-09-23 20:49:27 【问题描述】:

我的问题在下一个。

我的代码中有下一个简单模型:

public class Client

    public Guid Id  get; set; 

    public string Name  get; set; 

我为它定义了一个映射:

public class CustomMappings : Mappings

    public CustomMappings()
    
        For<Client>().TableName("clients")
                     .PartitionKey(x => x.Id);
    

我通过Table&lt;TEntity&gt;.CreateIfNotExist()方法创建了表格:

var table = new Table<Client>(session);
table.CreateIfNotExists();

我可以通过以下方式插入我的数据:

IMapper mapper = new Mapper(session);

var client = new Client

    Id = Guid.NewGuid(),
    Name = "John Smith"
;

await mapper.UpdateAsync(client);

在此之后,我通过添加一个新属性更改了我的模型:

public class Client

    public Guid Id  get; set; 

    public string Name  get; set; 

    public string Surname  get; set; 

我需要更改此表,因为我想在其中添加 surname 列。 当然,当我尝试插入一个值时,我有一个例外:

Cassandra.InvalidQueryException: Undefined column name surname
   at Cassandra.Requests.PrepareHandler.Prepare(PrepareRequest request, IInternalSession session, Dictionary`2 triedHosts)
   at Cassandra.Requests.PrepareHandler.Prepare(IInternalSession session, Serializer serializer, PrepareRequest request)
   at Cassandra.Session.PrepareAsync(String query, IDictionary`2 customPayload)
   at Cassandra.Mapping.Statements.StatementFactory.GetStatementAsync(ISession session, Cql cql, Nullable`1 forceNoPrepare)
   at Cassandra.Mapping.Mapper.ExecuteAsync(Cql cql)

但是Cassandra.Data.Linq.Table&lt;TEntity&gt; 类既不包含.AlterOrCreate() 也不包含.Alter() 方法。另外,我们在Cassandra.Mapping.Statements.CqlGenerator 中没有.GetAlter() 方法。

哪种方式更适合解决这个问题?我有两个假设(除了使用所需的方法创建一个拉取请求以在 github 上对 csharp 驱动程序存储库进行 datastax :))。

    通过 .cql 文件中的 cql 脚本更改表,该脚本将在 c# 代码中执行。 在每次更改模型后创建一个新表并将旧数据迁移到该表。

我是 Cassandra 的新手,我怀疑库中不存在所需的方法是有充分理由的。可能是因为Cassandra是分布式数据库,修改后一致性有问题吗?

【问题讨论】:

【参考方案1】:

Cassandra 架构的更改应该非常准确 - 您对它的分布式特性是正确的,并且在进行更改时需要考虑到这一点。通常建议仅通过一个节点进行更改,并且在执行任何 DDL 语句(create/drop/alter)后,您需要检查架构协议(例如,通过 Metadata 类的 method CheckSchemaAgreementAsync),并且不要t 执行下一条语句,直到模式一致。

谈论更改本身 - 我不确定 C# 驱动程序是否能够自动生成架构更改,但您可以将更改作为 CQL 命令执行,如documentation 中所述(请仔细阅读限制!) .架构的变化可以分为 2 组:

    这可以应用于表而无需迁移数据 这将需要创建具有所需结构的新表并迁移数据。

在第一组中,我们可以进行以下操作(可能不是完整列表):

向表中添加新的常规列 从表中删除常规列 重命名聚类列

第二组包括其他所有内容:

更改主键 - 在其中添加或删除列 重命名非聚集列 更改列的类型(确实建议创建具有所需类型的全新列,复制数据,然后删除原始列 - 不建议使用不同类型的相同名称,因为这可能会使您的数据无法访问)

数据迁移可以通过不同的工具来完成,它可能取决于具体的要求,比如类型更改等。但这是另一回事。

【讨论】:

非常感谢您的详细回复!

以上是关于通过 C# 更改 Cassandra 表的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

是否需要 LB 优先于 Cassandra C# 驱动程序中的内置策略? [关闭]

如何在 cassandra 中追溯列族的大分区

从 Cassandra 填充缓存的正确方法

通过压缩和修复从 Cassandra db 中删除大量数据后,磁盘空间未更改

使用 Spring Data 中的 CassandraRepository 为 Cassandra 实现分页的正确方法

c# cassandra DataStax驱动版本兼容性