|
XML 是当今 Web 最常用的数据交换格式之一。DB2® 对 pureXML™ 的支持以及与 parsing and generating XML API(REXML)的结合,为 Web 应用程序开发提供了强大的技术组合。DB2 数据服务器中的本地 XML 支持引入了极大的灵活性,通过使用 DB2 的混合型数据库引擎编译器和解析器(可同时使用 SQL 和 XQuery),能够混合存储半结构化的具有层次结构的 XML 文档和关系数据。在 Ruby on Rails 系列 的第二篇文章中,我们将演示如何在第一篇文章的 Team Room 示例中利用 pureXML 特性。 简介 在 Ruby on Rails 系列的第 1 部分中,我们使用 Ruby on Rails 和 DB2 构建了一个 Team Room 示例,这个应用程序允许注册的成员共享各种文本文档、图像文件和 XML 文档。为了管理不断增加的共享文档集合,您学习了如何按类别对文档分组。然后,学习了如何添加订阅特性,这样当用户订阅的文档类别中添加了新文档时,我们就可以通过电子邮件通知他们。在第一篇文章的末尾,成员能够将不同类型的文件上载到 Team Room,文件被存储在后端 DB2 数据服务器中。现在,我们进一步增强 Team Room,提供更高级的用户特性和更好的资源访问。 步骤 1. 添加用户管理特性 首先,在用户模型和它的底层表持久存储中增加一些必要的东西,从而支持正确的身份验证:一个惟一的用户 id 字符串和一个散列的密码(使用 SHA 算法和一个伪随机种子)。可以添加其他用户属性(比如有效性、等级等等)来进一步改进这个用户模型,并对控制器和视图做几处修改来支持新用户的注册和安全登录。我们的 Rails 项目放在 D:\rails\teamroom 目录中,所以下面引用的所有路径都是 D:\rails\teamroom 目录中的相对路径。 a) 执行 ruby script/generate migration add_user_credentials_columns 启动迁移进程,在 USERS 表中添加必要的列。 b) 编辑 db/migrate/008_add_user_credentials_columns.rb 文件,添加必要的列(见清单 1): 清单 1. 编辑 008_add_user_credentials_columns.rb class AddUserCredentialsColumns < ActiveRecord::Migration def self.up add_column :users, :userid, :string, :limit => 8 add_column :users, :hash_passwd, :string add_column :users, :salt, :string end
def self.down remove_column :users, :userid remove_column :users, :hash_passwd remove_column :users, :salt end end |
c) 运行 rake db:migrate,在 USERS 表中添加这些新列。 步骤 2. 让主题可供多个用户订阅 在第一篇文章描述的 Team Room 中,每个主题只能属于一个订阅。每个订阅是一个用户已经订阅的主题集合,这让我们的 Team Room 相当不真实,因为一个用户选择了某个主题之后,Team Room 中的其他用户就不能再订阅这个主题了。 随着 Team Room 的流行,许多成员希望订阅同一个主题。成员的这种要求是正常的,应该允许对同一主题进行多次订阅。在更新的 Team Room 中,一个用户可以通过一个订阅订阅许多主题。为了实现这一修改,需要执行以下步骤: - 以前在 SUBSCRIPTIONS 和 SUBJECTS 之间存在一对多关系。但是,每个主题只能属于一个订阅。为了放宽这个限制,我们需要在 SUBSCRIPTIONS 和 SUBJECTS 之间建立多对多关系。
- 为了确保数据库是规范化的(参见注 1),创建一个新的表 SUBJECTS_SUBSCRIPTIONS 来连接 SUBJECTS 和 SUBSCRIPTIONS 表。在中间连接表的名称选择方面,我们使用了 Ruby 约定:Active Record 假设这个连接表的名称是两个目标表名的组合(按字母表次序),它包含链接两个目标表的外键对。
- 修改现有的关联,并在 SUBJECTS_SUBSCRIPTIONS 表以及主题和订阅模型中添加新的关联来反映这些修改。
注 1:参阅 IBM DB2 Database for Linux, UNIX, and Windows Information Center 中的 “Normalization” 部分。 SUBJECTS_SUBSCRIPTIONS 表包含以下列: 表 1. SUBJECTS_SUBSCRIPTIONS 表列和描述
| 列名 | 数据类型 | 描述 |
|---|
| SUBSCRIPTION_ID | Integer | SUBSCRIPTIONS 表的外部 ID |
|---|
| SUBJECT_ID | Integer | SUBJECTS 表的外部 ID |
|---|
在迁移过程中,执行以下步骤: a) 执行 ruby script/generate migration create_subjects_subscriptions_table。 b) 编辑 db/migrate/009_create_subjects_subscriptions_table.rb 文件: 清单 2. 编辑 009_create_subjects_subscriptions_table.rb class CreateSubjectsSubscriptions < ActiveRecord::Migration def self.up create_table :subjects_subscriptions, :id => false do |t| t.column :subscription_id, :integer, :null => false t.column :subject_id, :integer, :null => false end remove_column :subjects, :subscription_id add_index :subjects_subscriptions, :subject_id end
def self.down drop_table :subjects_subscriptions add_column :subjects, :subscription_id, :integer end end |
c) 运行 rake db:migrate 创建 SUBJECTS_SUBSCRIPTIONS 表。 e) 将 /app/models/subject.rb 文件中现有的关联 belongs_to :subscription 替换为新关联 has_and_belongs_to_many :subscriptions。 f) 将 /app/models/subscription.rb 文件中现有的关联 has_many: subject 替换为 has_and_belongs_to_many :subjects。 注:在往回迁移时,必须确保相应地修改并恢复每个模型中数据库对象的关联。 步骤 3. XML 数据:客户信息 我们的市场营销部门用 XML 格式收集了匿名的客户信息,用来分析客户的购物习惯。下面是零售商为市场研究收集的数据示例。 清单 3. XML 文档示例 <marketinfo xmlns="http://www.ibm.com/developerworks"> <sales> <customer> <address> <city>Nashville</city> <state>TN</state> <zip>46808</zip> </address> <categories> <category type='Toys'> <item> <SKU>2434901</SKU> </item> <item> <SKU>9043272</SKU> </item> </category> <category type='Video Games'> <item> <SKU>1915216</SKU> </item> </category> </categories> <last_purchase>2007-05-12</last_purchase> </customer> </sales> </marketinfo> |
每个客户购买记录包含一个美国或加拿大的地址、产品类别细节(包括产品的 SKU 号)以及上一次购买的日期。产品类别包括:- Apparel
- Automotive
- Baby
- Books
- Computers
- Cosmetics
- Electronics
- Garden & Patio
- Home
- Jewelry
- Movies
- Music
- Pets
- Pharmacy
- Sports
- Toys
- Video Games
后面一节演示如何使用 Team Room 应用程序对这个 XML 数据执行查询操作。 |