开发者

If I have two tables in SQL with a many-many relationship, do I need to create an additional table?

Take these tables for example.

Item
    id
    description
    category

Category
    id
    description 

An item can belong to many categories and a category obviously can be attached to many items.

How would the database be created in this situatio开发者_JS百科n? I'm not sure. Someone said create a third table, but do I need to do that? Do I literally do a

create table bla bla

for the third table?


Yes, you need to create a third table with mappings of ids, something with columns like:

 item_id     (Foreign Key)
 category_id (Foreign Key)

edit: you can treat item_id and category_id as a primary key, they uniquely identify the record alone. In some applications I've found it useful to include an additional numeric identifier for the record itself, and you might optionally include one if you're so inclined

Think of this table as a listing of all the mappings between Items and Categories. It's concise, and it's easy to query against.

edit: removed (unnecessary) primary key.


Yes, you cannot form a third-normal-form many-to-many relationship between two tables with just those two tables. You can form a one-to-many (in one of the two directions) but in order to get a true many-to-many, you need something like:

Item
    id primary key
    description

Category
    id primary key
    description

ItemCategory
    itemid     foreign key references Item(id)
    categoryid foreign key references Category(id)

You do not need a category in the Item table unless you have some privileged category for an item which doesn't seem to be the case here. I'm also not a big fan of introducing unnecessary primary keys when there is already a "real" unique key on the joining table. The fact that the item and category IDs are already unique means that the entire record for the ItemCategory table will be unique as well.

Simply monitor the performance of the ItemCategory table using your standard tools. You may require an index on one or more of:

  • itemid
  • categoryid
  • (itemid,categoryid)
  • (categoryid,itemid)

depending on the queries you use to join the data (and one of the composite indexes would be the primary key).

The actual syntax for the entire job would be along the lines of:

create table Item (
    id            integer       not null primary key,
    description   varchar(50)
);
create table Category (
    id            integer       not null primary key,
    description   varchar(50)
);
create table ItemCategory (
    itemid        integer       references Item(id),
    categoryid    integer       references Category(id),
    primary key   (itemid,categoryid)
);

There's other sorts of things you should consider, such as making your ID columns into identity/autoincrement columns, but that's not directly relevant to the question at hand.


Yes, you need a "join table". In a one-to-many relationship, objects on the "many" side can have an FK reference to objects on the "one" side, and this is sufficient to determine the entire relationship, since each of the "many" objects can only have a single "one" object.

In a many-to-many relationship, this is no longer sufficient because you can't stuff multiple FK references in a single field. (Well, you could, but then you would lose atomicity of data and all of the nice things that come with a relational database).

This is where a join table comes in - for every relationship between an Item and a Category, the relation is represented in the join table as a pair: Item.id x Category.id.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