一、问题

项目做到后期,或者项目版本升级时,有时不得不更新原来的数据库设计。比如有一张表,可能需要增加字段、修改字段等。在某些情况下,ALTER TABLE命令不能完成这个任务,比如更换主键。这时只能用全新的设计替换掉原来的设计。但是,如果让新设计的表格中,包含原来的数据呢?

二、解决方案

其实很简单,分4步:

  1. 创建新表
  2. 将原表数据插入到新表中
  3. 删除原表
  4. 将新表重命名为原表名

三、实例

知名开源项目BlogEngine.NET就是这样做的!比如以下是它从2.0版本升级到2.5版本时,所使用的SQLite数据库升级脚本的一部分,对be_Posts表做了升级。

--
-- Update be_Posts
--
CREATE TABLE be_PostsNew (
[PostRowID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
[BlogID] VARCHAR(36) NOT NULL,
[PostID] VARCHAR(36) NOT NULL,
[Title] VARCHAR(255) NOT NULL,
[Description] TEXT NOT NULL,
[PostContent] TEXT NOT NULL,
[DateCreated] DATETIME NOT NULL,
[DateModified] DATETIME NOT NULL,
[Author] VARCHAR(50) NOT NULL,
[IsPublished] BOOLEAN NOT NULL,
[IsCommentEnabled] BOOLEAN NOT NULL,
[Raters] INTEGER NOT NULL,
[Rating] REAL NOT NULL,
[Slug] VARCHAR(255) NOT NULL,
[IsDeleted] BOOLEAN NOT NULL
);

INSERT INTO bePostsNew (BlogID, PostID, Title, Description, PostContent, DateCreated, DateModified, Author, IsPublished, IsCommentEnabled, Raters, Rating, Slug, IsDeleted) SELECT '27604f05-86ad-47ef-9e05-950bb762570c', p.PostID, p.Title, p.Description, p.PostContent, p.DateCreated, p.DateModified, p.Author, p.IsPublished, p.IsCommentEnabled, p.Raters, p.Rating, p.Slug, p.IsDeleted FROM bePosts p;

DROP TABLE bePosts; ALTER TABLE bePostsNew RENAME TO be_Posts;