如何有效的版本存储程序?

如何有效的版本存储程序?

问题描述:

我是数据库开发团队为大eshop服务的一部分。我们正在使用MS SQL 2016和ASP.NET。在生产环境中,10台使用连接池的IIS服务器的客户端使用SQL Server(我们有7-10k批/秒),我们使用18台DEV/TESTING IIS服务器(但由于多TB大小,只有一个DEV数据库)。 我们开发了一个新功能,迫使我们经常更改现有的存储过程。如何有效的版本存储程序?

如果我们正在部署对生产环境的更改,它将更改应用程序对IIS的修改以及数据库过程中的更改。部署时,它们总是更改为5个IIS服务器,然后更改为5个。同时,IIS服务器上都存在旧版本和新版本。这些版本必须同时共存一段时间,同时使用数据库中的过程。在数据库级别,我们通过使用多个版本来解决这种情况。旧的应用程序版本调用EXEC dbo.GetProduct,新的应用程序版本使用dbo.GetProduct_v2。将新版本的应用程序部署到所有IIS后,每个人都使用dbo.GetProduct_v2。在下一次部署期间,情况会逆转,并且dbo.GetProduct将包含新版本。类似的情况在于开发和测试环境。

我完全意识到这个解决方案并不理想,我想受到启发。

我们考虑分离数据部分和逻辑部分。在一个数据库中会有数据表,其他数据库将只包含程序和其他程序对象。部署新版本时,我们只需部署包含逻辑的整个数据库的新版本,而不需要创建过程的版本。来自逻辑数据库的程序将用数据查询数据库。 但是,这种解决方案的缺点是不可能使用我们计划明年使用的本机编译过程,因为它们不支持在其他数据库中查询。

另一种选择是使用一个数据库,并在不同的模式不同的程序版本...

如果您有任何意见,优点/缺点,或者你知道什么样的工具可以帮助我们和管理/部署/使用多个版本PROC请发表评论。

谢谢你这么多

编辑:我们正在使用TFS和Git,但是这并没有解决在SQL数据库的程序版本。我的主要问题是如何处理使用数据库中多个版本的过程来管理多个IIS应用程序版本的需求。

+0

你看过像GIT这样的源代码库吗?还有很多其他的选择,但那真的是你想要投资的东西。https://git-scm.com/ –

+0

当有人问一个问题时,它招待我,但他们的帖子完全由陈述关于该问题的不正确信息组成。如果您使用正确的项目和工具,TFS/Git肯定可以解决版本控制的问题。看看Schema Compare。 –

+0

你的最终目标是什么?不必在您的IIS代码中更改SP引用?然后才能够在DB中管理SP版本? – thomas

通过SSDT或SQL比较和源代码控制,版本控制非常简单。部署也是如此。

您的问题不是版本控制。

您需要两个具有相同名称的不同存储过程,可能参数相同,但代码不同,结果可能不同。例如,.net代码更可行,因为您可以使用重载到某个点。

你的问题是分阶段采用不同的代码部署:同一个进程内
两个版本必须共存

在你的情况,我会考虑使用同义词掩盖实际的存储过程名称。

所以你有这些存储过程。

  • dbo.GetProduct_v20170926(最后一个版本)
  • dbo.GetProduct_v20171012(此版本)
  • dbo.GetProduct_v20171025(下一版本)
  • dbo.GetProduct_v20171113(一个后)

然后你有

CREATE SYNONYMN dbo.GetProductBlue FOR dbo.GetProduct_v20171012; 
CREATE SYNONYMN dbo.GetProductGreen FOR dbo.GetProduct_v20170926; 

你[R分阶段部署IIS指的是SYNONYMNs

下释放一个...

DROP SYNONYMN dbo.GetProductBlue; 
CREATE SYNONYMN dbo.GetProductBlue FOR dbo.GetProduct_v20171025; 

然后

DROP SYNONYMN dbo.GetProductGreen; 
CREATE SYNONYMN dbo.GetProductGreen FOR dbo.GetProduct_v20171113; 

使用不同的模式是一样的结果,但你最终与

- Blue.GetProduct 
- Green.GetProduct 

或者将您的发布日期编码到架构名称中。

- Codev20171025.GetProduct 
- Codev20171113.GetProduct 

你最好有同样的问题,即使你有另一套IIS服务器,并保持一个代码基础上的每一组服务器:基于blue/green deployment model

+0

这些感觉就像OP已经在做的一样,只有一层抽象层(SYNONYMN)。我可能会错过这个区别。 – thomas

+0

@ thomas:true,它只是稳定了客户端代码的API,使得它更加明显,哪个版本正在使用 – gbn

一对夫妇的假设

  • 您的IIS代码版本号的地方 - 也许一个app.config或Web.config文件和版本号可以在你的.NET代码中引用
  • 你的目标是不是要改变你的IIS每个版本的.NET SP的名称,但它调用SP的正确版本DB
  • SP的所有版本采用相同的参数
  • 不同版本的SP可以返回不同的结果

UL在数据库中存在多个版本的存储过程是毫无意义的。这个想法是尽可能地从IIS中抽象出来(我假设)。

基于上述,我认为你可以添加另一个参数到你的SP接受版本号(你可能会从IIS中的Web.config获得)。

然后,您的存储过程dbo.GetProduct成为一个“控制器”或“路由”存储过程,其唯一目的是获取版本号并将其余参数传递给适当的底层SP。

因此,每个版本都会有1个SP(使用您希望的任何命名约定)。并且dbo.GetProduct将根据传入的版本号调用适当的一个。下面是一个示例。

create proc dbo.GetProduct_v1 @Param1 int, @Param2 int 
as 
begin 
    --do whatever is needed for v1 
    select 1 
end 

go 

create proc dbo.GetProduct_v2 @Param1 int, @Param2 int 
as 
begin 
    --do whatever is needed for v2 
    select 2 
end 

go 

create proc dbo.GetProduct @VersionNumber int, @Param1 int, @Param2 int 
as 
begin 
    if @VersionNumber = 1 
    begin 
     exec dbo.GetProduct_v1 @Param1, @Param2 
    end 

    if @VersionNumber = 2 
    begin 
     exec dbo.GetProduct_v2 @Param1, @Param2 
    end 
end 

另一个想法是动态建立在IIS中的SP名称(根据Web.config中的版本号),而不是硬编码的SP名称。