Kaji
Kaji

Reputation: 2330

Many-to-Many Relationships in MySQL

I've been reading up on foreign keys and joins recently, and have been pleasantly surprised that many of the basic concepts are things I'm already putting into practice. For example, with one project I'm currently working on, I'm organizing word lists, and have a table for the sets, like so:

`words` Table
    `word_id`
    `headword`
    `category_id`
`categories` Table
    `category_id`
    `category_name`

Now, generally speaking this would be a one-to-many relationship, with several words being placed under a single category with the foreign key category_id. Let's assume for a moment, however, that a user chooses to add another category to a word, making it many-to-many—Is there a way to set up my words table to handle additional categories for words without creating extra columns like category_2, category_3, etc.?

Upvotes: 5

Views: 3787

Answers (3)

Larry Lustig
Larry Lustig

Reputation: 50970

You MUST NOT create extra columns like category_2 and category_3. That way lies madness.

Instead, you would remove the column "category_id" from the "words" table. Then, you would create a new table "category_words" with columns "category_id" and "word_id". To place a word into a category, insert a record into this table. To place the same word into another category, insert another record into the table.

Upvotes: 6

Cade Roux
Cade Roux

Reputation: 89661

You would remove the category_id from the words table and have a word_category table containing word_id, category_id (usually unique index or constraint) which is typically called a link table or bridge table. This is the typical normalized structure for a many-to-many relationship.

Having multiple category_id columns in the words table is not advisable for many reasons, which is why normal forms eliminate "arrays" from being stored in rows.

Upvotes: 4

Usually you have a separate table to handle these mappings:

`Words_Categories` Table
    `word_id`
    `category_id`

Each pair in this Words_Categories table represents one possible mapping from any word to any other category.

The category_id field in the Words table becomes unneeded under this scheme, as neither of these tables references each other directly.

Upvotes: 12

Related Questions