- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在开发一个在客户系统上使用数据库(PostgreSQL、MySQL、Oracle 或 MSSQL)的应用程序。
因此我需要对每个新版本执行数据库更新。
我目前处于概念阶段,没有任何东西投入生产。
所有的 DDL 语句都在脚本文件中。
结构如下:
tables\employees.sql
customers.sql
orders.sql
这些脚本也在版本控制中,可用于从stretch构建数据库。
当然,这些表格在未来的某个时候会有变化。
例如表 employees 是这样创建的:
CREATE TABLE if not exists employees
(
EmployeeId serial,
FirstName text,
PRIMARY KEY (EmployeeId)
);
在未来的版本中,该表会得到扩展:
ALTER TABLE employees ADD COLUMN address varchar(30);
在我的研究中,我发现了这个例子:https://stackoverflow.com/posts/115422/revisions .版本号用于执行特定更改。
我喜欢这个概念,我的想法是实现类似的东西。但我考虑的不是系统版本号,而是为每个表引入一个版本。
当创建 employee 表时,它获得版本号 1。随着对该表的每次更改,版本号都会增加 1。添加 address 列后(更改上面的语句)表版本为 2。
每个表更改都将在嵌套事务中发生,如下所示:
BEGIN TRANSACTION;
UPDATE employees SET Version = 2;
ALTER TABLE employees
ALTER TABLE employees ADD COLUMN address varchar(30);
END TRANSACTION;
如果表版本低于当前表版本,事务将被回滚。该逻辑的实现尚未完成。
好处是表上的所有更改都在表的脚本文件本身内,并且初始语句始终是最新的。
例如,当第一次创建 employee 表时,它看起来像这样:
employees.sql
CREATE TABLE if not exists employees
(
EmployeeId serial,
FirstName text,
Version int default 1 not null,
PRIMARY KEY (EmployeeId)
);
经过一些修改后,它看起来像这样:
employees.sql
CREATE TABLE if not exists employees
(
EmployeeId serial,
FirstName varchar(100),
address varchar(80),
Version int default 3 not null, -- notice the 3
PRIMARY KEY (EmployeeId)
);
-- First Change
BEGIN TRANSACTION;
UPDATE employees SET Version = 2;
ALTER TABLE employees
ALTER TABLE employees ADD COLUMN address varchar(30);
END TRANSACTION;
-- Second Change
BEGIN TRANSACTION;
UPDATE employees SET Version = 3;
ALTER TABLE employees
ALTER COLUMN address TYPE varchar(80),
ALTER COLUMN FirstName TYPE varchar(100);
END TRANSACTION;
这个概念可以接受还是我在这里重新发明轮子?
最佳答案
我认为为每个表设置版本号有点矫枉过正。此外,它使管理数据库和应用程序变得复杂。我建议您为 DB_VersionNumber 添加一个新表,并为每次升级在该表中添加一行。我一直在做的是:1)在数据库中为数据库版本创建一个表(步骤)2)创建一个检查这个表的SP,如果表中不存在则运行DB升级步骤,否则跳过该步骤。3) 对于每个数据库更改,在升级脚本文件(您已经创建并添加到源代码管理)中添加一个步骤。
Here is the table and the SP:
IF OBJECT_ID (N'DB_Version', N'U') IS NULL
Begin
CREATE TABLE [DB_Version](
[VersionNumber] [decimal](18, 2) NOT NULL,
[CommitTimestamp] [smalldatetime] NOT NULL
) ON [PRIMARY]
ALTER TABLE DB_Version
ADD CONSTRAINT UQ_VersionNumber UNIQUE (VersionNumber);
End
IF OBJECT_ID ( 'NewDBStep', 'P' ) IS NULL
begin
Exec ('
-- ============================================
-- Description: Applies a new DB upgrade step to the current DB
-- =============================================
CREATE PROCEDURE NewDBStep
@dbVersion [decimal](18, 2),
@script varchar (max)
AS
BEGIN
If not exists (select 1 from DB_Version Where VersionNumber = @dbVersion)
Begin
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
BEGIN TRY
Begin tran
Exec (@script)
Insert into DB_Version (VersionNumber, CommitTimestamp) Values (@dbVersion, CURRENT_TIMESTAMP);
Commit tran
Print ''Applied upgrade step '' + Cast ( @dbVersion as nvarchar(20))
END TRY
BEGIN CATCH
Rollback tran
Print ''Failed to apply step '' + Cast ( @dbVersion as nvarchar(20))
Select ERROR_NUMBER() AS ErrorNumber
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
,ERROR_PROCEDURE() AS ErrorProcedure
,ERROR_LINE() AS ErrorLine
,ERROR_MESSAGE() AS ErrorMessage;
END CATCH
End
END ') ;
End
然后,通过调用 SP 应用您的升级(关键是您必须为每个升级脚本分配一个唯一的步骤编号:
---------------- Add the new steps here
-- Step: 0.01
-- Adding the MyTableName table if it does not exist.
Exec NewDBStep 0.01, '
IF OBJECT_ID (N''MyTableName'', N''U'') IS NULL
Begin
CREATE TABLE [MyTableName](
[Id] [int] IDENTITY(1,1) NOT NULL,
[UserType] [nvarchar](20) NULL,
PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
End
'
Exec NewDBStep 1.00, '
-- Some other DDL script
'
关于mysql - 将 SQL 更改部署到客户数据库(更改表、函数等),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39854089/
我有一个名为 flightbooking 的表。该表由字段组成,包括标有“R”或“C”的状态、已保留和已取消。 我想弄清楚的是允许删除状态为“C”的记录,但如果下一行的状态为“R”,则不应删除。 [编
关闭。这个问题是opinion-based .它目前不接受答案。 想改进这个问题?更新问题,以便 editing this post 可以用事实和引用来回答它. 1年前关闭。 Improve this
研究 PHP/Gearman。我试图了解 Gearman 服务器/进程如何确定什么构成“有效”客户端。 在我看过的文档中,文档显示了许多连接到 Gearman 服务器的客户端。但是,我没有找到任何描述
HBase案例:客户/订单 假设HBase 用于存储客户和订单信息。有两种核心记录类型被摄取:客户记录类型和订单记录类型。 客户记录类型将包含您通常期望的所有内容: 客户编号 客户名称
当运行配方时出现问题并且客户端运行中途挂起时,安装的 Chef 客户端将无法使用。 然后,您可以退出机器、重新启动、清理 Chef pid 文件等,但每次启动 Chef 客户端时都会显示以下消息: C
我正在用Java开发游戏,目前进展顺利。我想尽早实现多人游戏,因此我在此基础上进行构建,而不是在具有大量不同功能的情况下将整个游戏移植到多人游戏中。 我想使其成为客户端/服务器应用程序。 现在,我确定
我正在尝试以编程方式修改 magento 上的现有客户数据,但出现错误,希望有人可以帮助我。 require_once('../app/Mage.php'); ini_set("error_repor
我正在学习 JQuery。我需要创建一个自定义控件。该控件基本上将呈现一些 HTML。有时,我只想获取 HTML。我希望使用以下语法: // Put generated html inside of
我正在尝试以编程方式修改 magento 上的现有客户数据,但出现错误,希望有人可以帮助我。 require_once('../app/Mage.php'); ini_set("error_repor
我想选择表格的一行并插入到另一个现有表格中。(我用的是php和MySql,两张表除了id和timestamp外,其他列都是一样的) 我试着做一个手推车。我希望当有人付款时,从“carret”中选择该客
我想使用 JXTA 实现客户端-服务器架构。服务器部分的配置也将是 3 层。有谁知道开始这个项目的好地方吗? 提前致谢。 最佳答案 JXTA 处理 p2p 连接。这与客户端-服务器方法相反。 据我了解
我需要创建一个 Stripe 客户并为他们订阅一个计划。我查看了 Stripe.js,似乎虽然您可以获得 token ,但除此之外它没有提供任何东西。有可用于节点和 PHP 的库,但为什么不能用于 J
我有一个数据库设计要求,它变得越来越复杂,我需要找出最佳的处理方法。 目前,我有“联系人”,也有“公司”。一个公司可以有多个联系人,但一个联系人只能属于一个公司。这形成了明显的 1:n 关系。但是,联
http://ecc.galengrover.com/programs/facility-rentals/ 在那个页面上,只有那个页面我有一个奇怪的问题。在内容框上方,“所有区域”一词出现在其他文本的
所以,我让这个 CSS 预加载器正常工作。但是,我在将其添加到我的网站时遇到了一些困难。有人可以帮助我理解代码的实现,以允许预加载器成为网站加载前查看的第一个元素。此时预加载器将淡出。预加载器的代码如
考虑以下场景: 有一个 Windows 服务托管一个 WCF 服务。 WCF 服务在客户端和位于不同物理机器上的 AppFabric 服务器之间提供接口(interface)。它检索对象,对其进行计算
当前端的订单历史页面 (*/sales/order/history/) 只显示一条短消息时,这个问题首先被意识到:您没有下订单。 经过一番调试,发现问题出在这个函数上: Mage::getSingle
我的公司是一些项目的定制开发商店,有些较大,有些较小。目前,我们通过电子邮件处理所有客户通信。所以我们通过电子邮件发送设计文档,他们将其标记并发送回去。然后我们推出了他们产品的测试版,他们通过电子邮件
我有一个小部件 View 如下: 公共(public)类 RemoteNumView 扩展了 FrameLayout { 我如何调用 Roboguice 就像在 RoboActivity 中一样?如下
我有一个包含客户编号、客户名称和商品编号的 MySQL 表。它比这稍微复杂一点,但我尝试稍微简化它并删除敏感数据。 当前表 Unique Customer Number | Customer Name
我是一名优秀的程序员,十分优秀!