简介
PHP 支持简单的 Web 应用程序开发和部署环境。这是它得到普遍应用的原因之一。DB2 9的原生 XML 功能进一步简化了开发过程。这种简化体现在以下方面:
- 应用程序代码较少,复杂性降低
- 较简单的关系模式
- 更好地管理因为更改业务需要而发生的模式演化
|
在本文中,我们将在该基础上进行构建并说明使用 DB2 原生 XML 功能简化应用程序代码和关系模式的有效性。还将讲述业务需求更改对数据的影响(模式演化)以及对应用程序代码和关系模式的影响。
为了说明我们的推理,将通过一个模拟在线商店的使用情景来进行说明,该商店向注册客户出售古董银器。
我们将在该情景中说明的一些要点包括:
设置 PHP 环境的容易程度
将 DB2 原生 XML 功能与 PHP 应用程序(包括用 PHP 和 XQuery 编写的 Web 服务)集成的容易程度
使用 XQuery、存储过程和视图将业务逻辑和数据转换放到数据库中。
|
在该情景中使用的 DB2 XML 功能将包含以下方面:
按分列结构在列中存储 XML 文档
使用 XQuery 进行搜索和发布
在 DB2 存储过程和视图中支持 XML
使用 XML 索引提高性能
|
为突出使用 DB2 原生 XML 支持对 PHP 应用程序代码和关系模式设计的影响,该情景将创建一个并行环境,该环境使用不包含任何 XML 功能的数据库(例如,MySQL)。我们将研究这两个环境在应用程序代码、数据库查询和关系模式方面的差异。还将说明选择特定代码、模式或查询以及备选方案(如果可能)的理由。
情景
该情景模拟向注册客户出售古董银器的在线商店。因为该情景的一个目的是说明不同的数据库环境以及它们对应用程序代码的影响,所以我们将对两个应用程序进行同时说明,一个应用程序使用 DB2 原生 XML,另一个应用程序使用类似 MySQL 的开放源码 RDMS,具有有限的 XML 功能或没有任何 XML 功能。
因此,访问 Web 站点的客户将看到一个包含两个垂直面板的页面。每个面板都将显示同一应用程序的一个版本,提供相同的用户体验,但在后端使用不同的数据库:
具有原生 XML 支持的 DB2
其他 RDBMS(在本例中为不使用任何 XML 功能的 DB2)
|
为显示应用程序代码的差异,每个面板进一步分为两个水平框架,上面的框架显示在线商店,下面部分显示代码段。当用户进行任何操作(如单击某一种类或产品图像)时,上面部分都会生成一个新页面。下面部分显示创建此页面所需的代码。
图 1. 示例应用程序面板
这将说明,虽然在任何一个应用程序中用户的体验没有变化,但代码复杂性发生了很大变化。这种对比将突出用 PHP 编写的普通 SMB 应用程序使用 DB2 原生 XML 功能的好处。
注意:我们对此情景的假设是业务数据已经是 XML 格式的,尽管数据库可能没有任何 XML 功能。这将产生可用于数据库的使用 XML 功能的 PHP 应用程序代码(如简单 DOM)。具有有限 XML 功能或无 XML 功能的数据库将 XML 数据存储为 CLOB/BLOB 数据类型,或分割到关系字段中。
在 Web 站点中浏览时的功能和用户体验
Web 站点将为用户提供索引,列出商店中所有可用银器的种类和品牌。用户单击某一种类或品牌时,将显示该种类或品牌的货品列表。选择列表中的任何货品都会在页面中显示该货品的详细信息。用户可以将这些货品添加到购物车中。一旦用户提交了订单,将会创建采购订单并根据此采购订单向用户提供发票。用户可以随时检查购物车中的货品。用户还能够得到他们过去已订购的所有货品的报告。
应用程序体系结构
图 2 显示了示例应用程序的基本体系结构。
图 2. 应用程序体系结构
关系和 XML 模式
XML 文档和模式
原生 XML 存储不需要 XML 列与特定 XML 模式关联。需要对插入到数据库中的 XML 文档进行的任何验证都在插入语句中使用 SQL/XML 函数显式地进行。附录中包含 XML 文档示例。
关系模式
对于这两个数据库,用于存储这些 XML 文档的关系模式将有所不同。
对于 DB2 原生 XML,将有三个表,每个表包含两列。
图 3. DB2 原生 XML 模式
对于无 XML 支持的 RDBMS,将有四个表,每个表包含多个列:
图 4. 无 XML 支持的情景的关系模式
可以看出,与无 XML 支持的 RDBMS 相比,DB2 原生 XML 的关系模式非常简单。
我们已经通过将采购订单文档存储为 BLOB,在基本关系数据库中尽量保持采购订单表模式简单。当查看生成订单历史记录时,这种操作的作用将非常明显。
DB2 PHP 驱动程序
在开始讲述 PHP 应用程序代码之前,我们先了解一下 PHP 的 DB2 驱动程序。ibm_db2 驱动程序支持两种连接数据库的方法:编目 和非编目。编目连接可以是本地数据库(如果有 DB2 服务器在本地运行),也可以是远程 DB2 服务器节点。第二种方法通常用于远程非编目连接,需要构建连接字符串(类似于 JDBC URL)以建立非编目连接。以下代码连接编目数据库。(客户机应用程序不需要知道或关注编目连接时本地的还是远程的。)
$conn = db2_connect($dbname, $dbuser, $dbpass); if(!$conn) { echo db2_conn_errormsg(); die("Unable to connect to database!"); } |
还可以使用 db2_pconnect 创建与数据库的持久连接。调用 db2_close 时,持久连接实际将不被关闭,因为连接句柄将在请求中保留。有关 PHP 的 IBM DB2 驱动程序的详细信息,请访问 http://www.php.net/manual/en/ref.ibm-db2.php。在下面的代码段中,假设 $conn 是有效连接句柄。
填充数据库 在 Web 站点可以开通之前,需要使用客户信息和产品目录填充数据库。对于我们的情景,将不详细说明如何获取此数据。假设其以 XML 文档的形式包含在本地文件系统的文件中。下面显示了连接数据库和执行 SQL 插入语句所需的 PHP 代码段示例。
DB2 Viper 因为每个产品文档都包含产品 ID 属性,我们需要使用 PHP 的 SimpleXml API 提取该 ID。
注意: 使用此 API 比操作 DOM 对象容易得多,该对象在 PHP 版本 5 之前是惟一选择。
- 创建数据库连接:
$conn =db2_connect($dbname, $dbuser, $dbpass); |
- 从文件打开文档,成为一个变量:
$fileContents = file_get_contents("products/p1.xml"); |
- 从此变量创建简单的 XML 对象:
$dom = simplexml_load_string($fileContents); |
- 从文档中提取产品 ID:
$prodID = (string) $dom["pid"]; |
- 创建准备好的语句,将 XML 文档插入数据库中:
$stmt =db2_prepare($conn, "INSERT INTO xmlproduct VALUES (?, ?)"); |
- 将从文档中提取的产品 ID 作为参数与文档一起传递到查询:
db2_execute($stmt, array($prodID, $fileContents); |
注意插入数据到 XML 列中与插入数据到任何 CLOB 列中没有区别。因为这个 DB2 新版本允许在插入时对 XML 数据进行隐式分析,我们不需要对传入值显式地调用 XMLPARSE。如果我们希望在 XML 标记周围保留无关空格,则可以使用带 RESERVE WHITESPACE 选项的 XMLPARSE 函数。
注意: 这些代码段中的查询都使用斜体表示,以区别于 PHP 应用程序代码。
非 XML RDBMS 因为此数据库不具有任何 XML 功能,产品文档需要分解到两个关系表中。关系模式和 XML 模式之间的映射信息将直接嵌入 PHP 应用程序代码中。
- 首先加载文档到 DOM 中:
$fileContents = file_get_contents("$products/p1.xml"); $dom = simplexml_load_string($fileContents); |
- 现在将产品的单个元素分割到本地变量中:
$prodID = (string) $dom["pid"]; $prodName = (string) $dom->description->name; $prodDetails = (string) $dom->description->details; $prodPrice = (float) $dom->description->price; |
- 每个产品的图像 URL 需要存储在单独的图像表中:
$images = array(); foreach($dom->description->images->image as $image) { switch((string) $image[type']) { case thumbnail':$prodImgThumb = (string) $image; $prodImgAlias = (string) $image[alias']; if(!$prodImgAlias) $prodImgAlias = NULL; $stmt = db2_prepare($conn, "INSERT INTO sqlimages (Pid, Type, Alias, Location) VALUES (?, ?, ?, ?)"); db2_execute($stmt, array($prodID, thumbnail', $prodImgAlias, $prodImgThumb)); case full': $prodImgFull = (string) $image; $prodImgAlias = (string) $image[alias']; if(!$prodImgAlias) $prodImgAlias = NULL; $stmt = db2_prepare($conn, "INSERT INTO sqlimages (Pid, Type, Alias, Location) VALUES (?, ?, ?, ?)"); db2_execute($stmt, array($prodID, full', $prodImgAlias, $prodImgFull)); } } |
- 当前实现 ibm_db2 驱动程序不能适当地将 NULL 变量作为参数来处理,以便执行函数;因此我们使用一个非强制性解决方案:
if(!$prodBrand) $prodBrand = " "; if(!$prodCategory) $prodCategory = " "; if(!$prodImgFull) $prodImgFull = " "; |
- 现在保存产品表中的产品信息:
$stmt = db2_prepare($conn, "INSERT INTO sqlproduct (Pid, Name, Details, Brand, Category, Price, Weight, Size, Description) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"); db2_execute($stmt, array($prodID, $prodName, $prodDetails, $prodBrand, $prodCategory, $prodPrice, $prodWeight, $prodSize, $fileContents)); |
创建主页 主页包含在线商店中所有可用产品的种类和品牌的索引。索引的右边区域显示所有货品的列表。
图 5. 主页
创建种类和品牌的索引列表 索引通过查询数据库中所有产品的惟一种类和品牌的列表而创建。启动应用程序时将创建此列表。
DB2 Viper
- 首先创建 DB2 视图,以使用 XQuery 列出种类,XQuery 在所有产品中循环并返回所有惟一种类:
CREATE VIEW Categories(Category) AS SELECT DISTINCT(XMLCAST( XMLQUERY(for $i in $t/product/description/category return $i' PASSING BY REF T.DESCRIPTION AS "t" RETURNING SEQUENCE) AS VARCHAR(128))) FROM xmlproduct AS t |
- 现在从应用程序调用该视图:
$stmt = db2_exec($conn, "SELECT * FROM Categories"); while(list($cat) = db2_fetch_array($stmt)) { echo " ";} |
The application code is similar in both cases. Creating an XML data view allows us to easily query the view, which helps in understanding the structure of the product XML from the application code. The XQuery in the view needs to be changed to find the brand element, and the same SQL call needs to look at the Brand column.
Impact of schema evolution on index listings
Based on customer feedback, we need to allow users to browse the site to find items that are silver plated or made from sterling silver. Let's look at the impact of adding subcategories to the index on: XML schema, relational schema, queries, and PHP application code.
Impact on XML schemas and document instances
Add new attributes (catx) to the category element in the product XML schema. All new XML documents for products now properly populate this attribute with solid or silvered silver:
Miscellaneous
Effects on relational schema
- DB2 Viper
This will not require any changes to the relational schema as the XML document is stored in a single column.
- Non-XML RDBMS
In a basic relational database, you will need to change the schema of the products table, adding another column named catx. This may involve deleting and reinserting all product documentation.
Impact on queries
- The XQuery required for DB2 Viper to create indexes will change to include this new property in the criteria. Likewise, the XQuery used to list items based on selections in the index will change to include the new criteria.
- Non-XML RDBMS
Insert statements will change to include the new columns.
The query required to create the index will change to include this new column in the WHERE clause. Likewise, the query used to list items based on selections in the index will change to include the new criteria.
Impact on application code
- DB2 Viper
There will be no changes to application code.
- Non-XML RDBMS
- will require additional DOM code to separate out subcategory information.
- The INSERT statement will require additional parameters.
- All data may need to be reinserted, resulting in a period of inoperability for the end user.
List of items when the user clicks on a category or brand
When the user clicks on a specific category or brand, a list of all items in that category or brand will be generated. Each item in the listing has a short description and a URL to a thumbnail image. This list appears and is formatted on the home page.
Figure 6. List of goods in a certain category
DB2 Viper
In DB2, XQuery not only creates the list, but also converts it to HTML output so that the browser can directly use. Using this feature of XQuery, not only can business logic be pushed out, but it can also be published to the database server, effectively making middle-tier applications very simple. This is why you should use PHP instead of Java™ or VS .NET®.
$xquery =for $i in $t/product let $thumb := $i/description/images/image[@type="thumbnail"] where $i/description/category = " . htmlentities($category) . " return
http://www.bkjia.com/PHPjc/446840.htmlwww.bkjia.comtruehttp: //www.bkjia.com/PHPjc/446840.htmlTechArticleIntroduction PHP supports a simple web application development and deployment environment. This is one of the reasons for its widespread use. DB2 9's native XML capabilities further simplify the development process. This simplification...
|