Why does WordPress combine a term with the same name in the wp_terms table?

  1. Add a term for a certain taxonomy with the name: Test
  2. Add another term for a different taxonomy with the same name: Test
  3. In the wp_terms table you find one record for both terms. In the wp_term_taxonomy table you find two records with the taxonomy and description and other information about the terms.
  4. Now, if you edit one term and change the name from Test to Test2 then both terms are changed…

Why is WordPress working that way?

EDIT:
The real question is not why WP uses a unique slug for a taxonomy. Thats obvious.
It’s why WP uses one record in wp_terms for the same term. But the meaning of ‘Test’ can be different in different taxonomies.
If you edit one of the terms to be different. That isn’t possible anymore.
WordPress will edit both because they are both linked to the same term_id.

1
1

It is because terms.slug and terms.name are both unique indexes with the MySQL table structure.

Unique  Packed  Column  Cardinality Collation
PRIMARY BTREE   Yes No  term_id 13  A
slug    BTREE   Yes No  slug    13  A
name    BTREE   No  No  name    13  A

WordPress uses canonical redirects which mainly rely on a viable single posts.post_name or terms.slug query result. Having multiple entries for the same post_name or slug completely removes the reliability of canonical redirects, thus unique indexes are defined in these tables.

The reason a term name is unique is because it is typically the source of the slug when a user creates a new category or tag. Also, menus term slugs are generated from the term name. If two names match, then the slug would not be unique.

Though I wouldn’t recommend it, you can manually go into term_taxonomy and associate term_id with a different term if you need a pseudo ‘duplicate’. I can’t speak to the implications of this on your site, but it technically would work to subvert this structural dictation.

A wise man once told me, don’t burn a bridge without asking first why it was built. This is a good application. Don’t start creating pseudo duplicates without understanding why the table indexes are unique in the first place.

Canonical redirects have been in place since 2.3. Check out Mark Jaquith’s post here for a more in-depth explanation.

You can use the following to disable canonical redirects:

remove_filter('template_redirect', 'redirect_canonical');

Hope this helps clarify the issue a bit.

Leave a Comment