帮朋友设计一个交友网站,是朋友介绍朋友互相认识的那种。
用户间将形成一个网状结构,并且相互之间是有层次的。
举例如下:
用户 第一层朋友
A B,C,D,G
D A,E,F,G
G A,D,H,I
. .
. .
. .
用户之间形成的网状关系图见http://www.netop.cc/net.gif
如图所示,对于用户A,他的第一层朋友有B,C,D,G,他的第二层朋友有E,F,H,I
假如C要和D认识,可供选择的介绍路径有C-->A-->D,C-->F-->D,C-->A-->G-->D
系统有如下要求:
给出任意两个节点,
1:能够判别以上路径并给出最短路径;
2:能够判别两节点的最小层次,也即最短路径经过的节点数
系统拟采用ASP+MS SQL Server,请高手教我如何设计数据库及书写存储过程,能够得到最高效率
我在论坛和文档区都查了,没有找到相关文档,如果有,请知道的告诉我
谁能帮我解决此问题,除送分外,等网站建成,将邀请您成为首批元老级会员,在那里可以认识许多同行业朋友并得到他们的帮助。
拜托了!
---------------------------------------------------------------
--一般是这样设计
--用户信息表
create table tb_User(UserID int primary key,UserName nvarchar(10))
insert tb_User select 1,'A'
union all select 2,'B'
union all select 3,'C'
union all select 4,'D'
union all select 5,'E'
union all select 6,'F'
union all select 7,'G'
union all select 8,'H'
union all select 9,'I'
--用户关系表
create table tb_User_relation(UserID int references tb_User(UserID),Friend int references tb_User(UserID))
insert tb_User_relation select 1,2
union all select 1,3
--union all select 1,4
union all select 1,7
union all select 2,1
--union all select 2,5
union all select 2,6
union all select 2,7
union all select 7,1
union all select 7,4
union all select 7,8
union all select 7,9
union all select 4,5
union all select 4,6
go
--查询的存储过程
create proc p_qry
@UserName1 nvarchar(20),
@UserName2 nvarchar(20)
as
set nocount on
declare @UserID1 int,@UserID2 int
select @UserID1=UserID from tb_User where UserName=@UserName1
if @@rowcount=0
begin
raiserror('用户"%s"无效',1,16,@UserName1)
return
end
select @UserID2=UserID from tb_User where UserName=@UserName2
if @@rowcount=0
begin
raiserror('用户"%s"无效',1,16,@UserName2)
return
end
--如果存在直接的关系,则直接显示
if exists(
select * from tb_User_relation
where UserID=@UserID1 and Friend=@UserID2)
begin
select Path=@UserName1+'->'+@UserName2,level=1
return
end
--如果没有直接的关系,则循环得到结果
declare @l int
set @l=2
select a2.Friend,Path=cast(@UserName1+'->'+b.UserName as varchar(8000)),level=@l
into #t from tb_User_relation a1,tb_User_relation a2,tb_User b
where a1.UserID=@UserID1
and a1.Friend=a2.UserID and a2.UserID=b.UserID
while @@rowcount>0 and not exists(
select * from #t where Friend=@UserID2)
begin
set @l=@l+1
insert #t select a2.Friend,a1.Path+'->'+b.UserName,@l
from #t a1,tb_User_relation a2,tb_User b
where a1.level=@l-1
and a1.Friend=a2.UserID and a2.UserID=b.UserID
end
--显示结果
select Path=Path+'->'+@UserName2,level
from #t where level=@l and Friend=@UserID2
go
--调用
exec p_qry 'A','E'
go
--删除测试
drop table tb_User_relation,tb_User
drop proc p_qry
/*--测试结果
Path level
----------------- -------------
A->G->D->E 3
--*/