RowVersion字段从SqlServer到PostgreSQL的迁移

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RowVersion字段从SqlServer到PostgreSQL的迁移相关的知识,希望对你有一定的参考价值。

SQL Server 有个列是rowversion,之前是timestamp,因此这两个关键字在SQL server中是同义词,不过目前timestamp处在废弃阶段,因此我们最好使用rowversion来代替它。而在数据库迁移时,因为使用到该类型,因此要考虑怎么迁移它。

  • 📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!

  • 📢本文作者:由webmote 原创,首发于 【CSDN】

  • 📢作者格言:生活在于折腾,当你不折腾生活时,生活就开始折腾你,让我们一起加油!💪💪💪

1. SQL Server中 RowVersion的含义

Timestamp/rowversion 是一个EF Core属性,在每次插入或更新数据行时,数据库会自动为其生成新值。

因此此属性也被视为并发标记,这确保了在你查询行后,如果正在更新的行发生了更改,则会出现异常。可以参考之前的数据库乐观锁介绍。

对于 SQL Server,通常使用 byte [] 属性,该属性将设置为数据库中的 ROWVERSION 列。

代码如下:

public class Blog 
    public int BlogId get; set;  
    public string Url  get; set; 
    1637552921
    public byte[] Timestamp  get; set; 

当然也可以是在 OnModelCreating 内设置

internal class MyContext : DbContext

    public DbSet<Blog> Blogs  get; set; 

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    
        modelBuilder.Entity<Blog>()
            .Property(p => p.Timestamp)
            .IsRowVersion();
    


public class Blog

    public int BlogId  get; set; 
    public string Url  get; set; 
    public byte[] Timestamp  get; set; 

注意: 如果需要映射到ulong,需要使用转换函数HasConversion

modelBuilder.Entity<Blog>()
            .Property(p => p.Timestamp)
            .IsRowVersion().HasConversion<int>();

在SQL Server里,RowVersion是一种自增的只用于定义数据表的列类型,其值占用的大小是固定的8个字节,是SQL Server数据库自动生成的、数据库级别唯一的、二进制数字,使用binary(8)存储。

1.1 递增原理介绍

每个数据库都有一个自增的计数器,该计数器是Database RowVersion,在用户对有RowVersion 字段的数据表执行插入或修改命令时,该计数器就会增加。

可以使用全局变量 @@DBTS 进行查询其值, 该值在整个数据库中是唯一的、递增的,不可回滚的。

select @@DBTS;

当然对于一个数据表,最多有一个RowVersion 字段。

1.2 RowVersion字段的特性

  1. 每个数据库只有一个计数器,因此所有拥有RowVersion字段的数据表,其值都是不同的;

  2. 数据库的RowVersion 只会递增,不会回滚;

  3. 由数据库自动赋值(插入,修改),不能显式赋值;

2. PostgreSQL 有无Timestamp/RowVersion

PostgreSQL中具有Timestamp类型,其是日期时间字段,并不能直接转为SQL Server的RowVersion/Timestamp类型。

与RowVersion行为最为接近的列类型,是PostgreSQL中用于MVCC管理的 xmin隐藏列,这个列每个表系统都会自动建立,因此无需增加。当然还有其他隐藏列,比如xmax,xmin表示插入该表的事务号,xmax表示删除该表的事务号。

唯一的瑕疵是使用xmin作为行版本标识不能区别同一个事务内的两次、多次修改。当然事务内的第一次修改对其他事务不可见,唯一能看见它的只有修改这一行的事务自己。

在EF中我们可以采用下列实体定义,以便支持xmin列。

1637552921
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
[Column("xmin", TypeName = "xid")]
public uint Rowversion  get; set; 

当然,也可以在OnConfiguring里写语句。

builder.Entity<EmailAddressValidation>()
.Property(e => e.RowVersion).IsRowVersion().HasColumnName("xmin").HasConversion<int>();

检查数据库数据,OK,是那么的回事了。

3. 小结

rowversion字段还是挺有意思的,你学废了吗?

👓都看到这了,还在乎点个赞吗?

👓都点赞了,还在乎一个收藏吗?

👓都收藏了,还在乎一个评论吗?

以上是关于RowVersion字段从SqlServer到PostgreSQL的迁移的主要内容,如果未能解决你的问题,请参考以下文章

RowVersion字段从SqlServer到PostgreSQL的迁移

RowVersion字段从SqlServer到PostgreSQL的迁移

是否可以使用实体框架将 SQL Server 的 rowversion 类型映射到比 byte[] 更友好的东西?

RowVersion 用法

SQL MIN_ACTIVE_ROWVERSION() 值长时间不变

Microsoft SQL Server Management Studio 说 RowVersion 是无效类型