Question: I have **two tables** for one is `category` and another one is `sub-category`. that two table is assigned to `FK` for many table. In some situation we will move one record of **sub-category** to **main category**. so this time occur constraints error because that **key** associated with other table. so i would not create this **schema**.

so now i plan to **create category** and **sub-category** in same table and **create relationship table** to make relationship between them.

`category table:`

```
id(PK,AUTO Increment),
item===>((1,phone),(2.computer),(3,ios),(4,android),(5,software),(6,hardware)).

```

`relationship table:`

```
id,cate_id(FK),
parentid(refer from category table)===>((1,1,0),(2,2,0),(3,3,1),
                                        (4,4,1),(5,5,2),(5,5,3)).

```

in my side wouldnot go hierarchy level more than three.

if we easily move to subcategory to main category `ex:(4,4,1) to (4,4,0)` without affect any other table. is this good procedure?

if we will maintain millions record, will we face any other problem in future?

have any another idea means let me know?

Answer: 
There might be a problem if you have multiple levels in the tree, and want to find all the subcategories of any category. This would require either multiple queries, or a recursive one.

You could instead look into the ["Nested Sets"](http://www.codeproject.com/Articles/4155/Improve-hierarchy-performance-using-nested-sets) data-structure. It supports effective querying of any sub-tree. It does have a costly update, but updates probably won't happen very often. If need be, you could batch the updates and run them over night.

```
create table Category (
    Id int not null primary key auto_increment,
    LeftExtent int not null,
    RightExtent int not null,
    Name varchar(100) not null
);

create table PendingCategoryUpdate (
    Id int not null primary key auto_increment,
    ParentCategoryId int null references Category ( Id ),
    ParentPendingId int null references PendingCategoryUpdate ( Id ),
    Name varchar(100) not null
);

```

---

If you have a small number of categories, a normal parent reference should be enough. You could even read the categories into memory for processing.

```
create table Category (
    Id int not null primary key auto_increment,
    ParentId int null references Category ( Id ),
    Name varchar(100) not null
);

-- Just an example
create table Record (
    Id int not null primary key auto_increment,
    CategoryId int not null references Category ( Id )
);

select *
from Record
where CategoryId in (1, 2, 3); -- All the categories in the chosen sub-tree

```
How about creating one table as following:

```
categories(
    id int not null auto_increment primary key, 
    name char(10), 
    parent_id int not null default 0)

```

Where parent\_id is a FK to the id, which is the PK of the table.
When parent\_id is 0, then this category is a main one. When it is > 0, this is a sub category of this parent.
To find the parent of a category, you will do self-join.