【IT168 技术文档】在过去的十几年中,我曾经创建和管理了不下百个MySQL数据库,在这个过程中我曾使用各种工具来使管理它的过程更简单,例如首选的图形化管理工具PHPMyAdmin,以及基于命令行的MySQL clent,它们都非常好用。但是在我内心身处始终觉得,我是一个程序员,而不是一个数据库管理员,总感觉编程和数据库管理之间有些跨越。为什么不用与编程相同的方式来管理数据库结构呢?我的这种梦想一直没有实现,不过自从开始使用Rails,我找到了答案。通过Rails的数据迁移(migration)功能,我可以使用程序员的方式来管理MySQL数据库了。
数据迁移功能让你可以使用Ruby语言来管理你的数据库方案,你可以充分利用一些Ruby所特有的工具,诸如Rake,来根据Ruby脚本提供的指令来更新数据库。还有,数据迁移功能还具有一个内置的版本控制功能,让你可以像在Subversion或CVS中那样对所做的修改进行前后的回滚。听起来是不是很具有诱惑力呢?在本篇文章中,我将介绍给你几个关键的数据迁移概念,并且告诉你如何才能比以前更高效的管理你的MySQL数据库。
从头开始,首先创建一个新的Rails项目,并将其命名为addresbook:
%>rails addressbook
创建数据库
接下来需要做的是针对一个应用程序的开发周期来创建Rails需要的数据库,我们这儿用的是addressbook_development、addressbook_test和addressbook_production:
mysql> create database addressbook_development; Query OK, 1 row affected (0.00 sec) mysql> create database addressbook_test; Query OK, 1 row affected (0.00 sec) mysql> create database addressbook_production; Query OK, 1 row affected (0.00 sec)
最后,为了让Rails能够与这个数据库进行会话,打开这个应用程序的database.yml文件,并修改其中的authorization参数。因为在这篇文章中我只是使用了addressbook_development数据库,因此只需在database.yml文件中的development加入以下内容:
development: adapter: mysql database: addressbook_development username: addressbook_user password: secret host: localhost
完成以上工作后,你就可以开始使用它的数据移植功能了。
创建你的首个数据移植脚本
第一个数据移植脚本将执行表创建和删除功能。通过执行以下命令来创建这个脚本:
%>ruby script/generate migration add_contacts_table create db/migrate create db/migrate/001_add_contacts_table.rb
执行这个命令将创建一个经典的框剪,用于创建和删除名为contacts的表。但是,you're responsible for implementing these features。这样做,打开001_add_contacts_table.rb文件,你看到的类似下面的内容:
class AddContactsTable < ActiveRecord::Migration def self.up end def self.down end end
因为这个类的用途就是创建这个表,所以你将使用up方法来创建表和增加列,而使用down方法来删除表。因此如下所示修改这两个方法:
class AddContactsTable < ActiveRecord::Migration def self.up create_table :contacts do |table| table.column :name, :string table.column :email, :string table.column :birthday, :date end end def self.down drop_table :contacts end end
每一个table.column调用负责增加一个新的列到表中。传递了两个参数,第一个是列名,第二个是列的数据类型。需要注意的是,尽管它支持使用:limit选项来限定列的大小,你可以不用去设定它;如果:limit没有被提供的话,将使用最大的允许大小。还有,add_column参数支持所有常见的数据类型,例如text、float、decimal、datetime、timestamp和boolean等。另外,它还支持设定默认值和指定列非空。
现在,执行以下命令;它将告诉Rails使用development数据库,并创建contact表。如果你使用的是Linux的话,使用export来替换下面Windows命令中的set:
%>set RAILS_ENV=development %>rake db:migrate
如果这个命令执行过程中没有任何错误的话,你将不会看到任何输出。因此,要想查看结果,登录到你的MySQL数据库中,选择addressbook_development数据库,然后执行DESCRIBE contacts命令,你会看到到如下内容:
+----------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(255) | YES | | NULL | | | email | varchar(255) | YES | | NULL | | | birthday | date | YES | | NULL | | +----------+--------------+------+-----+---------+----------------+ 4 rows in set (0.02 sec)
你将看到一个id字段已经被自动创建,尽管在表创建声明中没有指定它。这是Rails为你完成常规任务的一个伟大例子之一,它可以让你专注于更重要的事情。还有,你可以在一次数据移植中创建多个表;只需要增加多个create_table代码段到up方法中就可以了。
使用数据移植删除一个表
那么你如何让down方法执行呢?因为数据移植功能的工作原理与版本控制工具很相似,你可以将数据库回滚到一个早期的版本。版本号是由数据移植脚本所提供的数字来确认的;因为上面的001_add_contacts_table.rb脚本的版本号是001,因此你可以如下所示实现对这些修改的回滚:
%>rake db:migrate VERSION=000 (in C:/ruby/addressbook) == AddContactsTable: migrating =============================== -- create_table(:contacts) -> 0.1250s == AddContactsTable: migrated
执行完这条命令后,你再使用show tables命令来看到的话,你会发现contacts表已经被删除了!
使用数据移植修改表
当然,开发者总想通过一种简单的方式来管理数据库的表。和前面的任务一样,你只需要创建一个新的数据移植脚本,就可以完成管理数据表了。举个例子来说,假如你像增加一个city列到contacts表中:
%>ruby script/generate migration modify_contacts_add_city exists db/migrate create db/migrate/002_modify_contacts_add_city.rb
打开002_modify_contacts_add_city.rb文件并对它进行修改,如下所示:
class ModifyContactsAddCity < ActiveRecord::Migration def self.up add_column :contacts, :city, :string end def self.down remove_column :contacts, :city end end
再次执行describe contacts命令,你将看到city列已经被增加到这个表中了!
mysql> describe contacts; +----------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(255) | YES | | NULL | | | email | varchar(255) | YES | | NULL | | | birthday | date | YES | | NULL | | | city | varchar(255) | YES | | NULL | | +----------+--------------+------+-----+---------+----------------+ 5 rows in set (0.00 sec)
注意,我还执行了down方法;它将移除这个city列。为了删除这个列,只需回滚数据移植到001版本即可,如下所示:
C:\ruby\addressbook>rake db:migrate VERSION=001 (in C:/ruby/addressbook) == ModifyContactsAddCity: reverting =========================== -- remove_column(:contacts, :city) -> 0.1720s == ModifyContactsAddCity: reverted (0.1720s) ==================
结论
这个指南只是介绍给了你Rails的数据移植功能的冰山一角;它不仅支持MySQL,还支持目前市面上的大多数数据库,诸如SQLite、PostgreSQL、SQL Server和Oracle。如果你想了解更多这个精彩工具的功能,可以去查看Rails的官方站点的migrations documentation(http://api.rubyonrails.org/classes/ActiveRecord/Migration.html)。尽管数据库移植是Rails特有的一个功能,there's nothing to prevent you from quickly creating a solution for managing MySQL no matter what web development language you settle upon.