苏州知名高端网站建设企业做网站图结构

张小明 2025/12/31 4:36:34
苏州知名高端网站建设企业,做网站图结构,网站建设 部署与发布题库,建设化工网站的功能2#xff09;、开发测试环境使用的数据库版本与生产环境的数据库不同#xff0c;例如开发测试环境使用的是数据库的“开发版”、社区版#xff0c;或者较低的版本#xff0c;生产环境用的是企业版、最新的版本#xff1b;这样做自然也是为了降低开发成本#xff0c;比如开…2、开发测试环境使用的数据库版本与生产环境的数据库不同例如开发测试环境使用的是数据库的“开发版”、社区版或者较低的版本生产环境用的是企业版、最新的版本这样做自然也是为了降低开发成本比如开发环境用金仓V8版本而线上用的是最新的金仓V9版本。3、国产化要求需要将之前运行在MySQL、Oracle、SQLServer等数据库上的数据迁移到金仓、达梦等国产数据库上国产化要求是现在很多政府类项目的硬性要求软件公司之前成熟的产品用的是非国产化数据库现在都有数据迁移需求。4、提高数据库性能和数据备份的要求线上一些系统运行时间长产生的很多历史数据需要迁移到其它数据库上以便给线上的数据库“瘦身”起到一个数据备份和提高线上系统查询效率的作用比如一些日志数据、报警数据可以把归档后的数据迁移到新的数据库上。在国产数据库领域金仓数据库算是比较常用的一种数据库了号称百分百兼容Oracle的也基本百分百兼容MySQL等数据库能“无缝”迁移。金仓等国产数据库在兼容性这方面的确很努力如果这事不努力国人为什么要用你的数据库在实际使用过程中的确感觉不到兼容性问题但在做数据迁移的时候才发现在兼容性方面还是有一些问题而金仓提供的数据迁移工具对于非资深用户而言还是有较高的门槛每次遇到问题都不得不求助于金仓的技术支持人员每次寻求他们支持都要沟通很久于是我决定自己手搓一个数据库迁移工具而且还能反向迁移即从金仓迁移到MySQL等各种数据库而不是金仓自己的工具只能从OracleSQL Server,MySQL,PostgreSQL这几种数据库迁移到金仓。关于数据迁移以前工作中经常进行因此积累了一定的经验而且还把这些经验写到《SOD框架“企业级”应用数据架构实战》这本书里面了。下面介绍一下怎么使用SOD框架手搓一个数据迁移工具开始之前必须先了解数据迁移有哪些问题才能明白手搓一个自己的迁移工具的好处。数据迁移的常见问题数据迁移并不是一个简单的工作虽然很多数据库都提供了将别的数据库迁移过来的数据迁移工具但使用的时候还是会遇到很多问题第一个问题是数据量很大我们往往希望把一个有几百万行、几千万行的表数据从一个小型数据库迁移到一个大中型的数据库中比如把一个单机MySQL数据库中的数据迁移到金仓数据库集群中或者将上百万的数据迁移到历史数据库中存档给原来的库瘦身。第二个问题就是不同类型数据库之间进行迁移比如从MySQL迁移到金仓、从金仓迁移到Oracle由于源数据库和目标数据库类型不同它们支持的字段类型、表类型甚至SQL语法都有差异。有些数据库厂商从商业上考虑可能只愿意提供将别的数据库迁移到自家数据库来的功能而不支持反向迁移。第三个问题是同一种数据库不同版本之间进行数据迁移。按理说数据库不同版本之间应该保持兼容至少是高版本兼容低版本的但国产数据库很牛它不同版本之间的数据类型是可能不兼容的导致数据无法直接迁移这个问题让我明白了金仓数据库迁移工具为何使用起来那么复杂。第四个问题是数据迁移过程可能还伴随数据筛选、数据清洗和转换这个属于ETL的范畴了有一些成熟的ETL工具可以使用但这些工具使用复杂并且不一定免费。接下来我们自己手搓迁移工具时看怎么解决上面这些问题。迁移方案设计迁移的数据量很大所以不能读取太多的数据到内存最好从源数据读取一部分就写入目标数据库一部分数据不同种类数据库之间进行数据迁移由于数据库之间SQL语法、字段类型有差异所以最好不要直接采用编写SQL语句的方式来实现用ORM框架可以完美解决这个问题数据库不同版本之间的数据迁移注意采用兼容的数据类型即可如果不能兼容也有办法第四个问题好办了由于是自己手搓的工具迁移前后可以自定义自己的处理逻辑进行数据筛选、清洗和转换工作都不在话下了。根据这个迁移方案采用SOD框架来实现是很合适的它的一些特性解决这些问题具有很大优势下面我们逐个介绍怎么实现。准备工作首先我们需要明确源数据库和目标数据库的类型、版本数据库连接信息要迁移的表和视图数据。比如本文的例子以从金仓数据库迁移到MySQL数据库为例使用VS先创建一个控制台项目目标框架选择.NET8然后项目中添加两个Nuget包在目文件中添加下面的包引用代码PackageReference IncludePWMIS.SOD.Kingbase.Provider.Net6V9 Version6.0.1 /PackageReference IncludePWMIS.SOD.MySQL.Provider Version6.0.3 /或者使用Nuget包管理工具查找 PWMIS.SOD 关键字然后安装SOD框架的金仓数据库访问提供程序和MySQL数据库访问提供程序Install-Package PWMIS.SOD.Kingbase.ProviderInstall-Package PWMIS.SOD.MySQL.Provider然后在解决方案资源管理器选择项目名称右键菜单“添加-新建项-常规”然后选择“应用程序配置文件”添加一个 app.config文件内容如下View Code有关如何配置连接字符串的详细内容请移步框架的Nuget下载页面NuGet Gallery | PWMIS.SOD 6.0.3注意金仓数据库访问程序的选择不同版本有点差异可以移步SOD的金仓数据库Nuget下载页面详细了解NuGet Gallery | PWMIS.SOD.Kingbase.Provider 6.0.7到此使用SOD框架开发数据迁移工具的准备工作已经完成下面正式开始编写实现代码。创建目标数据库数据迁移通常都是目标数据库已经存在的情况下进行的但这里为什么要强调创建目标数据库呢这是因为很可能既有的目标数据库的数据表和表字段与源数据库是不兼容的比如目标数据库的字符编码是UTF8而源数据库是GB2312目标表的字段类型是int而源表字段的类型是long,或者表字段都是varchar类型但是源表和目标表该字段的长度却不相同当然更夸张的是连字段名都可能不相同字段业务含义是一样的这些千奇百怪的问题只有你想不到没有你遇不到的。所以最佳办法是由迁移工具自动创建一个目标数据库。SOD框架的Code First方案可以由实体类创建表它在第一次连接数据库的时候检查表是否存在如果不存在才创建表如果表已经存在则跳过以避免意外更改表结构。实现此过程很简单只需要继承DbContext即可比如对于本文的目标数据库创建一个TargetDbContext类复制代码public class TargetDbContext : DbContext{public TargetDbContext () : base(TargetDb){}protected override bool CheckAllTableExists(){CheckTableExistsUserInfo();//创建其它表。。。return true;}}复制代码在上面的代码中DbContext类的构造函数参数值“TargetDb” 就是app.config中配置的连接名称重载方法CheckAllTableExists 中 CheckTableExists泛型方法的类型参数UserInfo是一个SOD实体类它可以根据实体类指定的表名称来创建目标表。这样当TargetDbContext类型的对象被实例化的时候就会自动创建好迁移数据的目标表了。迁移标识字段数据库的标识字段是用来唯一标识一行数据的主键就起到这种作用我们也使用带自增功能的字段做主键但自增字段不一定都是主键本文说的标识字段是数据库的自增标识列如SQLServer的IDENTITY 列MySQL 用 AUTO_INCREMENTOracle 用 SEQUENCE触发器或 IDENTITY 列PostgreSQL和金仓数据库也是用 SEQUENCE 并设置 DEFAULT nextval。SOD框架的Code First功能可以为各种数据库自动创标识列只需要实体类设置 Identity标识字段名即可示例代码如下复制代码public class UserInfo : EntityBase{public UserInfo(){TableName UserInfo;IdentityName ID; //标识字段PrimaryKeys.Add(ID); //主键}public int ID{get{return getPropertyint(ID);}set{setProperty(ID,value );}}public string Name{get{return getPropertystring(Name);}set{setProperty(Name,value ,50);}}}复制代码默认情况下自增字段IDENTITY / AUTO_INCREMENT / SERIAL在插入数据的时候不能直接插入值但在数据迁移的时候需要将自增字段的值也迁移过去除非自增字段没有被别的表在逻辑上引用。如果确实需要给自增列塞一个指定值必须显式关闭/绕过自增字段的这个机制操作完恢复自增字段的默认行为否则后续普通方式插入数据会出错。比如对于SQLServer数据库复制代码-- 1 允许手动插入自增字段值SET IDENTITY_INSERT dbo.UserInfo ON;-- 2 手动写值列清单必须显式写出INSERT INTO dbo.UserInfo (ID Name) VALUES (100, zhangsan);-- 3 恢复自增字段默认行为SET IDENTITY_INSERT dbo.UserInfo OFF;复制代码对于PostgreSQL和金仓数据库的默认模式PG模式下自增字段可以直接插入值只要插入的值与现有自增字段值不重复即可。SOD框架根据实体类是否设置IdentityName属性来决定插入数据的时候是否插入自增列的值所以在使用SOD框架迁移数据的时候除了要注意目标数据库对于自增字段的问题还需要设置IdentityName属性为空值我们定义一个 IImportable 接口来表示该实体类可以插入自增字段值public interface IImportable{void IgnoreIdentity();}修改前面的实体类将IdentityName设置为空复制代码public class UserInfo : EntityBase,IImportable{public public_AlarmsInfo(){TableName UserInfo;IdentityName ID; //标识字段PrimaryKeys.Add(ID); //主键}public void IgnoreIdentity(){IdentityName ;}public int ID{get{return getPropertyint(ID);}set{setProperty(ID,value );}}public string Name{get{return getPropertystring(Name);}set{setProperty(Name,value ,50);}}}复制代码采用这种方式在运行时修改IdentityName 属性值既可以享受到Code First自动创建目标表的便利又可以实现插入自增列数据的功能注意迁移完自增列数据后需要重置自增列的标识数据到最大的自增列值这样后续插入数据才不会出问题。对于金仓数据库迁移完成当前表的数据后可以用下面的方式重置自增列的标识数据复制代码//entity 是当前正在迁移的表对于的SOD实体类对象if (targetDb.CurrentDBMSType PWMIS.Common.DBMSType.Kingbase){//更新序列值ALTER SEQUENCE equipment_id_seq RESTART WITH 100;string tableName entity.GetTableName();string sql $ALTER SEQUENCE {tableName.ToLower()}_id_seq RESTART WITH {max_id 1};targetDb.ExecuteNonQuery(sql);}复制代码另外一种可选方式是在数据库上直接将原来的标识字段修改为普通字段然后在实体类构造函数里面注释掉 IdentityName 这行字段即可但用这种方式来进行Code First模式开发无法自动创建自增列但可以等数据迁移完成后再手动设置自增标识。大数据量查询一次性在内存中加载10万条数据很可能导致进程无法正常运行而且这种大数据也会导致.NET内存难以有效回收而大表数据迁移又是很常见的事情所以最佳方案是数据逐条读取读一部分写一部分避免将大量数据读取到内存后再写入这样可以加快迁移速度。SOD框架的实体类查询支持这种“迭代器查询”通过调用EntityQueryT.QueryEnumerable方法复制代码static void DataMigrationT(AdoHelper sourceDb,AdoHelper targetDb,ActionT action, string identityNameID) where T : EntityBase, new(){//其它代码略var oql OQL.FromT().END;var readQuery EntityQueryT.QueryEnumerable(oql, sourceDb);var insetQuery new EntityQueryT(targetDb);foreach (var item in readQuery){action(item);//写入数据到目标数据库代码暂略}//其它代码略}复制代码QueryEnumerable 方法通过DataReader对象循环读取数每次只返回一个读取的实体类对象从而避免了一次读取大量数据的问题。数据复制广义的数据复制是将读取的数据写入到目标数据库但这里说的数据复制是将上面读取的数据复制到一个新的对象里面。虽然理论上可以将从源数据库读取的实体类直接写入到目标数据库但数据迁移的环境可能比较复杂比如源数据库和目标数据库是不同类型的数据库或者虽然类型一样但是版本不一样或者字段名称不一样甚至字段类型都不完全一样另外一个原因是SOD实体类的设计与市面上绝大部分ORM都不同SOD实体类采用值数组的方式存储从数据库读取的原始值这些值可能携带了数据驱动程序特定的类型信息而这种类型可能与目标数据库的类型是不兼容的比如日期类型MySQl驱动程序有自己的日期子类型金仓数据库驱动程序也有自己的日期子类型甚至不同版本的金仓数据库日期子类型还有微小的差异所以数据迁移的时候最好消除源数据库读取字段的特定的类型信息直接使用.NET的数据类型然后让数据库驱动程序根据.NET数据类型转换到目标数据库支持的数据类型。驱动程序数据类型转换的问题比较复杂这里不细究。针对不同的数据复制场景SOD有不同的支持方案最通常的方案是直接调用实体类的MapForm方法做数据映射拷贝复制代码var insetQuery new EntityQueryT(targetDb);foreach (var item in readQuery){T targetEntity new T();targetEntity.MapFrom(item,false);targetEntity.ResetChanges(true);//其它代码略}复制代码上面代码中MapFrom方法表示从任意一个实例对象中拷贝与当前实体类同名属性的值到当前实体类中ResetChanges方法强行设置所有属性的修改状态是否修改SOD框架会根据实体类属性是否修改是否进行过赋值操作来决定是否将该属性的值更新或者插入到数据库中。除了调用上面的两个方法直接使用SOD的扩展方法CopyTo方法也可以实现类似的效果foreach (var item in readQuery){T targetEntity new T();item.CopyTo(targetEntity);}但是使用上面的方式都没法复制源数据库表字段的NULL值这个功能对SOD框架来说很简单复制代码foreach (var item in readQuery){T targetEntity new T();item.CopyTo(targetEntity);for (int i 0; i item.PropertyValues.Length; i){if (item[i] DBNull.Value){targetEntity.PropertyValues[i] DBNull.Value;}}}复制代码上面的代码中item是源数据库的实体类对象targetEntity是目标数据库的实体类对象SOD的实体类具有索引器功能可以通过索引访问属性值也可以通过索引直接修改实体类的属性值这样就可以为属性设置NULL值。实体类的这种访问方式是绝大部分ORM框架都不支持的功能这个功能为SOD框架处理数据带来了极大的便利性。批量插入目标数据库的写入是数据迁移过程中最慢的操作批量插入能大大提高插入操作的性能很多数据库都有一次性插入多条数据的功能其中大多支持下面这种方式复制代码INSERT INTO 表名 (列1, 列2, …)VALUES(值1_1, 值1_2, …),(值2_1, 值2_2, …),…(值n_1, 值n_2, …);复制代码SOD框架对于MySQL和金仓数据库采用了这种方式进行批量插入对于SQLServer采用了SqlBulkCopy方案。只要支持批量插入都可以调用QuickInsert方法InsertListDataT(ListT targetList, EntityQueryT insetQuery) where T : EntityBase, new(){int importedCountinsetQuery.QuickInsert(targetList);return importedCount;}如果数据库不支持批量插入也可以使用EntityQuery对象的Insert重载方法插入一个实体列表对象内部使用事务等方式优化插入性能。进度信息数据迁移可能耗时比较长迁移过程中实时显示迁移进度是必要的我实现了一个ConsoleProcessDisplayer类效果类似Linux系统中下载文件的命令行进度显示方式下面直接给出主要代码View Code下面是模拟显示进度的代码调用方法复制代码int recordCount 3721;Console.WriteLine(【模拟】开始处理数据);ConsoleProcessDisplayer displayer new ConsoleProcessDisplayer(recordCount);Console.WriteLine(插入记录数);displayer.Begin();for (int i 0;i recordCount; i){displayer.DisplayProcessing(i);System.Threading.Thread.Sleep(10);}displayer.DisplayProcessing(recordCount);displayer.End();
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

