2012-04-25 45 views
1

我有点困惑什么是类别数据库结构的最佳解决方案。在这里,我有以下cateogry列表。类别和子类别的数据库结构

  1. 新闻

    1.1一般新闻

    1.2 Entertaintment新闻

    1.3体育新闻

  2. 2.1每日占星

    2.1.1 Aries 
    
        2.1.2 Taurus 
    
        2.1.3 Gemini 
    
        ..... 
    
        2.1.12 Pisces 
    

    2.2每周运势

    2.2.1 Aries 
    
        2.2.2 Taurus 
    
        2.2.3 Gemini 
    
        ..... 
    
        2.2.12 Pisces 
    
  3. 笑话

这是我现在的类别列表。在这里,我必须建立管理面板,可以添加类别和子类别。目前,我有2个星座运势的子类别。在未来,更多的子类别可以像月度和星期几一样加入,例如。另一个困惑是,每日和每周的星座有相同的子类别,这意味着单个子类别有多个父类别。在这里,我怎样才能消除数据库表中的重复。我需要使用递归函数在树结构中显示类别。 我谷歌的解决方案,我找不到合适的答案。你会提供给我答案或链接与此相关。我在php和MS-server数据库编码。

+2

我心目中最好的解决办法是有一个字段'parent_id'其引用到同一个表 – k102 2012-04-25 06:16:44

+0

什么SQL你使用的服务器版本是? – Arion 2012-04-25 06:25:42

+0

可能的重复http://stackoverflow.com/questions/5132875/categories-and-subcategories(在我的答案中有一般的解决方案) – SergeS 2012-04-25 06:26:37

回答

1

如何尝试这样的事情,有一个类别表具有以下字段,id,parent_id和标题, 每个类别都有一个parent_id或0为顶级类别。

如果您希望可以将标题设置为拥有ID和标题的不同表格,然后您可以在类别表格上引用titles表格上适当的标题。

它想,它会遵循这个规则集这是你在寻找什么:

  • 每个类别与零个或多个类别相关联。
  • 每个类别都与一个标题相关联。
  • 每个标题都与一个或多个类别相关联。

至于递归表示它,这是相当容易的这种方式。希望能为你解决问题。

+0

您能否提供循环遍历所有类别和子类别的递归函数示例列表.. – 2012-04-25 07:43:53

0

你的数据库结构应该B本包含其父相关ID和管理面板中获取选择框

USE `database`; 


