最近一直在忙公司里的SDC to PDC Data Migartion项目。原来服务亚太区业务的新加坡物流配送中心要迁移到马来西亚槟城。信息系统中的不少数据需要配合这次迁移做相应的修改,涉及销售订单(Sales Order)、采购订单(Purchase Order)和库存(Inventory)。在与商务分析员的讨论后,我们的方案中有很大一部分数据修改需要在数据库端写脚本完成。前段时间一直在讨论方案、设计逻辑、撰写脚本,到现在脚本基本完成了。在这个过程中,零零星星有些收获,在这里整理一下,作为备忘。

业务需求

新加坡物流配送中心(SDC)为Asean,Shanghai,Taiwan,Korea分公司提供仓储管理与物流配送服务。现在新加坡物流配送中心(SDC)要迁移至槟城(PDC),如下图所示:

数据迁移需要在SDC到PDC切换的时间点一次性完成。

所要做的数据修改按顺序如下:

Section One: Back Order and Un-reserve

1.各分公司把从SDC发货且已经产生ship但未shipconfirm(即还未生成Inventory)的订单做Back Order

2.各分公司把从SDC发货且已经reserve到货的订单做unreserve

Section Two: Open SO Migration

3.各分公司把从SDC发货的订单转到从PDC发货

  • 对于从SDC发货的完全Open的订单(即订单中的每一条SOItem都未发货或关闭),直接修改订单的SubInventory信息,使用PDC相应的SubInventroy
  • 对于从SDC发货的部分Open的订单(即订单中有些SOItem已经发货或关闭),生成新的从PDC发货的订单(包含那些未发货或关闭的SOItem),Cancel之前SDC的SOItem

Section Three: Open Inventory Migration

4.对于在SDC中的所有当前库存(Inventory)生成销售订单(SalesOrder),发货方为PDC

5.在PDC端创建采购订单(PurchaseOrder),把SDC发出的货物收回PDC仓库

Section Four: Open PO Migration

6.关闭所有SDC的采购订单

开发所得

整个代码非常冗长,贴在这里意义不大。对于其中几个有意思的点,在这里分析一下。

1.分布式数据修改

这次的数据Migration牵扯多个分公司的数据库,而且其中有些表有同步关系(即要保持一致)。

所以经常会有如下场景:在修改某数据库中某表的数据,要把这些修改分发到处于异地的其他数据库中的同步表中。举例来说:对Asean上Table_SalesOrder的数据修改需要分发给Asean、Shanghai、Taiwan、Korea上的同步表Table_SDCSalesOrder。

解决方案:

  • 最原始的方式是在SQL Server Management Studio中连接多个数据库,在其中一个数据库上进行数据修改之后,把结果集手工拷贝到其他数据库,再同步修改其他各库中的对应表。当需要同步的结果集很多时,这种方法相当繁琐。反复在不同数据库间切换并进行手工拷贝和同步修改容易出现错误。所以这个方案并不合适。
  • 在SQL Server中可以创建linked server进行异地SQL Server的数据查询、修改。创建linked sever如下例所示:
if not exists (select * from sys.servers srv where srv.name = N'sh-mis-xxin')
beginEXEC sp_addlinkedserver   @server=N'sh-mis-xxin', @srvproduct=N'SQL Server';EXEC sp_addlinkedsrvlogin@rmtsrvname=N'sh-mis-xxin',@useself=N'False',@locallogin=NULL,@rmtuser=N'UserName',@rmtpassword='Password';
end

用linked server是否能解决我们的问题呢?通过实验发现,当需要修改的远程表数据较多,或需要与远程大表进行连接时,linked server性能非常差。所以这个方案也未使用。

  • 使用SQL Server Integration Service(SSIS)是否能解决这个问题呢?我觉得肯定能,而且整个Data Migration都可以用SSIS工具完成。但SSIS用得不是很多,而且这次Data Migration的时间又非常紧,所以最终没有采用。我自己计划在项目后,用SSIS把这个Migration重新做一下。
  • 第四种方案是在Migration之前,把各个分公司的数据库进行备份压缩,拉到一台主机上并restore到一个SQL Server的instance中。在一个instance上不同数据库的访问是非常方便的,在此instance上进行Data Migration的所有操作。之后再把这些数据库还原回各个分公司。

我们最后选定了第四种方案,原因是各分公司的数据库并不大,而且我们每天都有计划性的数据备份压缩并拉回的维护操作。所以这种方式肯定是可行的。

