views:

217

answers:

3

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.?

+5  A: 

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.

FrustratedWithFormsDesigner
+3  A: 

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.

Cade Roux
"typically called a link table or bridge table" thanks for adding the terminology in here.
Cody Snider
+4  A: 

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.

Larry Lustig
+1 for "That way lies madness!" ;)
FrustratedWithFormsDesigner