CREATE TABLE `category` (
`c_id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
`category_name` varchar(255) DEFAULT NULL, 
`status` enum('active','inactive') DEFAULT 'active', 
PRIMARY KEY (`c_id`) 
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1; 

/*Data for the table `category` */ 

insert into `category`(`c_id`,`category_name`,`status`) values (1,'For Sale','active'),(2,'Community','active'),(3,'Classes','active'),(4,'Vehicles','active'),(5,'Real Estate','active'),(6,'Services','active'),(7,'Matrimonial','active'),(8,'Jobs','active'); 
CREATE TABLE `sub_category` (
`sub_cat_id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
`c_id` int(11) DEFAULT NULL, 
`sub_category_name` varchar(255) DEFAULT NULL, 
`status` enum('active','inactive') DEFAULT 'active', 
PRIMARY KEY (`sub_cat_id`) 
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1; 

/*Data for the table `sub_category` */ 

insert into `sub_category`(`sub_cat_id`,`c_id`,`sub_category_name`,`status`) values (1,1,'Animals','active'),(2,1,'Art - Collectibles','active'),(3,1,'Books - Magazines','active'),(4,1,'Business - Industrial','active'),(5,4,'Cars','active'),(6,4,'Truck','active'); 
/*Table structure for table `sub_category_child` */ 
CREATE TABLE `sub_category_child` (
`sub_category_child_id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
`c_id` int(11) DEFAULT NULL, 
`sub_cat_id` int(11) DEFAULT NULL, 
`sub_category_child_label` varchar(255) DEFAULT NULL, 
`nature` varchar(20) DEFAULT NULL, 
`status` enum('active','inactive') DEFAULT 'active', 
PRIMARY KEY (`type_id`) 
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1; 

insert into `sub_category_child`(`sub_category_child_id`,`c_id`,`sub_cat_id`,`sub_category_child_label`,`nature`,`status`) values (1,4,5,'Make','parent','active'),(2,4,5,'Model','child','active'),(3,4,5,'doors','independent','active'),(4,4,5,'accessories','independent','active'),(5,1,1,'abc','parent','active'),(6,4,6,'No of Tyre','parent','active'),(8,4,6,'loader','independent','active'); 
1

这里父类别和子类别的母公司是一些丑陋的代码,我几年前写的......但它可以帮助你如何对

DB表“表格名”结构

ID PARENT NAME 
1  0  1 
2  0  2 
3  1  1.1 
4  1  1.2 
5  4  1.2.1 
6  4  1.2.2 
7  2  2.1 

获取和准备数据

$Select = mysql_query("SELECT * FROM table_name"); 
while($Row = mysql_fetch_assoc($Select)){ 
    if($Row['parent'] == 0){ 
    $Arr[$Row['id']] = $Row['name']; 
    }else{ 
    $Childs[$Row['parent']][$Row['id']] = $Row['name']; 
    } 
} 

有些愚蠢,但足以功能

function gettree($Array){ 
    global $Childs; 
    foreach($Array as $key => $value){ 
    echo '<li>'.$value.'</li>'; 
    if(isset($Childs[$key])){ 
     echo '<li><ul>'; 
     gettree($Childs[$key]); 
     echo '</ul></li>'; 
    } 
    } 
} 

和BULDING树为HTML

echo '<ul>'; 
gettree($Arr); 
echo '</ul>'; 

和结果应该是这样

1 
1.1 
1.2 
    1.2.1 
    1.2.2 
2 
2.1 

我建议你把它改写为你对象为更好的使用

对不起,我的英语

+0

我认为可以有多个具有相同索引的数组。在这里,数组可以有多个相同的索引,因为父列不具有唯一值,例如在while循环中,可能有$ childs [1] [1]两次替代以前的值。 – 2012-04-25 08:21:29

+0

但ID列是唯一的,所以它不会取代以前的值,只需向数组中添加另一个值即可。此解决方案使用多维数组。 – miro 2012-04-25 08:24:29

+0

哦..我的错,我显然没有得到你的答案。对不起 – miro 2012-04-25 08:28:26

0

这个工作对我来说:

CREATE TABLE [dbo].[Category](
[id] [int] IDENTITY(1,1) NOT NULL, 
[Cat_Id] [int] NOT NULL, 
[Cat_Nm] [varchar](50) NOT NULL, 
[Parent_Id] [int] NULL, 
CONSTRAINT [PK_Category] PRIMARY KEY CLUSTERED 
(
    [id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,  ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 

/****** Object: Index [IX_Category] Script Date: 04/25/2012 07:30:14 ******/ 
CREATE UNIQUE NONCLUSTERED INDEX [IX_Category] ON [dbo].[Category] 
(
[Cat_Id] ASC, 
[Cat_Nm] ASC, 
[Parent_Id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
GO 
ALTER TABLE [dbo].[Category] WITH CHECK ADD CONSTRAINT [FK_Category_Category] FOREIGN KEY([Parent_Id]) 
REFERENCES [dbo].[Category] ([id]) 
GO 
ALTER TABLE [dbo].[Category] CHECK CONSTRAINT [FK_Category_Category] 

GO 

SET IDENTITY_INSERT [dbo].[Category] ON; 
INSERT INTO [dbo].[Category]([id], [Cat_Id], [Cat_Nm], [Parent_Id]) 
SELECT 9, 1, N'Aries', 7 UNION ALL 
SELECT 12, 1, N'Aries', 8 UNION ALL 
SELECT 7, 1, N'Daily', 2 UNION ALL 
SELECT 4, 1, N'General News', 1 UNION ALL 
SELECT 1, 1, N'News', NULL UNION ALL 
SELECT 5, 2, N'Enterntainment News', 1 UNION ALL 
SELECT 2, 2, N'Horoscope', NULL UNION ALL 
SELECT 10, 2, N'Taurus', 7 UNION ALL 
SELECT 13, 2, N'Taurus', 8 UNION ALL 
SELECT 8, 2, N'Weekly', 2 UNION ALL 
SELECT 11, 3, N'Gemini', 7 UNION ALL 
SELECT 14, 3, N'Gemini', 8 UNION ALL 
SELECT 3, 3, N'Jokes', NULL UNION ALL 
SELECT 6, 3, N'Sports News', 1 
SET IDENTITY_INSERT [dbo].[Category] OFF; 

GO 

CREATE VIEW Categories 
AS 
    WITH cte (id, Cat_Id, [Name], [Level]) 
       AS (SELECT id , 
         Cat_Id , 
         Cat_Nm , 
         CAST(Cat_Id AS VARCHAR(5)) 
       FROM  dbo.Category c 
       WHERE Parent_Id IS NULL 
       UNION ALL 
       SELECT c.id , 
         c.Cat_Id , 
         c.Cat_Nm , 
         CAST(ct.[Level] + '.' 
         + CAST(c.Cat_Id AS VARCHAR(5)) AS VARCHAR(5)) 
       FROM  dbo.Category c 
         JOIN cte ct ON c.Parent_Id = ct.id 
       WHERE c.Parent_Id IS NOT NULL 
      ) 
SELECT Level , 
     Name 
FROM cte