2.Open SO Migration部分代码分析

Open SO Migration中有一步就是要生成新的销售订单(SalesOrder)和订单明细(SOItem),我们直接看代码:

--2.3.3 Copy the source order to the new order (OE2)
--2.3.3.1 Create New SO
create table #NewSO
(SO_ID int not null,SO_SourceID int not null
);insert into Table_SalesOrder
(Contact_ID,Customer_ID,Site_ID,SO_OrderDate,SO_OrderStatus,SO_CustomerPO,SO_OrderType,SO_RequestDate,SO_SalesPerson,SO_VAT,EndUserContact_ID,EndUserSite_ID,ShipToContact_ID,ShipToSite_ID,BillToContact_ID,BillToSite_ID,DeliveryToContact_ID,DeliveryToSite_ID,SO_PriceList,SO_CurrencyType,SO_LineSet,SO_PaymentTerm,SO_ShipPriority,SO_PaymentType,SO_ShippingMethod,SO_SalesChannel,SO_FreightTerm,SO_WinProbability,SO_IncoTerm,SO_SourceType,SO_SourceID,SO_WareHouse,SO_ShippingInstructions,SO_PackingInstructions,SO_CreatedBy,SO_CreatedAt,SO_ModifiedBy,SO_ModifiedAt,SO_Activity,SO_InvoicePrintoutType,SO_OrderNotes,SO_TaxStatus,SO_CForm,SO_OUID,SO_CFormReceived,SO_CFormReceivedBy,SO_CFormReceivedAt,SO_CFormNumber,SO_DCNo,SO_PONumber,SO_DCModifiedBy,SO_DCModifiedAt
)
outputinserted.SO_ID,inserted.SO_SourceID
into#NewSO
select distinctSO.Contact_ID,SO.Customer_ID,SO.Site_ID,SO.SO_OrderDate,SO.SO_OrderStatus,SO.SO_CustomerPO,SO.SO_OrderType,SO.SO_RequestDate,SO.SO_SalesPerson,SO.SO_VAT,SO.EndUserContact_ID,SO.EndUserSite_ID,SO.ShipToContact_ID,SO.ShipToSite_ID,SO.BillToContact_ID,SO.BillToSite_ID,SO.DeliveryToContact_ID,SO.DeliveryToSite_ID,SO.SO_PriceList,SO.SO_CurrencyType,SO.SO_LineSet,SO.SO_PaymentTerm,SO.SO_ShipPriority,SO.SO_PaymentType,SO.SO_ShippingMethod,SO.SO_SalesChannel,SO.SO_FreightTerm,SO.SO_WinProbability,SO.SO_IncoTerm,N'Order' as SO_SourceType,SO.SO_ID as SO_SourceID,case SO.SO_WareHousewhen 1018 then 1041when 1019 then 1042when 1026 then 1043when 1031 then 1044when 1040 then 1045 end as SO_WareHouse,SO.SO_ShippingInstructions,SO.SO_PackingInstructions,N'SDC to PDC Migration' as SO_CreatedBy,getdate() as SO_CreatedAt,N'SDC to PDC Migration' as SO_ModifiedBy,getdate() as SO_ModifiedAt,SO.SO_Activity,SO.SO_InvoicePrintoutType,SO.SO_OrderNotes,SO.SO_TaxStatus,SO.SO_CForm,SO.SO_OUID,SO.SO_CFormReceived,SO.SO_CFormReceivedBy,SO.SO_CFormReceivedAt,SO.SO_CFormNumber,SO.SO_DCNo,SO.SO_PONumber,SO.SO_DCModifiedBy,SO.SO_DCModifiedAt
from#NeedCreateSOItem NeedCreateSOIteminner joinTable_SalesOrder SOonNeedCreateSOItem.SO_ID = SO.SO_ID
wherecast(SO.SO_ID as nvarchar)+ cast((case SO.SO_WareHousewhen 1018 then 1041when 1019 then 1042when 1026 then 1043when 1031 then 1044when 1040 then 1045 end) as nvarchar)+ N'SDC to PDC Migration' not in (select cast(SO_SourceID as nvarchar) + SO_Warehouse + isnull(SO_CreatedBy, N'') from Table_SalesOrder);--2.3.3.2 Create New SOItem
create table #NewSOItem
(SOItem_ID int not null,SourceItem_ID int not null
);insert into Table_SOItem
(SO_ID,SOItem_LineMajor,SOItem_LineMinor,Product_PN,SOItem_Description,SOItem_Quantity,SOItem_ListPrice,SOItem_AdjustedPrice,SOItem_UnitPrice,SOItem_Discount,SOItem_RequestDate,SOItem_ScheduledShipDate,SOItem_PromiseDate,SOItem_LineSet,SOItem_Status,SOItem_ReservedQty,SOItem_CancelledQty,SOItem_ShippedQty,SOItem_ShippedDate,SOItem_ShippingMethod,SOItem_FreightTerm,SOItem_ShippingInstructions,SOItem_PackingInstructions,SOItem_WaybillNumber,EndUserSite_ID,EndUserContact_ID,DeliveryToSite_ID,DeliveryToContact_ID,SOItem_CreditReason,SOItem_CreditUnitPrice,SOItem_AcceptedQty,Invoice_ID_ToBeDelete,SOItem_ServiceStartDate,SOItem_ServiceEndDate,SOItem_ServiceRefType,SOItem_ServiceRefNo,SOItem_CreditQty,SOItem_CreatedBy,SOItem_CreatedAt,SOItem_ModifiedBy,SOItem_ModifiedAt,SourceItem_ID,SOItem_VAT,SOItem_BoundleParentItemID,SOItem_VATCategory,SOItem_AppendService,ItemPricingAttr_ID
)
outputinserted.SOItem_ID,inserted.SourceItem_ID
into#NewSOItem
selectNewSO.SO_ID,dense_rank() over(partition by SOI.SO_ID order by SOI.SOItem_LineMajor) as SOItem_LineMajor,row_number() over(partition by SOI.SO_ID,SOI.SOItem_LineMajor order by SOI.SOItem_LineMinor) as SOItem_LineMinor,SOI.Product_PN,SOI.SOItem_Description,SOI.SOItem_Quantity,SOI.SOItem_ListPrice,SOI.SOItem_AdjustedPrice,SOI.SOItem_UnitPrice,SOI.SOItem_Discount,SOI.SOItem_RequestDate,SOI.SOItem_ScheduledShipDate,SOI.SOItem_PromiseDate,SOI.SOItem_LineSet,SOI.SOItem_Status,SOI.SOItem_ReservedQty,SOI.SOItem_CancelledQty,SOI.SOItem_ShippedQty,SOI.SOItem_ShippedDate,SOI.SOItem_ShippingMethod,SOI.SOItem_FreightTerm,SOI.SOItem_ShippingInstructions,SOI.SOItem_PackingInstructions,SOI.SOItem_WaybillNumber,SOI.EndUserSite_ID,SOI.EndUserContact_ID,SOI.DeliveryToSite_ID,SOI.DeliveryToContact_ID,SOI.SOItem_CreditReason,SOI.SOItem_CreditUnitPrice,SOI.SOItem_AcceptedQty,SOI.Invoice_ID_ToBeDelete,SOI.SOItem_ServiceStartDate,SOI.SOItem_ServiceEndDate,SOI.SOItem_ServiceRefType,SOI.SOItem_ServiceRefNo,SOI.SOItem_CreditQty,N'SDC to PDC Migration' as SOItem_CreatedBy,getdate() as SOItem_CreatedAt,N'SDC to PDC Migration' as SOItem_ModifiedBy,getdate() as SOItem_ModifiedAt,SOI.SOItem_ID as SourceItem_ID,SOI.SOItem_VAT,SOI.SOItem_BoundleParentItemID,SOI.SOItem_VATCategory,SOI.SOItem_AppendService,SOI.ItemPricingAttr_ID
from#NeedCreateSOItem NeedCreateSOIteminner join#NewSO NewSOonNeedCreateSOItem.SO_ID = NewSO.SO_SourceIDinner joinTable_SOItem SOIonNeedCreateSOItem.SOItem_ID = SOI.SOItem_ID
where(cast(SOI.SOItem_ID as nvarchar) + SOI.Product_PN + N'SDC to PDC Migration')not in (select isnull(cast(SourceItem_ID as nvarchar), N'') + Product_PN + isnull(SOItem_CreatedBy, N'') from Table_SOItem);

