论坛上问树型表的问题多了,突然想到,有没有办法在数据库中存储一个图?定义
图是由结点的有穷集合V和边的集合E组成。其中,为了与树形结构加以区别,在图结构中常常将结点称为顶点,边是顶点的有序偶对,若两个顶点之间存在一条边,就表示这两个顶点具有相邻关系。
在上面两个图结构中,一个是有向图,即每条边都有方向,另一个是无向图,即每条边都没有方向。在数据库中怎样存储一个有向图和无向图?
要能够直观,方便,完整地表示顶点与顶点之间的关系.
要有较小的冗余,较小的空间占用.
要能够快速地查询出顶点与顶点之间的关系,能方便地遍历这个图.100分.纯属讨论研究.
图是由结点的有穷集合V和边的集合E组成。其中,为了与树形结构加以区别,在图结构中常常将结点称为顶点,边是顶点的有序偶对,若两个顶点之间存在一条边,就表示这两个顶点具有相邻关系。
在上面两个图结构中,一个是有向图,即每条边都有方向,另一个是无向图,即每条边都没有方向。在数据库中怎样存储一个有向图和无向图?
要能够直观,方便,完整地表示顶点与顶点之间的关系.
要有较小的冗余,较小的空间占用.
要能够快速地查询出顶点与顶点之间的关系,能方便地遍历这个图.100分.纯属讨论研究.
解决方案 »
- SQL Server 2005 sp4补丁较sp3更新了哪些内容?
- 触发器相关相关问题
- The operation could not be performed because the OLE DB provider 'MSDAORA' was unable to begin a distributed transaction.
- 求sql语句——在线
- 该内嵌函数为什么报错?
- sql server2005 完整备份问题
- 数据更新问题,牛人来帮帮忙!!!!
- 对视图排序,去重,增加新行连续报错……求助……
- 一个非常简单的问题,请各位指点,非常感谢!!!
- 求工资条语句写法
- SQL重复记录中要求取出最后(近)更新的一条记录
- 一个语句修改多个列,调用几次update触发器
有向图:
点表:id,x,y,关系表id1,id2
无向图还没搞明白啥意思
看看老大的乘车路线查询..
create table [tb] (id int,name varchar(1),pid int)
insert into [tb]
select 1,'A',0 union all
select 2,'B',1 union all
select 3,'D',1 union all
select 4,'C',2 union all
select 5,'D',2 union all
select 6,'A',4 union all
select 7,'E',5 union all
select 8,'F',5
GO
;with cte
as
(
select *,[path]=cast([name]+'->' as varchar(100)) ,[level] = 1 from tb where pid = 0
union all
select a.*, cast(c.[path]+a.[name]+'->' as varchar(100)),[level]+1 from cte c ,tb a where a.pid = c.id
)
select
*
from cte
where len([path]) > 6 and right([path],3) = left([path],3)
/*
id name pid path level
----------- ---- ----------- -------------- -----
6 A 4 A->B->C->A-> 4(1 行受影响)
*/------------------------------------------------------------------------
-- Author : happyflystone
-- Date : 2010-04-06
-- Version: Microsoft SQL Server 2005 - 9.00.2047.00 (Intel X86)
-- Apr 14 2006 01:12:25
-- Copyright (c) 1988-2005 Microsoft Corporation
-- Standard Edition on Windows NT 5.2 (Build 3790: Service Pack 2)
--
-------------------------------------------------------------------------- Test Data: ta
IF OBJECT_ID('[tb]') IS NOT NULL
DROP TABLE [tb]
Go
CREATE TABLE tb([cid] NVARCHAR(1),[pid] NVARCHAR(1))
Go
INSERT INTO tb
SELECT 'A','B' UNION ALL
SELECT 'A','D' UNION ALL
SELECT 'B','C' UNION ALL
SELECT 'B','D' UNION ALL
SELECT 'C','A' UNION ALL
SELECT 'D','E' UNION ALL
SELECT 'D','F'
GO
--Start
;with cte
as
(
select *,[path]=cast([cid]+'->' as varchar(100)) ,[level] = 1
from (select distinct cid,cast('' as nvarchar(1)) as pid from tb union select distinct pid ,'' from tb) b
union all
select a.*,cast(a.[cid]+'->'+c.[path] as varchar(100)),[level]+1
from cte c ,tb a
where a.pid = c.cid and charindex(a.[cid]+'->',c.[path])=0
)
select
[path]+cid+'->'
from cte
where exists(select 2 from tb where cid+'->' = right([path],3) and pid+'->' = left([path],3))-- = left([path],3)
--Result:
/*
--------------
A->B->C->A->
C->A->B->C->
B->C->A->B->(3 行受影响)*/
--End
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/htl258/archive/2010/04/06/5456223.aspx