热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PHP与MongoDB数据库的应用开发

八、实际应用一些开发人员可能害怕使用一种新型的数据库,因为它和他们以前工作中用过的那些不同。在理论上学习新事物不同于在实践中学习如何使用,所以,这部分内容将通过比较基于SQL的关系型数据库,比如MySQL,来解释如何用MongoDB来开发实际应用,这样

八、实际应用

一些开发人员可能害怕使用一种新型的数据库,因为它和他们以前工作中用过的那些不同。

在理论上学习新事物不同于在实践中学习如何使用,所以,这部分内容将通过比较基于SQL的关系型数据库,比如MySQL,来解释如何用MongoDB来开发实际应用,这样就可以熟悉这两种途径

的不同。

例如,我们将构建一个blog系统,有用户,提交和评论功能。在使用关系型数据库的时候,你可以象下面这样通过定义表模式来实现它。

基于MongoDB的php应用开发(2)
在MongoDB中实现同样的文档定义如下:

$users = array(

 'username' => 'crodas',   

 'name' => 'Cesar Rodas',

);

$posts = array(

 'uri' => '/foo-bar-post',

 'author_id' => $users->_id,

 'title' => 'Foo bar post',

 'summary' => 'This is a summary text',

 'body' => 'This is the body',

 'comments' => array(

  array(

   'name' => 'user',

   'email' => 'foo@bar.com',

   'content' => 'nice post'

  

 )

);

你可能注意到,我们只用一个文档就代替了posts和comments两个表,这是因为comments是post文档的子文档。这样做使实现更简单,在你想存取发布内容和它的评论时,会节省查询数据库的时间。

为了更简洁,用户所做评论的细节可以和评论的定义合并,所以你可以用一个查询来获取所发布的内容,评论和用户这些信息。

$posts = array(

 'uri' => '/foo-bar-post',

 'author_id' => $users->_id,

 'author_name' => 'Cesar Rodas',

 'author_username' => 'crodas',

 'title' => 'Foo bar post',

 'summary' => 'This is a summary text',

 'body' => 'This is the body',

 'comments' => array(

  array(

   'name' => 'user',

   'email' => 'foo@bar.com',

   'comment' => 'nice post'

  ), 

 )

);

这意味着会存在一些重复信息,但现在磁盘空间比CPU的RAM要便宜得多,以空间换时间,网站访问者的耐心和时间更重要。如果你关注重复信息的同步,那么在更新author信息的时候,你可以执行下面这个更新查询来解决这个问题。

$filter = array(   

 'author_id' => $author['_id'],

);

$data = array(

 '$set' => array(

  'author_name' => 'Cesar D. Rodas',

  'author_username' => 'cesar',

 )

);

$collection->update($filter, $data, array(

  'multiple' => true)

);

以上是我们对数据模型的转换和优化,下面将重写一些用在MongoDB中的和SQL等价的查询。

SELECT * FROM posts

 INNER JOIN users ON users.id = posts.user_id

 WHERE URL = :url;

SELECT  * FROM comments WHERE post_id = $post_id;

首先,增加索引:

$collection->ensureIndex( 

 array('uri' => 1),

 array('unique' => 1, 'background')

);

$collection->find(array('uri' => ''));

INSERT INTO comments(post_id, name, email, contents)

 VALUES(:post_id, :name, :email, :comment);

$comment = array(   

 'name' => $_POST['name'],   

 'email' => $_POST['email'],   

 'comment' => $_POST['comment'],

);

$filter = array(

 'uri' => $_POST['uri'], 

);

$collection->update($filter, array(

 '$push' => array('comments' => $comment))

);

SELECT * FROM posts WHERE id IN (

 SELECT DISTINCT post_id FROM comments WHERE email = :email

);

首先,增加索引:

$collection->ensureIndex(

 array('comments.email' => 1),

 array('background' => 1)

);

$collection->find( array('comments.email' => $email) );

九、用MongoDB存储文件

MongoDB也提供许多超过基本数据库操作的特点。例如,它提供了在数据库中存储小文件和大文件的解决方案。

文件被自动分块(块)。如果MongoDB运行在自动分片(auto-sharded)环境,文件块也会被跨多个服务器复制。

有效地解决文件的存储是一个相当困难的问题,尤其是当你需要管理大量的文件时。把文件保存在本地文件系统中通常不是个好的方案。

一个困难的例子是YouTube必须有效地服务那些上百万视频的小图片,或者由Facebook为数十亿图片提供的高效运行服务。

MongoDB通过创建两个内部集合(collections)来解决这个问题:文件集合保存关于文件元数据的信息,块集合保存关于文件块的信息。

如果你想存储一个大的视频文件,你可以使用如下这样的代码:

$metadata = array(

 "filename" => "path.avi",

 "downloads" => 0,   

 "comment" => "This file is foo bar",   

 "permissions" => array(

  "crodas" => "write",  

  "everybody" => "read",

 )

);

$grid = $db->getGridFS();

$grid->storeFile("/file/to/path.avi", $metadata);

正如你所看到的,这很简单且容易理解。

十、Map-Reduce

Map-Reduce是一种处理大量信息的操作手段。map操作应用于每个文档并产生一套新的key-value数据对。reduce操作使用map功能产生的结果并产生基本每个key的单一结果。

MongoDB Map-Reduce功能可以应用到集合上用于数据转换,这和Hadoop很类似。

当map处理完成后,结果被保存并且通过键值(key value)被分组。对每个结果键(key),使用2个参数来调用reduce功能:键(key)及其所有值的数组。

为了更好地理解它的工作原理,我们假设有了前面定义过的blog的提交文档,接下来你想使每个提交的内容有一系列的tag,如果你想获得关于这些tag的统计情况,你只需要像下面这样计算一下即可:

首先定义map和reduce功能代码,

$map = new  MongoCode("function () {

  var i;

  for (i=0; i

  

   emit(this.tags[i], {count: 1});

  }

}");

$reduce = new MongoCode("function (key, values) {

  var i, total=0;

  for (i=0; i

   total = values[i].count;

  }

  return {count: total}

}");

然后执行map-reduce命令:

$map_reduce = array(

 

 'out' => 'tags_info',

 

 'verbose' => true,

 

 'mapreduce' => 'posts',

 'map' => $map,

 'reduce' => $reduce,

);

$information = $db->command($map_reduce);

var_dump($information);

如果MongoDB运行在切片(sharded)环境,那么这个数据处理功能将会在所有shard节点上并行。

要知道执行map-reduce处理通常是很慢的。它的目的是把大量的数据分布在许多服务器上。所以,如果你有许多服务器,你就可以把这个操作分布在这些服务器上进行处理并获得结果,这会比在一台服务器上运行所需的时间要少得多。

建议在后台运行map-reduce处理,因为它们需要花比较长的时候才能完成。在这种情况下,如果通过Gearman来异步管理启动它是个不错的方法。

十一、Auto-sharding

在前面多次提到sharding,但你可能并不熟悉这个概念。

Data sharding是一种把数据分布在多个服务器上的数据库技术手段。

MongoDB只需要很少的配置就可完成auto-sharding。然而,安装和配置一个shard已超出本文章的范围。

下面这张图展示了工作在shard环境中的MongoDB,这样你会在你使用sharding时都发生了什么有个了解。

基于MongoDB的php应用开发(2)
 十二、其它

正则表达式使用面面的格式:

"//"

和SQL语句中的 username LIKE '%bar%'等价的方式如下:

$filter = array(

'username' => new MongoRegex("/.*bar.*/i"),

);

$collection->find($filter);

?>

在使用Regex时要小心,大多时候它不能使用索引,因此它将对整个数据扫描,所以比较好的方法是对文档的数目进行限制。

$filter = array(

'username' => new MongoRegex("/.*bar.*/i"),

'karma' => array('$gt' => 10),

);

$collection->find($filter);

?>

使用Regex可以完成如下这个复杂的查询:

$filter = array(

'username' => new MongoRegex("/[a-z][a-z0-9\_]+(\_[0-9])?/i"),

'karma' => array('$gt' => 10),

);

$collection->find($filter);

?>


推荐阅读
  • 如何在U8系统中连接服务器并获取数据
    本文介绍了如何在U8系统中通过不同的方法连接服务器并获取数据,包括使用MySQL客户端连接实例的方法,如非SSL连接和SSL连接,并提供了详细的步骤和注意事项。 ... [详细]
  • 本文详细介绍了如何搭建一个高可用的MongoDB集群,包括环境准备、用户配置、目录创建、MongoDB安装、配置文件设置、集群组件部署等步骤。特别关注分片、读写分离及负载均衡的实现。 ... [详细]
  • 本文探讨了如何在PHP与MySQL环境中实现高效的分页查询,包括基本的分页实现、性能优化技巧以及高级的分页策略。 ... [详细]
  • PHP面试题精选及答案解析
    本文精选了新浪PHP笔试题及最新的PHP面试题,并提供了详细的答案解析,帮助求职者更好地准备PHP相关的面试。 ... [详细]
  • MongoDB核心概念详解
    本文介绍了NoSQL数据库的概念及其应用场景,重点解析了MongoDB的基本特性、数据结构以及常用操作。MongoDB是一个高性能、高可用且易于扩展的文档数据库系统。 ... [详细]
  • 在CentOS 7环境中安装配置Redis及使用Redis Desktop Manager连接时的注意事项与技巧
    在 CentOS 7 环境中安装和配置 Redis 时,需要注意一些关键步骤和最佳实践。本文详细介绍了从安装 Redis 到配置其基本参数的全过程,并提供了使用 Redis Desktop Manager 连接 Redis 服务器的技巧和注意事项。此外,还探讨了如何优化性能和确保数据安全,帮助用户在生产环境中高效地管理和使用 Redis。 ... [详细]
  • H5技术实现经典游戏《贪吃蛇》
    本文将分享一个使用HTML5技术实现的经典小游戏——《贪吃蛇》。通过H5技术,我们将探讨如何构建这款游戏的两种主要玩法:积分闯关和无尽模式。 ... [详细]
  • 软件测试行业深度解析:迈向高薪的必经之路
    本文深入探讨了软件测试行业的发展现状及未来趋势,旨在帮助有志于在该领域取得高薪的技术人员明确职业方向和发展路径。 ... [详细]
  • CentOS下ProFTPD的安装与配置指南
    本文详细介绍在CentOS操作系统上安装和配置ProFTPD服务的方法,包括基本配置、安全设置及高级功能的启用。 ... [详细]
  • 从CodeIgniter中提取图像处理组件
    本指南旨在帮助开发者在未使用CodeIgniter框架的情况下,如何独立使用其强大的图像处理功能,包括图像尺寸调整、创建缩略图、裁剪、旋转及添加水印等。 ... [详细]
  • 精选10款Python框架助力并行与分布式机器学习
    随着神经网络模型的不断深化和复杂化,训练这些模型变得愈发具有挑战性,不仅需要处理大量的权重,还必须克服内存限制等问题。本文将介绍10款优秀的Python框架,帮助开发者高效地实现分布式和并行化的深度学习模型训练。 ... [详细]
  • 本文详细探讨了在Web开发中常见的UTF-8编码问题及其解决方案,包括HTML页面、PHP脚本、MySQL数据库以及JavaScript和Flash应用中的乱码问题。 ... [详细]
  • MySQL Decimal 类型的最大值解析及其在数据处理中的应用艺术
    在关系型数据库中,表的设计与SQL语句的编写对性能的影响至关重要,甚至可占到90%以上。本文将重点探讨MySQL中Decimal类型的最大值及其在数据处理中的应用技巧,通过实例分析和优化建议,帮助读者深入理解并掌握这一重要知识点。 ... [详细]
  • V8不仅是一款著名的八缸发动机,广泛应用于道奇Charger、宾利Continental GT和BossHoss摩托车中。自2008年以来,作为Chromium项目的一部分,V8 JavaScript引擎在性能优化和技术创新方面取得了显著进展。该引擎通过先进的编译技术和高效的垃圾回收机制,显著提升了JavaScript的执行效率,为现代Web应用提供了强大的支持。持续的优化和创新使得V8在处理复杂计算和大规模数据时表现更加出色,成为众多开发者和企业的首选。 ... [详细]
  • 本文深入探讨了NoSQL数据库的四大主要类型:键值对存储、文档存储、列式存储和图数据库。NoSQL(Not Only SQL)是指一系列非关系型数据库系统,它们不依赖于固定模式的数据存储方式,能够灵活处理大规模、高并发的数据需求。键值对存储适用于简单的数据结构;文档存储支持复杂的数据对象;列式存储优化了大数据量的读写性能;而图数据库则擅长处理复杂的关系网络。每种类型的NoSQL数据库都有其独特的优势和应用场景,本文将详细分析它们的特点及应用实例。 ... [详细]
author-avatar
桑语敬
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有