如上代码中值得注意的有如下几点:

(1)insert语句中的output谓词,如下高亮处

由于Table_SalesOrder中的SO_ID列为identity列,所以在插入销售订单之前这些SO_ID都是未知的。但在下一步插入Table_SOItem时又需要引用这些SO_ID。这种情况下就可以使用output谓词从inserted虚表中得到新插入的SO_ID值。

(2)SO_SourceID的辅助作用

如上高亮显示处,我们output另一列SO_SourceID,其中的值为原先的SO_ID。SO_SourceID对于插入新的SOItem信息非常重要,我们是通过这列来找到原先对于的SOItem的,如下图所示

在我们这个例子中Table_SalesOrder中正好有一列SO_SourceID。但在有些表中没有类似的列,对于这种情况,可以先在原表上加一列存放该信息,在Migration之后再删除此列。

(3)用where条件来防止重复插入

在我们插入Table_SalesOrder和Table_SOItem时,我们加了where条件,如下高亮显示:

这些条件可以不加,但如果要使代码反复跑不会插入重复数据的话,就需要这些条件。这些条件是为了增加代码的健壮性。

需要注意的是,where条件中连接的值不能为null,否则会返回空集合。所以对于可能有null值的列需要用isnull进行转换。

(4)编号函数的使用

Table_SOItem有两个编号列,插入时需要重新编号,如下高亮显示

