scrabsoftware | 0902.835.110 tư vấn miễn phí
  • Thiết kế website cho ca sĩ
    Thiết kế website cho ca ...
    Thiết kế website cho ca sĩ, nhạc sĩ ? Bạn là 1 ca sĩ chuyên nghiệp? Bạn muốn lập một website để PR thương hiệu ...
  • Thiết kế website cho nội thất, trang trí nội thất
    Thiết kế website cho nội ...
    Thiết kế website cho nội thất, trang trí nội thất? Là gói website dành cho lĩnh vực nội thất với những yêu cầu riêng biệt ...
  • Thiết kế website dạng điện máy, điện lạnh, điện tử...
    Thiết kế website dạng điện ...
    Thiết kế website dạng điện máy, điện lạnh, điện tử...Là một gói website tổng hợp và bao gồm các nghiệp vụ riêng biệt cho lĩnh ...
  • Thiết kế website giáo dục
    Thiết kế website giáo dục
    Kiến thức luôn là nền tảng cho mọi quyết định sáng suốt của con người. Ở SCRAB với tinh thần ham học hỏi và sự nố ...
  • Website thương mại điện tử
    Website thương mại điện tử
    Trong kỷ nguyên của côngnghệ thông tin hiện nay, việc mua bán sản phẩm không còn đơn thuần là rachợ hay đến siêu thị. Xu ...
  • Thiết kế website du lịch
    Thiết kế website du lịch
    Với kinh nghiệm qua nhiều website du lịch SCRAB thấu hiểu tầm quan trọng của website du lịch trong lĩnh vực này. Vàcam kết cung ...
  • Website khách sạn, nhà hàng
    Website khách sạn, nhà hàng
    Làm thế nào để khi khách hàng truy cập vào website của bạn, họ bị thuyết phục và đưa ra quyết định đặt phòng ngay? ...
  • Website Quảng cáo, rao vặt
    Website Quảng cáo, rao vặt
    Cung cấp một  giải pháp hoàn chỉnh đểngười có nhu cầu và người cung cấp nhu cầu có thể gặp nhau. doanh nghiệpvà người tiêu ...
  • Website Sàn GD Bất động sản
    Website Sàn GD Bất động ...
    Những giá trị mà giải pháp SCRAB mang lại cho Bạn: Giao diện đẹp, sáng tạo với bố cục hợp lý giúp người truy cập ...
  • Website Tòa soạn báo trực tuyến
    Website Tòa soạn báo trực ...
    Ngày nay với sự phát triển mạnh mẽ của Internet đã tạo ra sự bùng nổthông tin trên toàn thế giới! Thông tin ngày nay không ...

Ngày 17/06/2013

MongoDB for the PHP Mind, Part 3

Lượt xem: 4730

This is part 3 in a series, which will focus on the data modeling aspect of working with document databases. The previous parts are also available for reading: Part 1: Getting Started, and Part 2: Queries and Indexes.

The Usual Suspects

Although there are plenty of existing articles, presentations and webcasts about modeling your data to take advantage of a document database, this post is taking a slightly PHP-centric position as a part of this series. This information is useful to anyone though, regardless of their chosen programming language.

We’re going to use two different scenarios to look at data modeling in the document world, chosen as common examples to illustrate differences in implementation between relational and document databases:

  • Blog. Your garden variety of data, covering posts, comments and tags
  • Private Sale / E-Commerce. Taking a look at needs for orders, users and products

Scenario 1: Getting All Bloggy

I’m kicking off with the tried-but-true blog example as it is a common frame of reference. Part of the biggest challenges of assessing MongoDB is the ability to quickly understand document data modeling, and stepping outside the constraints of relational data modeling. A common scenario helps illustrate that.

Your typical blog will have the following elements to consider:

AuthorsIn most cases this can point at existing user dataPostsWhere you store the actual data about each blog postCommentsAll blog posts need commentsCategoriesHow you choose to organize your posts by category groupingTagsTagging helps people find posts, and helps you link your related posts together

A typical third normal form relational model will produce around six tables. For many-to-many relationships (such as with posts to tags) you need the reference table as well as the link table with the keys. For example, for tags you might have the posts table, the tags table, and a posts_tags table that simply links post_id with tag_id for each reference. This not only complicates your data model, but it shows a disconnect between relational theory and document structure.

Here’s an example of how your posts might hook into tags, using a relational model:


This approach can complicate your code, as you have to write more sophisticated queries to join multiple tables together. If your application is also expected to create new posts and tags, then that logic will be more complex as well. If you are using a framework, you might find yourself spending more time figuring out how to deal with the database inserts and updates, as opposed to actually writing code.