程序员做网站给女朋友那个网站做足球测

Unity内置着色器终极指南:从入门到精通 【免费下载链接】Unity-Built-in-Shaders Unity-Built-in-Shaders:提供了Unity游戏引擎内置着色器的非官方代码仓库,对使用Unity进行游戏开发的程序员有帮助。 项目地址: https://gitcode.com/gh_mir…

张小明 2025/12/28 15:50:25 网站建设

2017网站发展趋势网络公司是干什么的

大模型落地加速:15158精选资源清单助力开发者攻克技术难关 【免费下载链接】LongAlign-7B-64k 项目地址: https://ai.gitcode.com/zai-org/LongAlign-7B-64k 在人工智能技术迅猛发展的浪潮中,大语言模型(LLM)正经历着从实…

张小明 2025/12/28 15:49:15 网站建设

网站登录页面盗号怎么做三明建设网站

课题摘要基于 JavaWebSpringBoot 的校园集市二手物品交易管理系统,直击 “校园二手信息杂乱、交易流程无保障、物流对接不畅” 的核心痛点,依托 JavaWeb 的跨平台特性与 SpringBoot 的高扩展性,构建 “校园专属 安全可信 便捷高效” 的二手…

张小明 2025/12/28 15:48:39 网站建设

jq插件网站重庆市住房和城乡建设信息网官网

Java代码安全卫士:Momo安全审计插件5分钟极速上手指南 【免费下载链接】momo-code-sec-inspector-java IDEA静态代码安全审计及漏洞一键修复插件 项目地址: https://gitcode.com/gh_mirrors/mo/momo-code-sec-inspector-java 项目速览 Momo Code Sec Inspec…

张小明 2025/12/28 15:48:04 网站建设

网站开发个性化wordpress 产品目录

在数字化转型的浪潮下,全球外卖市场规模预计将在2025年突破2000亿美元。与国内市场不同,海外外卖平台面临多语言支持、跨境支付、税务合规、文化差异等复杂挑战。作为拥有二十年开发经验的PHP全栈架构师,我将深入解析如何基于PHP技术栈构建高…

张小明 2025/12/28 15:47:29 网站建设

照片书哪家网站做的好网站建设胶州家园

想要在年会、活动中打造惊艳的抽奖环节吗?Magpie-LuckyDraw作为一款支持Windows、Mac、Linux、Web和Docker全平台的开源抽奖系统,让每个人都能轻松成为抽奖大师。无论你是技术小白还是资深用户,这套系统都能满足你的各种需求。 【免费下载链接…

张小明 2025/12/28 15:46:54 网站建设