I see often (rewritten) URLs without ID in it, like on some wordpress installations. What is the best way of achieve this? Example: site.com/product/some-product-name/ Maybe to keep array of page names and IDs in cache, to avoid DB query on every page request? How to avoid conflicts, and what are other issues on using urls without IDs?
As long as product names are unique it shouldn't be an issue. It won't take any longer (at least not significant) to look up a product by unique name than numeric ID as long as the column is indexed.
Using an ID presents the same conundrum, really--you're just checking for a different value in your database. The "some-product-name" part of your URL above is also something unique. Some people call them slugs (Wordpress, also permalinks). So instead of querying the database for a row that has the particular ID, you're querying the database for a row that has a particular slug. You don't need to know the ID to retrieve the record.
Product name can have some characters that i need to url-encode. For example, replace space with "-", dots, brackets , ..., that I need to restore again on page request and find it in DB. There are great chances that I don't find it, because space and "-" and "_" are all replaced with "-" !
How does wordpress do it?
Wordpress has a field in the wp_posts table for the slug. When you create the post, it creates a slug from the post title (if that's how you have it configured), replacing spaces with dashes (or I think you can set it to underscores). It also takes out the apostrophes, commas, or whatnot. I believe it also limits the overall length of the slug, too.
So, in short, it isn't dynamically decoding the URL into the post's title--there's a field in the table that matches the URL version of the post name directly.
As you may or may not know, the URLs are being re-written with Apache's mod_rewrite module. As mentioned here, Wordpress is, in the background, assigning a slug after sanitizing the title or post name.
But, to answer your question, what you're describing is Wordpress' "Pretty Permalinks" feature and you can learn more about it in the Wordpress codex. Newer versions of Wordpress do the re-writing internally (no .htaccess editin, wp_rewrite instead). Which is why you'll see the same ruleset for any permalink structure.
Though, if you do some digging you can find the old rewrite rules. For example:
RewriteRule ^([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/?$ /index.php?year=$1&monthnum=$2&day=$3 [QSA,L]
Will take a URL like /2008/01/01/
and direct it to /index.php?year=2008&monthnum=01&day=01
(and load a date category).
But, as mentioned, a page like product-name
exists only because Wordpress already sanitized the post title and stored it as a field in the database.