For instance, every time you create a new blog post, you’re going to have to do the following:

  • First check if that category exists, if not then create it
  • Check for tags, create them too
  • Create link between post and tag, for each tag used for this article
  • Link to author

Comments of course happen after the post is live, so inserting them is a little less effort:

  • Check to see if this comment is responding to another comment
  • Insert comment

With MongoDB you have a few approaches to solve this problem.

Equi-join and Embedded Lists

Taking our example with posts and tags, you can remove the middle by storing a list of tag_ids in your post document. This is how this might look with a document model:

	> db.posts.findOne();
		"_id" : ObjectId("508d27069cc1ae293b36928d"),
		"title" : "This is the title",
		"body" : "This is the body text.",
		"tags" : [
		"created_date" : ISODate("2012-10-28T12:41:39.110Z"),
		"author_id" : ObjectId("508d280e9cc1ae293b36928e"),
		"category_id" : ObjectId("508d29709cc1ae293b369295"),
		"comments" : [

This approach presumes that you are storing your tags and comments in their own collection. Of course your users are in a separate collection as well. With MongoDB, an equi-join works just like in the relational model, however you have to perform a separate query to fetch that data.

You might be asking yourself so why is running separate queries a better idea than one SQL statement with a few joins? Think about the query cache from a relational database. That one query will hit multiple tables, and any of which need to be updated only once and that query gets dropped from the cache.

MongoDB caches queries too, however with separate queries for each collection, an update to one of these collections does not invalidate the cache for the others; and for example, a user updating their password will not touch the cached post, comments, categories, or tags. That same event on a relational database will drop the query from the cache, even though the data being updated had nothing to do in particular with that query.

One last comment about the monster SQL statement approach: Many platforms and frameworks are breaking out the logic that pulls the content for a page, and separating that from the blocks that typically populate the sidebars and footer. For example, the comments are always rendered from a separate module. If you are using a complex, heavy platform that means you have to run separate queries for the post and comments anyway, as the comments module won’t have access to the post content object.

The simplest example is running a single query to fetch the content of your blog post and render it in the main body of your app, and then run a separate query for grabbing all the comments and displaying them in a separate comments module at the bottom of your content area. Although you still can enforce relational integrity, at this point you are getting a minimized benefit from a relational engine as you are displaying related data from separate queries. Some modern platforms will do this with everything, including separating queries for authors, categories, and tags — so you’re running separate queries in the end regardless of database platform.

Embedded Lists, No Join

You could also just embed all of your tags and comments in each post, dropping your count to just the posts collection, and no longer needing a separate collection for comments or tags.

	> db.posts.findOne();
		"_id" : ObjectId("508d27069cc1ae293b36928d"),
		"title" : "This is the title",
		"body" : "This is the body text.",
		"tags" : [
		"created_date" : ISODate("2012-10-28T12:41:39.110Z"),
		"author_id" : ObjectId("508d280e9cc1ae293b36928e"),
		"category_id" : ObjectId("508d29709cc1ae293b369295"),
		"comments" : [
				"subject" : "This is coment 1",
				"body" : "This is the body of comment 1.",
				"author_id" : ObjectId("508d345f9cc1ae293b369296"),
				"created_date" : ISODate("2012-10-28T13:34:23.929Z")
				"subject" : "This is coment 2",
				"body" : "This is the body of comment 2.",
				"author_id" : ObjectId("508d34739cc1ae293b369297"),
				"created_date" : ISODate("2012-10-28T13:34:43.192Z")
				"subject" : "This is coment 3",
				"body" : "This is the body of comment 3.",
				"author_id" : ObjectId("508d34839cc1ae293b369298"),
				"created_date" : ISODate("2012-10-28T13:34:59.336Z")

This greatly speeds the assembly of data for rendering that page, as one query returns the post, tags and comments.

So which approach is better?

With document design you need to consider two things: scale and search. ScaleMongoDB Documents have a limit of 16MB, which although sounds quite small, can accommodate thousands of documents. However if you are expecting 20,000 comments per post on a high traffic website, or your comments are unlimited in size, then embedding might not work well for you.SearchDepending on how you want to find your documents, you should consider their structure. MongoDB makes it dead simple to embed lists and even other documents, but if you find yourself constantly reaching deeper and deeper to find the data you need, then performance can become a problem as your data set grows.

You must weigh both of these to decide what approach makes the most sense for your application’s needs.

Outro, or What’s Coming Next

The next article in this series covers Example Scenario 2: Private Sales. That article examines the issues of managing inventory and making atomic updates.


■ Bình luận:

Tin liên quan

Hỗ trợ trực tuyến

ken.0110 Kỹ thuật

Mr Thiện: 0989 916 495


ken.0110 Tư vấn thiết kế

Mr.Ken:  0902 835 110