row_number()函数在做migration特别有用,大家也比较熟悉。对于dense_rank我们看一个小例子:

selectdense_rank() over(order by field1),*
fromTable_Temp
order byfield1;

3.Open Inventory Migration部分代码分析

Open Inventory Migration中有一步是要把SDC下有库存的货物全出成SalesOrder。Table_InventoryBalance中的每一条记录会对应到一条SOItem。但业务上要求是不能把所用SOItem都归入一个SalesOrder(一个SalesOrder中的SOItem不能太多),要求一个SalesOrder中包含100条SOItem。要满足如上要求先看代码:

--0.Create temp table for need migration SDC inventory
selectIB.*,null as SOID
into#NeedMigrateInventory
fromTable_InventoryBalance IBinner joinTable_SubInventory SIonIB.SubInventory_ID = SI.SubInventory_ID
whereSI.Warehouse_ID = 1003andIB.InvBalance_QtyOnHand > 0;--2.1.3 Insert SO Header
declare @MaxSOItemQty int;
set @MaxSOItemQty = 100;while exists(select * from #NeedMigrateInventory where SOID is null)
begin;With SubInventoryHasSDCInv as(selectSubInventory_IDfrom #NeedMigrateInventory whereSOID is nullgroup by SubInventory_ID)insert intoTable_SalesOrder(Contact_ID,Customer_ID,Site_ID,SO_OrderDate,SO_OrderStatus,SO_CustomerPO,SO_OrderType,SO_RequestDate,SO_SalesPerson,SO_VAT,EndUserContact_ID,EndUserSite_ID,ShipToContact_ID,ShipToSite_ID,BillToContact_ID,BillToSite_ID,DeliveryToContact_ID,DeliveryToSite_ID,SO_PriceList,SO_CurrencyType,SO_LineSet,SO_PaymentTerm,SO_ShipPriority,SO_PaymentType,SO_ShippingMethod,SO_SalesChannel,SO_FreightTerm,SO_WinProbability,SO_IncoTerm,SO_SourceType,SO_SourceID,SO_WareHouse,SO_ShippingInstructions,SO_PackingInstructions,SO_CreatedBy,SO_CreatedAt,SO_ModifiedBy,SO_ModifiedAt,SO_Activity,SO_InvoicePrintoutType,SO_OrderNotes,SO_TaxStatus,SO_CForm,SO_OUID,SO_CFormReceived,SO_CFormReceivedBy,SO_CFormReceivedAt,SO_CFormNumber,SO_DCNo,SO_PONumber,SO_DCModifiedBy,SO_DCModifiedAt    )outputinserted.SO_ID,inserted.SO_WareHouseinto#NewCreatedSOselectSOHeaderInfo.Contact_ID,SOHeaderInfo.Customer_ID,SOHeaderInfo.Site_ID,SOHeaderInfo.SO_OrderDate,SOHeaderInfo.SO_OrderStatus,SOHeaderInfo.SO_CustomerPO,SOHeaderInfo.SO_OrderType,SOHeaderInfo.SO_RequestDate,SOHeaderInfo.SO_SalesPerson,SOHeaderInfo.SO_VAT,SOHeaderInfo.EndUserContact_ID,SOHeaderInfo.EndUserSite_ID,SOHeaderInfo.ShipToContact_ID,SOHeaderInfo.ShipToSite_ID,SOHeaderInfo.BillToContact_ID,SOHeaderInfo.BillToSite_ID,SOHeaderInfo.DeliveryToContact_ID,SOHeaderInfo.DeliveryToSite_ID,SOHeaderInfo.SO_PriceList,SOHeaderInfo.SO_CurrencyType,SOHeaderInfo.SO_LineSet,SOHeaderInfo.SO_PaymentTerm,SOHeaderInfo.SO_ShipPriority,SOHeaderInfo.SO_PaymentType,SOHeaderInfo.SO_ShippingMethod,SOHeaderInfo.SO_SalesChannel,SOHeaderInfo.SO_FreightTerm,SOHeaderInfo.SO_WinProbability,SOHeaderInfo.SO_IncoTerm,SOHeaderInfo.SO_SourceType,SOHeaderInfo.SO_SourceID,SDCInv.SubInventory_ID SO_WareHouse,SOHeaderInfo.SO_ShippingInstructions,SOHeaderInfo.SO_PackingInstructions,SOHeaderInfo.SO_CreatedBy,SOHeaderInfo.SO_CreatedAt,SOHeaderInfo.SO_ModifiedBy,SOHeaderInfo.SO_ModifiedAt,SOHeaderInfo.SO_Activity,SOHeaderInfo.SO_InvoicePrintoutType,SOHeaderInfo.SO_OrderNotes,SOHeaderInfo.SO_TaxStatus,SOHeaderInfo.SO_CForm,SOHeaderInfo.SO_OUID,SOHeaderInfo.SO_CFormReceived,SOHeaderInfo.SO_CFormReceivedBy,SOHeaderInfo.SO_CFormReceivedAt,SOHeaderInfo.SO_CFormNumber,SOHeaderInfo.SO_DCNo,SOHeaderInfo.SO_PONumber,SOHeaderInfo.SO_DCModifiedBy,SOHeaderInfo.SO_DCModifiedAt  from#SOHeaderInfo SOHeaderInfo,SubInventoryHasSDCInv SDCInv;With InvWithRN as(selectNeedMigrateInventory.InvBalance_ID,NewCreatedSO.SO_ID,row_number() over(partition by NeedMigrateInventory.SubInventory_ID order by NeedMigrateInventory.InvBalance_ID) as rnfrom#NeedMigrateInventory NeedMigrateInventoryinner join#NewCreatedSO NewCreatedSOonNeedMigrateInventory.SubInventory_ID = NewCreatedSO.SO_WareHousewhereNeedMigrateInventory.SOID is null)updateNeedMigrateInvsetNeedMigrateInv.SOID = InvWithRN.SO_IDfrom#NeedMigrateInventory NeedMigrateInvinner joinInvWithRNonNeedMigrateInv.InvBalance_ID = InvWithRN.InvBalance_IDwhereInvWithRN.rn <= @MaxSOItemQty;   truncate table #NewCreatedSO;
end

这段逻辑的主体思路是:把将转化为SOItem的Table_InventoryBalance相应记录放入临时表#NeedMigrateInventory中,并在临时表中加一辅助列SOID。在其后生成SalesOrder后,把生成的SO_ID放入辅助列SOID中。其中每个SalesOrder只有100条记录的要求是通过加row_number()辅助信息做到的。

转载于:https://www.cnblogs.com/DBFocus/archive/2010/08/27/1809900.html

配送中心数据迁移项目(SDC to PDC Data Migartion)相关推荐

  1. 美团脱颖而出的经验_使数据科学项目脱颖而出的6种方法

    美团脱颖而出的经验 The global COVID-19 pandemic has left many with a lot of time on their hands to work on th ...

  2. 大数据介绍项目流程_大数据介绍

    大数据介绍项目流程 About Big Data 关于大数据 什么是大数据?(What is Big Data?) In modern world, there are many big proble ...

  3. 如何将旧电脑数据迁移到新电脑?10 款数据迁移软件工具分享

    最好的数据迁移软件可以自动完成将数据从一个系统传输到另一个系统的过程.人们使用数据迁移软件的最常见原因是当他们从一个应用程序切换到另一个应用程序时. 10 款数据迁移软件 公司或个人出于各种原因移动数 ...

  4. zookeeper数据迁移

    zookeeper数据迁移 zookeeper目录下的data文件夹中的version-2 包含了log snop acceptedEpoch currentEpoch log是全量日志 snop是增 ...

  5. Atlassian data migrate 数据迁移

    Atlassian data migrate 数据迁移 数据迁移 在 Atlassian 的用户来看,都是让人觉得充满风险及工程艰巨的任务,但其实这个工作,在运维期间的各种场景会发现,数据迁移其实是一 ...

  6. 后盾网lavarel视频项目---1、数据迁移

    后盾网lavarel视频项目---1.数据迁移 一.总结 一句话总结: 1.lavarel的数据迁移比较简单,就是用php来创建数据表 2.创建迁移文件:php artisan make:migrat ...

  7. ssh项目同时使用mysql跟sqlserver数据库_MSSQL_如何把sqlserver数据迁移到mysql数据库及需要注意事项,在项目开发中,有时由于项目 - phpStudy...

    如何把sqlserver数据迁移到mysql数据库及需要注意事项 在项目开发中,有时由于项目开始时候使用的数据库是SQL Server,后来把存储的数据库调整为MySQL,所以需要把SQL Serve ...

  8. 数据中心安全风控_平安银行Hadoop集群跨数据中心迁移项目告捷项目骨干专访

    Hadoop集群跨数据中心迁移 平安银行东莞数据中心建成 平安银行科技中心零售大数据团队 平安银行科技中心科技运营中心 群迁告捷 经过平安银行科技运营中心和大数据团队的不懈努力,作为平安银行AI战略转 ...

  9. 项目案例之GitLab的数据迁移

    项目案例之GitLab的数据迁移 链接:https://pan.baidu.com/s/1CgaEv12cwfbs5RxcNpxdAg 提取码:fytm 复制这段内容后打开百度网盘手机App,操作更方 ...

  10. 商城项目18_esMapping字段映射、常用类型、数据迁移、ik分词器、自定义分词器

    文章目录 ①. Mapping字段映射概述 ②. 常用类型如下 - text.keyword ③. 映射中对时间类型详解 ④. ES的keyword的属性ignore_above ⑤. 映射的查看.创 ...

最新文章

  1. 谷歌利用人工智能设计的芯片揭示了智能的本质
  2. Python基础教程: with语句详解
  3. 光纤传感器实验模块_飞秒激光制备异质光纤光栅的温度应变双参数传感器
  4. MyBatis 传递多个参数
  5. Fater R-CNN 整体把握
  6. arc073F Many Moves
  7. c++ 协程_Python3 协程(coroutine)介绍
  8. 阿里巴巴开源技术汇总:115个软件(四)
  9. jsp中实现文件下载   两种方法
  10. 一起谈.NET技术,Silverlight 游戏开发小技巧:实现街霸4的选人界面
  11. Java中常用的正则表达式判断,如IP地址、电话号码、邮箱等
  12. 封装JedisClient.提供API实现对redis的操作
  13. 保研面试复习之数据结构篇
  14. 计算机二级考试c语言考试注意事项,计算机二级MS Office、ACCESS、二级C语言考试的注意事项...
  15. 2020UNCTF-MISC-网络深处1
  16. 首页-文章列表 (三) -列表文章布局-Cell 单元格组件-一张图和三张图 van-ellipsis 内容超过一行会省略 w33-宽度33%剩余1%做了图片之间间隙.md
  17. JSP时间TimeControl
  18. Android黄油计划之Choreographer原理解析
  19. OpenCV对矩阵进行padding操作
  20. 不用U盘,电脑之间快速传输大文件,共享功能

热门文章

  1. 搜狗浏览器连接海康摄像头,无法显示画面
  2. 玉龙雪山还会存在多久
  3. h文件中报错 unterminated conditional directive的原因
  4. GDI+处理带透明区域的png图片
  5. char*赋值给std::string是深拷贝
  6. C++ OpenCV 学习笔记【1】-安装环境搭建+基础文件资源链接
  7. python壁纸4k_别人用钱,而我用python爬虫爬取了一年的4K高清壁纸!真实用!
  8. centos7静默搭建oracle11g,centos7下静默安装oracle11G图解配置 1
  9. 逻辑回归python sigmoid(z)_python 实现逻辑回归
  10. deeplinux 热点_在深度deepin linux系统中同时开启wifi与热点的办法