Every blog post can have many comments but each comment only belongs to one blog post.

The way this is implemented is by giving every comment a blog_post_id so you can query the database for every comment with a blog_post_id that equal's the blog post's id.

Many to many: For example tags on a blog post.

Every blog post can have many tags (this one, for example, has two; #orm and #explainlikeimfive), and every tag can be attached to many blog posts (searching #explainlikeimfive will bring up many posts).

This cannot be implemented by adding a blog_post_id attribute to tags, because every tag needs to be able to have many blog_post_ids, instead, it's implemented using a join table.

A join table is a table that has two columns, blog_post_id and tag_id. Every time you want to add a tag to a blog post you add an entry to the join table with the id of the blog post and the id of the tag. Getting a list of all the tags that were applied to a given article is done by querying the join table for all of the tag_ids where the blog_post_id matches your blog post and vice versa for getting a list of all of the articles with a given tag.

This is a very nice answer! I'd just add that in the 'Object' part of ORM, the usage is usually pretty simple. For example, something like blog_post.tags will get the tags associated with a blog post and tag.blog_posts will get the blog posts associated with a given tag.

Behind the scenes the ORM will use its mapping configuration to retrieve these associations from a relational database. That's where a join table is probably going to be used to represent a many-to-many relationship between two tables, e.g. there would be something like an X_BLOG_POST_TAG table that connects the BLOG_POST and TAG tables. However, in your domain code, you usually won't need to be aware of this, which of course is the whole point behind object-relational mapping.