Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

MongoDB and PHP ZendCon 2011

7,119 views

Published on

Published in: Technology
  • Be the first to comment

MongoDB and PHP ZendCon 2011

  1. 1. MongoDB and PHP
  2. 2. My name isSteve Francia @spf13
  3. 3. • 15+ years building the internet• Father, husband, skateboarder• Chief Solutions Architect @ 10gen• Author of upcoming O’Reilly publication “PHP and MongoDB”
  4. 4. Introduction to MongoDB
  5. 5. Why MongoDB?
  6. 6. MongoDB Goals• OpenSource• Designed for today • Today’s hardware / environments • Today’s challenges• Easy development• Reliable• Scalable
  7. 7. • Company behind MongoDB • AGPL license, own copyrights, engineering team • support, consulting, commercial license revenue• Management • Google/DoubleClick, Oracle, Apple, NetApp • Funding: Sequoia, Union Square, Flybridge • Offices in NYC, Redwood Shores & London • 60+ employees
  8. 8. A bit of history
  9. 9. 1974The relational database is created
  10. 10. 1979
  11. 11. 1979 1982-1996
  12. 12. 1979 1982-1996 1995
  13. 13. Computers in 1995•Pentium 100 mhz•10base T•16 MB ram•200 MB HD
  14. 14. Cell Phones in 2011•Dual core 1.5 Ghz•WiFi 802.11n (300+ Mbps)•1 GB ram•64GB Solid State
  15. 15. How about a DBdesigned for today?
  16. 16. It started with DoubleClick
  17. 17. Signs something needed•doubleclick - 400,000 ads/second•caching is de rigueur•complex ORM frameworks•computer architecture increasing in complexity•cloud computing
  18. 18. Requirements We need enough functionality to handle broad set of use cases•strong consistency / atomicity•secondary indexes•ad hoc queries
  19. 19. Trim unneeded features Leave out a few things so we can scale•no choice but to leave out relational•distributed transactions are hard to scale
  20. 20. Needed a scalable data model Considered....•key/value•columnar / tabular•document oriented (JSON inspired)
  21. 21. MongoDB philosphy• Keep functionality when we can (key/ value stores are great, but we need more)• Non-relational (no joins) makes scaling horizontally practical• Document data models are good• Database technology should run anywhere VMs, cloud or straight metal
  22. 22. MongoDB is: Application Document Oriented { author: “steve”, High date: new Date(), text: “About MongoDB...”,Performance tags: [“tech”, “database”]} Fully Consistent Horizontally Scalable
  23. 23. MongoDB•JSON Documents•Querying/Indexing/Updating similar to relational databases•Traditional Consistency•Auto-Sharding
  24. 24. Under the hood•Written in C++•Available on most platforms•Data serialized to BSON•Extensive use of memory-mapped files
  25. 25. Database Landscape
  26. 26. This has led some to say“MongoDB has the bestfeatures of key/ valuesstores, document databasesand relational databases inone. John Nunemaker
  27. 27. Use Cases
  28. 28. CMS / BlogNeeds:• Business needed modern data store for rapid development and scaleSolution:• Use PHP & MongoDBResults:• Real time statistics• All data, images, etc stored together, easy access, easy deployment, easy high availability• No need for complex migrations• Enabled very rapid development and growth
  29. 29. Photo Meta-DataProblem:• Business needed more flexibility than Oracle could deliverSolution:• Use MongoDB instead of OracleResults:• Developed application in one sprint cycle• 500% cost reduction compared to Oracle• 900% performance improvement compared to Oracle
  30. 30. Customer AnalyticsProblem:• Deal with massive data volume across all customer sitesSolution:• Use MongoDB to replace Google Analytics / Omniture optionsResults:• Less than one week to build prototype and prove business case• Rapid deployment of new features
  31. 31. Online DictionaryProblem:• MySQL could not scale to handle their 5B+ documentsSolution:• Switched from MySQL to MongoDBResults:• Massive simplification of code base• Eliminated need for external caching system• 20x performance improvement over MySQL
  32. 32. E-commerceProblem:• Multi-vertical E-commerce impossible to model (efficiently) in RDBMSSolution:• Switched from MySQL to MongoDBResults:• Massive simplification of code base• Rapidly build, halving time to market (and cost)• Eliminated need for external caching system• 50x+ improvement over MySQL
  33. 33. Tons morePretty much if you can use a RDMBS or Key/Value MongoDB is a great fit
  34. 34. In Good Company
  35. 35. MongoDB in PHP
  36. 36. Relational made normalized data look like this
  37. 37. Document databases makenormalized data look like this
  38. 38. Terminology RDBMS MongoTable, View ➜ CollectionRow ➜ JSON DocumentIndex ➜ IndexJoin ➜ Embedded DocumentPartition ➜ ShardPartition Key ➜ Shard Key
  39. 39. Documents to ObjectsDocuments to Arrays Tables to Documents { PostObject Object( [title] => MongoDB title: ‘MongoDB’, [contributors] => Array( contributors: [ [0] => PersonObject Object( { name: ‘Eliot Horowitz’, [name] => Eliot Horowitz [email] => eh@10gen.com email: ‘eh@10gen.com’ }, ) { name: PersonObjectMerriman’, [1] => ‘Dwight Object( email: ‘dm@10gen.com’ } [name] => Dwight Merriman [email] => dm@10gen.com ], ) model: { ) relational: false, [model] => ModelObject Object( [relational] => awesome:=>true [awesome] 1 }) ) }
  40. 40. Documents to Objects Documents to Arrays Tables to Documents{ array( PostObject Object( title: ‘MongoDB’, "title" =>=> MongoDB [title] MongoDB, "contributors" =>=> Array( [contributors] array( contributors: [ array( => PersonObject Object( [0] { name: ‘Eliot Horowitz’, name => Eliot Horowitz, [name] => Eliot Horowitz email: ‘eh@10gen.com’ }, email => eh@10gen.com [email] => eh@10gen.com ), ) { name: ‘Dwight Merriman’, array( => PersonObject Object( [1] email: ‘dm@10gen.com’ } name => Dwight Merriman, [name] => Dwight Merriman email => dm@10gen.com [email] => dm@10gen.com ], ) ) model: { ),) relational: false, "model" =>=> ModelObject Object( [model] array( relational => false, [relational] awesome: true awesome => true [awesome] 1 } ) )} )
  41. 41. Documents to Objects Documents to Arrays Tables to Documents{ array( PostObject Object( title: ‘MongoDB’, "title" =>=> MongoDB [title] MongoDB, "contributors" =>=> Array( [contributors] array( contributors: [ array( => PersonObject Object( [0] { name: ‘Eliot Horowitz’, name => Eliot Horowitz, [name] => Eliot Horowitz email: ‘eh@10gen.com’ }, email => eh@10gen.com [email] => eh@10gen.com ), ) { name: ‘Dwight Merriman’, array( => PersonObject Object( [1] email: ‘dm@10gen.com’ } name => Dwight Merriman, [name] => Dwight Merriman email => dm@10gen.com [email] => dm@10gen.com ], ) ) model: { ),) relational: false, "model" =>=> ModelObject Object( [model] array( relational => false, [relational] awesome: true awesome => true [awesome] 1 } ) )} )
  42. 42. MongoDB speaks PHP
  43. 43. This has led some to say“The single best interface(API) of any phpextension.   Matthew Weier OPhinney
  44. 44. PHP DriverInstalling the driver $ pecl install mongoAdd to php.ini extension = mongo.so
  45. 45. Connecting to the DB$connection = new Mongo();$db = $connection->selectDB(blog);$posts = $db->post;If the DB or collection doesn’t exist,mongoDB will create it on connect.
  46. 46. DocumentsBlog Post Document$p1 = array("author" => "roger", "date" => new MongoDate(), "text" => "about mongoDB...", "tags" => array(tech, databases) );$posts->save($p1);
  47. 47. Queryingprint_r($posts->findOne());> db.posts.findOne()Array( [_id] => MongoId Object(> { _id : ObjectId("4c4ba5c0672c685e5e8aabf3"), [$id] => 4e9796764a18173a17000000 author : "roger", ) date : "Sat Jul 24 2010 19:47:11", [author] => roger text : "About MongoDB...", [date] => MongoDate Object( tags : [ "tech", "databases" ] } [sec] => 1318557302 [usec] => 581000 ) [text] => about mongoDB... [tags] => Array( Note: _id is unique, but can be anything [0] => tech [1] => databasesyou’d like ))
  48. 48. Queryingprint_r($posts->findOne());> db.posts.findOne()Array( [_id] => MongoId Object(> { _id : ObjectId("4c4ba5c0672c685e5e8aabf3"), [$id] => 4e9796764a18173a17000000 author : "roger", ) date : "Sat Jul 24 2010 19:47:11", [author] => roger text : "About MongoDB...", [date] => MongoDate Object( tags : [ "tech", "databases" ] } [sec] => 1318557302 [usec] => 581000 ) [text] => about mongoDB... [tags] => Array( Note: _id is unique, but can be anything [0] => tech [1] => databasesyou’d like ))
  49. 49. Inserting Objectsclass PostObj { public $comments = array(); public function __construct($author, $title, $content){ $this->author = $author; $this->title = $title; $this->content = $content; }}$posts->insert(new PostObj("Steve", "My first blog post", "Hello, World!"));
  50. 50. MongoIdAn autogenerated primary key$x = array("foo" => 1, "bar" => 2);$db->baz->save($x);var_dump($x[_id]);Result:object(MongoId)#4 (1) { ["$id"]=> string(24) "4e9cc76a4a1817fd21000000"}
  51. 51. MongoIdAn autogenerated primary keyobject(MongoId)#4 (1) { ["$id"]=> string(24) "4e9cc76a4a1817fd21000000"} 4e9cc76a4a1817fd21000000 |------||----||--||----| ts mac pid inc
  52. 52. Update Operations $set, $unset, $inc, $push, $pushAll, $pull, $pullAll, $bit$change = array($push => array(comments => array( author => Fred, created => new MongoDate(), comment => Best post ever!. ) ) );$posts->update(array("_id" => $id), $change);
  53. 53. Nested DocumentsArray( { _id : ObjectId("4c4ba5c0672c685e5e8aabf3"), [_id] => MongoId Object ( [$id] => 4e9796764a18173a17000000 ) author : "roger", [author] => roger date : "Sat Apr 24 2011 19:47:11", [comments] => Array( text : "About MongoDB...", [0] => Array( [author] => Fred tags : [ "tech", "databases" ], [created] => MongoDate Object( [sec] => 1318899392 comments : [ [usec] => 176000 ) { [comment] => Dumb post. ) ) author : "Fred", [date] => MongoDate Object( date : "Sat Apr 25 2010 20:51:03 GMT-0700", [sec] => 1318557302 [usec] => 581000 ) text : "Best Post Ever!" [tags] => Array( } [0] => tech ) ] [1] => databases}) [text] => about mongoDB...
  54. 54. Nested DocumentsArray( { _id : ObjectId("4c4ba5c0672c685e5e8aabf3"), [_id] => MongoId Object ( [$id] => 4e9796764a18173a17000000 ) author : "roger", [author] => roger date : "Sat Apr 24 2011 19:47:11", [comments] => Array( text : "About MongoDB...", [0] => Array( [author] => Fred tags : [ "tech", "databases" ], [created] => MongoDate Object( [sec] => 1318899392 comments : [ [usec] => 176000 ) { [comment] => Dumb post. ) ) author : "Fred", [date] => MongoDate Object( date : "Sat Apr 25 2010 20:51:03 GMT-0700", [sec] => 1318557302 [usec] => 581000 ) text : "Best Post Ever!" [tags] => Array( } [0] => tech ) ] [1] => databases}) [text] => about mongoDB...
  55. 55. Querying$posts = $blog->find(array( "author" => "Roger"));$commentsByFred = $blog->find(array( "comments.author" => "Fred"));$commentsByFred = $blog->find(array( "comments.author" => new MongoRegex("/fred/i")));
  56. 56. It’s all about the $ $ instead of >, <, =, etc. $gt, $gte, $lt, $lte, $eq, $neq, $exists, $set, $mod, $where, $in, $nin, $inc $push, $pull, $pop, $pushAll, $popAll$c->find(array("x" => array($gt => 4)));$c->find(array("x" => array(“$gt” => 4)));
  57. 57. It’s all about the $ $ instead of >, <, =, etc. $gt, $gte, $lt, $lte, $eq, $neq, $exists, $set, $mod, $where, $in, $nin, $inc $push, $pull, $pop, $pushAll, $popAll$c->find(array("x" => array($gt => 4)));$c->find(array("x" => array(“$gt” => 4)));
  58. 58. Adjust the behavior in php.ini or using ini_set()php.ini---------------mongo.cmd = ":"$c->find(array("x" => array(:gt => 4))); orini_set("mongo.cmd", ".");$c->find(array("x" => array(.gt => 4)));
  59. 59. Indexing including secondary and compound indexes$people->ensureIndex(array("age" => 1));$people->ensureIndex(array( "name" => -1, "ts" => -1, "comments.author" => 1));
  60. 60. More Indexing// Index nested documents$posts->ensureIndex( array("comments.author" => 1) )$posts->find( array("comments.author" => "Fred") )// Index on tags (multi-key index)$posts->ensureIndex( array("tags" => 1 ) )$posts->find( array("tags" => "tech") )// geospatial index$posts->ensureIndex( array("author.location" => "2d") )$posts->find( array("author.location" => array( $near => array(22,42)));
  61. 61. Cursors$cursor = $c->find(array("foo" => "bar"))foreach ($cursor as $id => $value) { echo "$id: "; var_dump( $value );}$a = iterator_to_array($cursor);
  62. 62. Paging$page_num = 3;$results_per_page = 10;$cursor = $results->find() ->sort(array("ts" => -1)) ->skip($page_num * $results_per_page) ->limit($results_per_page);
  63. 63. Rich Documents{ _id : ObjectId("4c4ba5c0672c685e5e8aabf3"), line_items : [ { sku: ‘tt-123’, name: ‘Coltrane: Impressions’ }, { sku: ‘tt-457’, name: ‘Davis: Kind of Blue’ } ], address : { name: ‘Banker’, street: ‘111 Main’, zip: 10010 }, payment: { cc: 4567, exp: Date(2011, 7, 7) }, subtotal: 2355}
  64. 64. Grid FS
  65. 65. Storing FilesUnder 16mb
  66. 66. Storing Big Files>16mb stored in 16mb chunks
  67. 67. Storing Big FilesWorks with replicatedand sharded systems
  68. 68. A better network FS• GridFS files are seamlessly sharded & replicated.• No OS constraints... • No file size limits • No naming constraints • No folder limits • Standard across different OSs• MongoDB automatically generate the MD5 hash of the file
  69. 69. Storing Files$grid = $db->getGridFS();// The files location in the File System$path = "/tmp/";$filename = "movie.mp4";// Note metadata field & filename field$storedfile = $grid->storeFile($path . $filename,array("metadata" => array("filename" => $filename),"filename" => $filename));// Return newly stored files Document IDecho $storedfile;
  70. 70. Storing Data$grid = $db->getGridFS();$filename = "zelda.jpg";$storedfile = $grid->storeBytes("ÿØÿà^@^PJFIF^@^A^A^A,^G^E^E^G,...", array("metadata" => array("filename" =>$filename), "filename" => $filename));
  71. 71. Streaming Data$gridFS = $db->getGridFS();// Find image to stream$image = $gridFS->findOne("zelda.jpg");// Stream image to browserheader(Content-type: image/jpeg);echo $image->getBytes();
  72. 72. PHP Libraries for MongoDB
  73. 73. Libraries & Frameworks• Doctrine MongoDB ODM • Zend Framework• Active Mongo • Lithium• Mongo Queue • Symfony2• Morph • Fuel• Mandango • Fat Free Framework
  74. 74. Doctrine MongoDB ODM• Provides full validation• Seamless integration with Doctrine ORM • Useful for hybrid solutions• Follows same persistence model as Doctrine• Uses a Document Manager & annotations• Supports embedded and referenced objects• Can use mongo’s query interface• Supports in place updates https://github.com/doctrine/mongodb-odm
  75. 75. Mandango•Very light and fast•Event support•Supports embedded and referenced objects•uses the mongo query syntax•Lacking validation, but events can be utilized to validate https://github.com/mandango/mandango
  76. 76. Active Mongo•Uses ActiveRecord (active document) interface•Supports full validation•Supports in place updating•Uses native query interface•Supports referenced documents https://github.com/crodas/ActiveMongo
  77. 77. Morph•Follows the Active Record model•Has own query object (Morph_Query)•Doesn’t provide validation•Doesn’t support embedded or referenced objects. https://github.com/a-musing-moose/morph
  78. 78. Mongo Queue An extensible job/message queueing system that uses mongodb as the persistent storage engine.• Fully Configurable• Distributed• Atomic Locking• Priority Support• Worker Timeout Support• Stable https://github.com/skiz/mongo_queue
  79. 79. http://spf13.com http://github.com/spf13 @spf13 Questions? download at mongodb.orgPS: We’re hiring!! Contact us at jobs@10gen.com

×