Entity Relationships ina Document Database    MapReduce Views for SQL Users
When to Choose aDocument DatabaseYou’re using a relational database, but have been relyingheavily on denormalization to op...
When Not to Choose aDocument DatabaseYour data fits better in a relational model—SQL is a powerfuland mature language for ...
Incremental Map/Reduce"How fucked is my NoSQL database?" howfuckedismydatabase.com. 2009. http://howfuckedismydatabase.com...
EntityRelationshipModel
Join vs. Collation
SQL Query JoiningPublishers and BooksSELECT  `publisher`.`id`,  `publisher`.`name`,  `book`.`title`FROM `publisher`FULL OU...
Joined Result Set     Publisher (“left”)            Book “right”publisher.id publisher.name          book.title           ...
Collated Result Set    key            id                 value["oreilly",0]   "oreilly"        "OReilly Media"        Publ...
View Result SetsMade up of columns and rowsEvery row has the same three columns:  • key  • id  • valueColumns can contain ...
One to Many Relationships
Embedded Entities:Nest related entities within a document
Embedded EntitiesA single document represents the “one” entityNested entities (JSON Array) represents the “many” entitiesS...
Example: Publisherwith Nested Books{  "_id":"oreilly",  "collection":"publisher",  "name":"OReilly Media",  "books":[    {...
Map Functionfunction(doc) {  if ("publisher" == doc.collection) {    emit([doc._id, 0], doc.name);    for (var i in doc.bo...
Result Set     key            id                 value ["oreilly",0]   "oreilly"        "OReilly Media"                   ...
LimitationsOnly works if there aren’t a large number of related entities: • Too many nested entities can result in very la...
Related Documents:Reference an entity by its identifier
Related DocumentsA document representing the “one” entitySeparate documents for each “many” entityEach “many” entity refer...
Example: Publisher{    "_id":"oreilly",    "collection":"publisher",    "name":"OReilly Media"}
Example: Related Book{    "_id":"9780596155896",    "collection":"book",    "title":"CouchDB: The Definitive Guide",    "p...
Map Functionfunction(doc) {  if ("publisher" == doc.collection) {    emit([doc._id, 0], doc.name);  }  if ("book" == doc.c...
Result Set      key                   id              value["oreilly",0]   "oreilly"         "OReilly Media"              ...
LimitationsWhen retrieving the entity on the “right” side of the relationship,one cannot include any data from the entity ...
Many to Many Relationships
List of Keys:Reference entities by their identifiers
List of KeysA document representing each “many” entity on the “left” sideof the relationshipSeparate documents for each “m...
Books and Related Authors
Example: Book{    "_id":"9780596805029",    "collection":"book",    "title":"DocBook 5: The Definitive Guide"}
Example: Book{    "_id":"9781565920514",    "collection":"book",    "title":"Making TeX Work"}
Example: Book{    "_id":"9781565925809",    "collection":"book",    "title":"DocBook: The Definitive Guide"}
Example: Author{    "_id":"muellner",    "collection":"author",    "name":"Leonard Muellner",    "books":[      "978156592...
Example: Author{    "_id":"walsh",    "collection":"author",    "name":"Norman Walsh",    "books":[      "9780596805029", ...
Map Functionfunction(doc) {  if ("book" == doc.collection) {    emit([doc._id, 0], doc.title);  }  if ("author" == doc.col...
Result Set        key                   id                  value["9780596805029",0] "9780596805029" "DocBook 5: The Defini...
Authors and Related Books
Map Functionfunction(doc) {  if ("author" == doc.collection) {    emit([doc._id, 0], doc.name);    for (var i in doc.books...
Result Set      key              id              value["muellner",0]   "muellner"   "Leonard Muellner"["muellner",1]   "mu...
Including Docs  include_docs=true     key          id    value               doc (truncated)["muellner",0] "muellner" …   ...
Or, we can reverse the references…
Example: Author{    "_id":"muellner",    "collection":"author",    "name":"Leonard Muellner"}
Example: Author{    "_id":"walsh",    "collection":"author",    "name":"Norman Walsh"}
Example: Book{    "_id":"9780596805029",    "collection":"book",    "title":"DocBook 5: The Definitive Guide",    "authors...
Example: Book{    "_id":"9781565920514",    "collection":"book",    "title":"Making TeX Work",    "authors":[      "walsh"...
Example: Book{    "_id":"9781565925809",    "collection":"book",    "title":"DocBook: The Definitive Guide",    "authors":...
Map Functionfunction(doc) {  if ("author" == doc.collection) {    emit([doc._id, 0], doc.name);  }  if ("book" == doc.coll...
Result Set     key                id                  value["muellner",0] "muellner"     "Leonard Muellner"["muellner",1] ...
LimitationsQueries from the “right” side of the relationship cannot includeany data from entities on the “left” side of th...
Relationship Documents:Create a document to represent eachindividual relationship
Relationship DocumentsA document representing each “many” entity on the “left” sideof the relationshipSeparate documents f...
Example: Book{    "_id":"9780596805029",    "collection":"book",    "title":"DocBook 5: The Definitive Guide"}
Example: Book{    "_id":"9781565920514",    "collection":"book",    "title":"Making TeX Work"}
Example: Book{    "_id":"9781565925809",    "collection":"book",    "title":"DocBook: The Definitive Guide"}
Example: Author{    "_id":"muellner",    "collection":"author",    "name":"Leonard Muellner"}
Example: Author{    "_id":"walsh",    "collection":"author",    "name":"Norman Walsh"}
Example:Relationship Document{    "_id":"44005f2c",    "collection":"book-author",    "book":"9780596805029",    "author":...
Example:Relationship Document{    "_id":"44005f72",    "collection":"book-author",    "book":"9781565920514",    "author":...
Example:Relationship Document{    "_id":"44006720",    "collection":"book-author",    "book":"9781565925809",    "author":...
Example:Relationship Document{    "_id":"44006b0d",    "collection":"book-author",    "book":"9781565925809",    "author":...
Books and Related Authors
Map Functionfunction(doc) {  if ("book" == doc.collection) {    emit([doc._id, 0], doc.title);  }  if ("book-author" == do...
Result Set       key                 id                         value["9780596805029",0] "9780596805029" "DocBook 5: The D...
Including Docs  include_docs=true      key         id value               doc (truncated)["9780596805029",0] … …      {"ti...
Authors and Related Books
Map Functionfunction(doc) {  if ("author" == doc.collection) {    emit([doc._id, 0], doc.name);  }  if ("book-author" == d...
Result Set      key              id              value["muellner",0]   "muellner"   "Leonard Muellner"["muellner",1]   "44...
Including Docsinclude_docs=true     key       id value               doc (truncated)["muellner",0] …   …      {"name":"Leo...
LimitationsQueries can only contain data from the “left” or “right” side of therelationship (without the use of include_do...
Doctrine’s Object-DocumentMapper (ODM)
Doctrine CouchDB[1]                      1. http://docs.doctrine-project.org/projects/doctrine-couchdb/
FeaturesIncludes a CouchDB client library and ODMMaps documents using Doctrine’s persistence semanticsMaps CouchDB views t...
Defining an                              Entity[1]/** @Document */class BlogPost{    /** @Id */    private $id;    /** @Fi...
Persisting an                                 Entity[1]$blogPost = new BlogPost();$blogPost->setHeadline("Hello World!");$...
Querying an                              Entity[1]// $dm is an instance of DoctrineODMCouchDBDocumentManager$blogPost = $d...
Doctrine MongoDB ODM [1]                  1. http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/
FeaturesMaps documents using Doctrine’s persistence semanticsMap embedded documentsMap referenced documentsUses batch inse...
Defining                          Entities[1]/** @MappedSuperclass */abstract class BaseEmployee{    /** @Id */    private...
Defining                          Entities[1]/** @Document */class Employee extends BaseEmployee{    /** @ReferenceOne(tar...
Defining                          Entities[1]/** @Document */class Manager extends BaseEmployee{    /** @ReferenceMany(tar...
Defining                          Entities[1]/** @EmbeddedDocument */class Address{    /** @String */    private $address;...
Defining                          Entities[1]/** @Document */class Project{    /** @Id */    private $id;    /** @String *...
Persisting                            Entities[1]$employee = new Employee();$employee->setName(Employee);$employee->setSal...
Persisting                            Entities[1]$address = new Address();$address->setAddress(555 Doctrine Rd.);$address-...
Persisting                            Entities[1]$project = new Project(New Project);$manager = new Manager();$manager->se...
Persisting                            Entities[1]// $dm is an instance of DoctrineODMMongoDBDocumentManager$dm->persist($e...
Querying an Entity// $dm is an instance of DoctrineODMMongoDBDocumentManager$manager = $dm->find("DocumentsManager",$theID);
Final Thoughts
Document Databases Comparedto Relational DatabasesDocument databases have no tables (and therefore no columns)Indexes (vie...
CaveatsNo referential integrityNo atomic transactions across document boundariesSome patterns may involve denormalized (i....
Additional TechniquesUse the startkey and endkey parameters to retrieve one entity andits related entities: startkey=["978...
Cheat Sheet                  Embedded     Related                 Relationship                                          Li...
http://oreilly.com/catalog/9781449303129/   http://oreilly.com/catalog/9781449303433/
Thank You                                   @BradleyHolt                              http://bradley-holt.com             ...
Upcoming SlideShare
Loading in...5
×

Entity Relationships in a Document Database at ZendCon 2012

1,048
-1

Published on

Unlike relational databases, document databases like CouchDB and MongoDB do not directly support entity relationships. This talk will explore patterns of modeling one-to-many and many-to-many entity relationships in a document database. These patterns include using an embedded JSON array, relating documents using identifiers, using a list of keys, and using relationship documents. This talk will explore how these entity relationship patterns equate to how entities are joined in a relational database. We'll take a look at the relevant differences between document databases and relational databases. For example, document databases do not have tables, each document can have its own schema, there is no built-in concept of relationships between documents, views/indexes are queried directly instead of being used to optimize more generalized queries, a column within a result set can contain a mix of logical data types, and there is typically no support for transactions across document boundaries.

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,048
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
16
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Entity Relationships in a Document Database at ZendCon 2012

  1. 1. Entity Relationships ina Document Database MapReduce Views for SQL Users
  2. 2. When to Choose aDocument DatabaseYou’re using a relational database, but have been relyingheavily on denormalization to optimize read performanceYou would like to give up consistency in exchange for ahigh level of concurrencyYour data model is a “fit” for documents (e.g. a CMS)
  3. 3. When Not to Choose aDocument DatabaseYour data fits better in a relational model—SQL is a powerfuland mature language for working with relational data setsConsistency is critical to your applicationYou haven’t bothered exploring scalability options foryour current database
  4. 4. Incremental Map/Reduce"How fucked is my NoSQL database?" howfuckedismydatabase.com. 2009. http://howfuckedismydatabase.com/nosql/ (24 October 2012).
  5. 5. EntityRelationshipModel
  6. 6. Join vs. Collation
  7. 7. SQL Query JoiningPublishers and BooksSELECT `publisher`.`id`, `publisher`.`name`, `book`.`title`FROM `publisher`FULL OUTER JOIN `book` ON `publisher`.`id` = `book`.`publisher_id`ORDER BY `publisher`.`id`, `book`.`title`;
  8. 8. Joined Result Set Publisher (“left”) Book “right”publisher.id publisher.name book.title Building iPhone Apps with oreilly OReilly Media HTML, CSS, and JavaScript CouchDB: The Definitive oreilly OReilly Media Guide DocBook: The Definitive oreilly OReilly Media Guide oreilly OReilly Media RESTful Web Services
  9. 9. Collated Result Set key id value["oreilly",0] "oreilly" "OReilly Media" Publisher "Building iPhone Apps with["oreilly",1] "oreilly" HTML, CSS, and JavaScript" "CouchDB: The Definitive["oreilly",1] "oreilly" Guide" Books "DocBook: The Definitive["oreilly",1] "oreilly" Guide"["oreilly",1] "oreilly" "RESTful Web Services"
  10. 10. View Result SetsMade up of columns and rowsEvery row has the same three columns: • key • id • valueColumns can contain a mixture of logical data types
  11. 11. One to Many Relationships
  12. 12. Embedded Entities:Nest related entities within a document
  13. 13. Embedded EntitiesA single document represents the “one” entityNested entities (JSON Array) represents the “many” entitiesSimplest way to create a one to many relationship
  14. 14. Example: Publisherwith Nested Books{ "_id":"oreilly", "collection":"publisher", "name":"OReilly Media", "books":[ { "title":"CouchDB: The Definitive Guide" }, { "title":"RESTful Web Services" }, { "title":"DocBook: The Definitive Guide" }, { "title":"Building iPhone Apps with HTML, CSS,and JavaScript" } ]}
  15. 15. Map Functionfunction(doc) { if ("publisher" == doc.collection) { emit([doc._id, 0], doc.name); for (var i in doc.books) { emit([doc._id, 1], doc.books[i].title); } }}
  16. 16. Result Set key id value ["oreilly",0] "oreilly" "OReilly Media" "Building iPhone Apps with ["oreilly",1] "oreilly" HTML, CSS, and JavaScript" "CouchDB: The Definitive ["oreilly",1] "oreilly" Guide" "DocBook: The Definitive ["oreilly",1] "oreilly" Guide" ["oreilly",1] "oreilly" "RESTful Web Services"
  17. 17. LimitationsOnly works if there aren’t a large number of related entities: • Too many nested entities can result in very large documents • Slow to transfer between client and server • Unwieldy to modify • Time-consuming to index
  18. 18. Related Documents:Reference an entity by its identifier
  19. 19. Related DocumentsA document representing the “one” entitySeparate documents for each “many” entityEach “many” entity references its related“one” entity by the “one” entity’s document identifierMakes for smaller documentsReduces the probability of document update conflicts
  20. 20. Example: Publisher{ "_id":"oreilly", "collection":"publisher", "name":"OReilly Media"}
  21. 21. Example: Related Book{ "_id":"9780596155896", "collection":"book", "title":"CouchDB: The Definitive Guide", "publisher":"oreilly"}
  22. 22. Map Functionfunction(doc) { if ("publisher" == doc.collection) { emit([doc._id, 0], doc.name); } if ("book" == doc.collection) { emit([doc.publisher, 1], doc.title); }}
  23. 23. Result Set key id value["oreilly",0] "oreilly" "OReilly Media" "CouchDB: The Definitive["oreilly",1] "9780596155896" Guide"["oreilly",1] "9780596529260" "RESTful Web Services" "Building iPhone Apps with["oreilly",1] "9780596805791" HTML, CSS, and JavaScript" "DocBook: The Definitive["oreilly",1] "9781565925809" Guide"
  24. 24. LimitationsWhen retrieving the entity on the “right” side of the relationship,one cannot include any data from the entity on the “left” side ofthe relationship without the use of an additional queryOnly works for one to many relationships
  25. 25. Many to Many Relationships
  26. 26. List of Keys:Reference entities by their identifiers
  27. 27. List of KeysA document representing each “many” entity on the “left” sideof the relationshipSeparate documents for each “many” entity on the “right” sideof the relationshipEach “many” entity on the “right” side of the relationshipmaintains a list of document identifiers for its related “many”entities on the “left” side of the relationship
  28. 28. Books and Related Authors
  29. 29. Example: Book{ "_id":"9780596805029", "collection":"book", "title":"DocBook 5: The Definitive Guide"}
  30. 30. Example: Book{ "_id":"9781565920514", "collection":"book", "title":"Making TeX Work"}
  31. 31. Example: Book{ "_id":"9781565925809", "collection":"book", "title":"DocBook: The Definitive Guide"}
  32. 32. Example: Author{ "_id":"muellner", "collection":"author", "name":"Leonard Muellner", "books":[ "9781565925809" ]}
  33. 33. Example: Author{ "_id":"walsh", "collection":"author", "name":"Norman Walsh", "books":[ "9780596805029", "9781565925809", "9781565920514" ]}
  34. 34. Map Functionfunction(doc) { if ("book" == doc.collection) { emit([doc._id, 0], doc.title); } if ("author" == doc.collection) { for (var i in doc.books) { emit([doc.books[i], 1], doc.name); } }}
  35. 35. Result Set key id value["9780596805029",0] "9780596805029" "DocBook 5: The Definitive Guide"["9780596805029",1] "walsh" "Norman Walsh"["9781565920514",0] "9781565920514" "Making TeX Work"["9781565920514",1] "walsh" "Norman Walsh"["9781565925809",0] "9781565925809" "DocBook: The Definitive Guide"["9781565925809",1] "muellner" "Leonard Muellner"["9781565925809",1] "walsh" "Norman Walsh"
  36. 36. Authors and Related Books
  37. 37. Map Functionfunction(doc) { if ("author" == doc.collection) { emit([doc._id, 0], doc.name); for (var i in doc.books) { emit([doc._id, 1], {"_id":doc.books[i]}); } }}
  38. 38. Result Set key id value["muellner",0] "muellner" "Leonard Muellner"["muellner",1] "muellner" {"_id":"9781565925809"}["walsh",0] "walsh" "Norman Walsh"["walsh",1] "walsh" {"_id":"9780596805029"}["walsh",1] "walsh" {"_id":"9781565920514"}["walsh",1] "walsh" {"_id":"9781565925809"}
  39. 39. Including Docs include_docs=true key id value doc (truncated)["muellner",0] "muellner" … {"name":"Leonard Muellner"}["muellner",1] "muellner" … {"title":"DocBook: The Definitive Guide"}["walsh",0] "walsh" … {"name":"Norman Walsh"}["walsh",1] "walsh" … {"title":"DocBook 5: The Definitive Guide"}["walsh",1] "walsh" … {"title":"Making TeX Work"}["walsh",1] "walsh" … {"title":"DocBook: The Definitive Guide"}
  40. 40. Or, we can reverse the references…
  41. 41. Example: Author{ "_id":"muellner", "collection":"author", "name":"Leonard Muellner"}
  42. 42. Example: Author{ "_id":"walsh", "collection":"author", "name":"Norman Walsh"}
  43. 43. Example: Book{ "_id":"9780596805029", "collection":"book", "title":"DocBook 5: The Definitive Guide", "authors":[ "walsh" ]}
  44. 44. Example: Book{ "_id":"9781565920514", "collection":"book", "title":"Making TeX Work", "authors":[ "walsh" ]}
  45. 45. Example: Book{ "_id":"9781565925809", "collection":"book", "title":"DocBook: The Definitive Guide", "authors":[ "muellner", "walsh" ]}
  46. 46. Map Functionfunction(doc) { if ("author" == doc.collection) { emit([doc._id, 0], doc.name); } if ("book" == doc.collection) { for (var i in doc.authors) { emit([doc.authors[i], 1], doc.title); } }}
  47. 47. Result Set key id value["muellner",0] "muellner" "Leonard Muellner"["muellner",1] "9781565925809" "DocBook: The Definitive Guide"["walsh",0] "walsh" "Norman Walsh"["walsh",1] "9780596805029" "DocBook 5: The Definitive Guide"["walsh",1] "9781565920514" "Making TeX Work"["walsh",1] "9781565925809" "DocBook: The Definitive Guide"
  48. 48. LimitationsQueries from the “right” side of the relationship cannot includeany data from entities on the “left” side of the relationship(without the use of include_docs)A document representing an entity with lots of relationshipscould become quite large
  49. 49. Relationship Documents:Create a document to represent eachindividual relationship
  50. 50. Relationship DocumentsA document representing each “many” entity on the “left” sideof the relationshipSeparate documents for each “many” entity on the “right” sideof the relationshipNeither the “left” nor “right” side of the relationship contain anydirect references to each otherFor each distinct relationship, a separate document includes thedocument identifiers for both the “left” and “right” sides of therelationship
  51. 51. Example: Book{ "_id":"9780596805029", "collection":"book", "title":"DocBook 5: The Definitive Guide"}
  52. 52. Example: Book{ "_id":"9781565920514", "collection":"book", "title":"Making TeX Work"}
  53. 53. Example: Book{ "_id":"9781565925809", "collection":"book", "title":"DocBook: The Definitive Guide"}
  54. 54. Example: Author{ "_id":"muellner", "collection":"author", "name":"Leonard Muellner"}
  55. 55. Example: Author{ "_id":"walsh", "collection":"author", "name":"Norman Walsh"}
  56. 56. Example:Relationship Document{ "_id":"44005f2c", "collection":"book-author", "book":"9780596805029", "author":"walsh"}
  57. 57. Example:Relationship Document{ "_id":"44005f72", "collection":"book-author", "book":"9781565920514", "author":"walsh"}
  58. 58. Example:Relationship Document{ "_id":"44006720", "collection":"book-author", "book":"9781565925809", "author":"muellner"}
  59. 59. Example:Relationship Document{ "_id":"44006b0d", "collection":"book-author", "book":"9781565925809", "author":"walsh"}
  60. 60. Books and Related Authors
  61. 61. Map Functionfunction(doc) { if ("book" == doc.collection) { emit([doc._id, 0], doc.title); } if ("book-author" == doc.collection) { emit([doc.book, 1], {"_id":doc.author}); }}
  62. 62. Result Set key id value["9780596805029",0] "9780596805029" "DocBook 5: The Definitive Guide"["9780596805029",1] "44005f2c" {"_id":"walsh"}["9781565920514",0] "9781565920514" "Making TeX Work"["9781565920514",1] "44005f72" {"_id":"walsh"}["9781565925809",0] "9781565925809" "DocBook: The Definitive Guide"["9781565925809",1] "44006720" {"_id":"muellner"}["9781565925809",1] "44006b0d" {"_id":"walsh"}
  63. 63. Including Docs include_docs=true key id value doc (truncated)["9780596805029",0] … … {"title":"DocBook 5: The Definitive Guide"}["9780596805029",1] … … {"name":"Norman Walsh"}["9781565920514",0] … … {"title":"Making TeX Work"}["9781565920514",1] … … {"author","name":"Norman Walsh"}["9781565925809",0] … … {"title":"DocBook: The Definitive Guide"}["9781565925809",1] … … {"name":"Leonard Muellner"}["9781565925809",1] … … {"name":"Norman Walsh"}
  64. 64. Authors and Related Books
  65. 65. Map Functionfunction(doc) { if ("author" == doc.collection) { emit([doc._id, 0], doc.name); } if ("book-author" == doc.collection) { emit([doc.author, 1], {"_id":doc.book}); }}
  66. 66. Result Set key id value["muellner",0] "muellner" "Leonard Muellner"["muellner",1] "44006720" {"_id":"9781565925809"}["walsh",0] "walsh" "Norman Walsh"["walsh",1] "44005f2c" {"_id":"9780596805029"}["walsh",1] "44005f72" {"_id":"9781565920514"}["walsh",1] "44006b0d" {"_id":"9781565925809"}
  67. 67. Including Docsinclude_docs=true key id value doc (truncated)["muellner",0] … … {"name":"Leonard Muellner"}["muellner",1] … … {"title":"DocBook: The Definitive Guide"}["walsh",0] … … {"name":"Norman Walsh"}["walsh",1] … … {"title":"DocBook 5: The Definitive Guide"}["walsh",1] … … {"title":"Making TeX Work"}["walsh",1] … … {"title":"DocBook: The Definitive Guide"}
  68. 68. LimitationsQueries can only contain data from the “left” or “right” side of therelationship (without the use of include_docs)Maintaining relationship documents may require more work
  69. 69. Doctrine’s Object-DocumentMapper (ODM)
  70. 70. Doctrine CouchDB[1] 1. http://docs.doctrine-project.org/projects/doctrine-couchdb/
  71. 71. FeaturesIncludes a CouchDB client library and ODMMaps documents using Doctrine’s persistence semanticsMaps CouchDB views to PHP objectsDocument conflict resolution supportIncludes a write-behind feature for increased performance
  72. 72. Defining an Entity[1]/** @Document */class BlogPost{ /** @Id */ private $id; /** @Field(type="string") */ private $headline; /** @Field(type="string") */ private $text; /** @Field(type="datetime") */ private $publishDate; // getter/setter here} 1. http://docs.doctrine-project.org/projects/doctrine-couchdb/en/latest/reference/introduction.html#architecture
  73. 73. Persisting an Entity[1]$blogPost = new BlogPost();$blogPost->setHeadline("Hello World!");$blogPost->setText("This is a blog post going tobe saved into CouchDB");$blogPost->setPublishDate(new DateTime("now"));$dm->persist($blogPost);$dm->flush(); 1. http://docs.doctrine-project.org/projects/doctrine-couchdb/en/latest/reference/introduction.html#architecture
  74. 74. Querying an Entity[1]// $dm is an instance of DoctrineODMCouchDBDocumentManager$blogPost = $dm->find("MyAppDocumentBlogPost",$theUUID); 1. http://docs.doctrine-project.org/projects/doctrine-couchdb/en/latest/reference/introduction.html#querying
  75. 75. Doctrine MongoDB ODM [1] 1. http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/
  76. 76. FeaturesMaps documents using Doctrine’s persistence semanticsMap embedded documentsMap referenced documentsUses batch insertsPerforms atomic updates
  77. 77. Defining Entities[1]/** @MappedSuperclass */abstract class BaseEmployee{ /** @Id */ private $id; /** @EmbedOne(targetDocument="Address") */ private $address; // ...} 1. http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/introduction.html#features-overview
  78. 78. Defining Entities[1]/** @Document */class Employee extends BaseEmployee{ /** @ReferenceOne(targetDocument="DocumentsManager") */ private $manager; // ...} 1. http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/introduction.html#features-overview
  79. 79. Defining Entities[1]/** @Document */class Manager extends BaseEmployee{ /** @ReferenceMany(targetDocument="DocumentsProject") */ private $projects = array(); // ...} 1. http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/introduction.html#features-overview
  80. 80. Defining Entities[1]/** @EmbeddedDocument */class Address{ /** @String */ private $address; /** @String */ private $city; /** @String */ private $state; /** @String */ private $zipcode; // ...} 1. http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/introduction.html#features-overview
  81. 81. Defining Entities[1]/** @Document */class Project{ /** @Id */ private $id; /** @String */ private $name; public function __construct($name) { $this->name = $name; } // ...} 1. http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/introduction.html#features-overview
  82. 82. Persisting Entities[1]$employee = new Employee();$employee->setName(Employee);$employee->setSalary(50000.00);$employee->setStarted(new DateTime()); 1. http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/introduction.html#features-overview
  83. 83. Persisting Entities[1]$address = new Address();$address->setAddress(555 Doctrine Rd.);$address->setCity(Nashville);$address->setState(TN);$address->setZipcode(37209);$employee->setAddress($address); 1. http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/introduction.html#features-overview
  84. 84. Persisting Entities[1]$project = new Project(New Project);$manager = new Manager();$manager->setName(Manager);$manager->setSalary(100000.00);$manager->setStarted(new DateTime());$manager->addProject($project); 1. http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/introduction.html#features-overview
  85. 85. Persisting Entities[1]// $dm is an instance of DoctrineODMMongoDBDocumentManager$dm->persist($employee);$dm->persist($address);$dm->persist($project);$dm->persist($manager);$dm->flush(); 1. http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/introduction.html#features-overview
  86. 86. Querying an Entity// $dm is an instance of DoctrineODMMongoDBDocumentManager$manager = $dm->find("DocumentsManager",$theID);
  87. 87. Final Thoughts
  88. 88. Document Databases Comparedto Relational DatabasesDocument databases have no tables (and therefore no columns)Indexes (views) are queried directly, instead of being used tooptimize more generalized queriesResult set columns can contain a mix of logical data typesNo built-in concept of relationships between documentsRelated entities can be embedded in a document, referenced froma document, or both
  89. 89. CaveatsNo referential integrityNo atomic transactions across document boundariesSome patterns may involve denormalized (i.e. redundant) dataData inconsistencies are inevitable (i.e. eventual consistency)Consider the implications of replication—what may seemconsistent with one database may not be consistent across nodes(e.g. referencing entities that don’t yet exist on the node)
  90. 90. Additional TechniquesUse the startkey and endkey parameters to retrieve one entity andits related entities: startkey=["9781565925809"]&endkey=["9781565925809",{}]Define a reduce function and use grouping levelsUse UUIDs rather than natural keys for better performanceUse the bulk document API when writing Relationship DocumentsWhen using the List of Keys or Relationship Documents patterns,denormalize data so that you can have data from the “right” and“left” side of the relationship within your query results
  91. 91. Cheat Sheet Embedded Related Relationship List of Keys Entities Documents Documents One to Many ✓ ✓Many to Many ✓ ✓<= N* Relations ✓ ✓> N* Relations ✓ ✓ * where N is a large number for your system
  92. 92. http://oreilly.com/catalog/9781449303129/ http://oreilly.com/catalog/9781449303433/
  93. 93. Thank You @BradleyHolt http://bradley-holt.com https://joind.in/7040Copyright © 2011-2012 Bradley Holt. All rights reserved.
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×