+ -
当前位置:首页 → 问答吧 → 请教相互对应有序的表设计问题

请教相互对应有序的表设计问题

时间:2011-12-11

来源:互联网

最近要设计一个数据库表,大致是这样的。
类似于一般游戏中的好友系统,玩家都会有好友,表中要记录好友的友好度,同时如果A像B提出申请,还要记录A向B提出申请的时间。游戏中拥有两个列表,一个是我的申请,一个是我的审批列表。
然后问题来了,因为AB共享一个数据项,假设有字段applyid,approveid,applyid向approveid提出申请,然后插入一条记录。在以后的好友列表中,我需要查找A的好友,我需要两次查找,一次查找applyid,一次查找approveid,因为AB无论什么位置,都是好友,我要找A的全部好友,我就需要查找A主动提出申请加为好友,或是审批别人同意成为好友。
有想过左一式两份的拷贝,但是因为AB共享一个好友度,这样容易出错,所以这样的设计又放弃。
但是,两次的数据库查找效率有点低,不知道有人涉及过类似的问题吗?
谢谢大家。

作者: dreamzme   发布时间: 2011-12-11

建议楼主先提出自己的设计,然后别人可以基于你自己的数据库结构设计进行评论修改。

作者: ACMAIN_CHM   发布时间: 2011-12-12

假设有字段applyid,approveid:你的表是这样的,在字段上建立索引,查询效率应该不低
applyid approveid type
TYPE用来标志是主动提出申请加为好友 OR 审批别人同意成为好友

作者: wwwwb   发布时间: 2011-12-12

"有想过左一式两份的拷贝,但是因为AB共享一个好友度,这样容易出错,所以这样的设计又放弃。"

这几乎不是一个数据库问题。
关键在于在A和B的个人属性列表中,如果他们是好友,那么彼此的好友度应该是相同的。OK?
所以,好友表可以设计为:
身份ID 好友ID 申请方(0为别人主动申请,1为自己申请01) 申请时间 好友度 其它一 其它二。。。

A和B每个人都有一张这样的表,只不过他俩的表上,身份ID和好友ID以及申请方这三列的值是相反的。其它值可能基本相同。然后,某程序在修改好友度时,应该同时修改A和B的好友度,以使两者保持一致就可以了。
也就是说,好友度的一致性,不应该由数据库保证,而是由程序逻辑来保证。

作者: jiahehao   发布时间: 2011-12-12

首先要确认一下需求

同意审核后,是默认相互都加好友,还是单向的?
如果是相互加的话,一旦好友关系确认后,是否有需求要知道当时是谁申请的?

作者: wfevgch   发布时间: 2011-12-12

引用 3 楼 jiahehao 的回复:

"有想过左一式两份的拷贝,但是因为AB共享一个好友度,这样容易出错,所以这样的设计又放弃。"

这几乎不是一个数据库问题。
关键在于在A和B的个人属性列表中,如果他们是好友,那么彼此的好友度应该是相同的。OK?
所以,好友表可以设计为:
身份ID 好友ID 申请方(0为别人主动申请,1为自己申请01) 申请时间 好友度 其它一 其它二。。。

A和B每个人都有一张这样的表……


我当时的想法也是这么想的,不过后面否定了。也是因为有两个类似的记录,虽然申请跟审批交换了位置,不过好友度还是同样的一个值。如果出现了问题,出现两者不一致的情况就麻烦了。

作者: dreamzme   发布时间: 2011-12-12

引用 2 楼 wwwwb 的回复:

假设有字段applyid,approveid:你的表是这样的,在字段上建立索引,查询效率应该不低
applyid approveid type
TYPE用来标志是主动提出申请加为好友 OR 审批别人同意成为好友

假设有字段applyid,approveid:你的表是这样的,在字段上建立索引,查询效率应该不低
applyid approveid type
TYPE用来标志是主动提出申请加为好友 OR 审批别人同意成为好友

作者: dreamzme   发布时间: 2011-12-12

引用 2 楼 wwwwb 的回复:

假设有字段applyid,approveid:你的表是这样的,在字段上建立索引,查询效率应该不低
applyid approveid type
TYPE用来标志是主动提出申请加为好友 OR 审批别人同意成为好友

问题是我现在如果需要查找某人的好友,我需要查询两次,这是关键问题。
一个是以我applyid为主搜索,一个是以approveid为主搜索。
刚开始涉及数据库,或者说mysql有没有一个语句可以解决这个需求。

作者: dreamzme   发布时间: 2011-12-12

问题是我现在如果需要查找某人的好友,我需要查询两次,这是关键问题。

是这样?
select * from tt where applyid='a' or approveid='a'

作者: wwwwb   发布时间: 2011-12-12

我不太懂mysql 但是之前做过SQLServer的有一个基本概念 -- 虚拟表 这个好像是数据库基础里的概念 很简单 你可以翻翻 应该能解决类似你的这种问题: 比如 把需要的字段临时组成一个虚拟表 只查询一次 而且性能很高;

另外 你的那个设计需求 我觉得 不需要查询两次 因为申请列表 最后需要 批准列表那边批准才能成为好友 所以搜索的时候可以不用查询 申请列表了 个人建议

作者: ZSP95   发布时间: 2011-12-12

引用 8 楼 wwwwb 的回复:

问题是我现在如果需要查找某人的好友,我需要查询两次,这是关键问题。

是这样?
select * from tt where applyid='a' or approveid='a'


如果我是主动申请的,那么我需要查找approveid,exp,approvetime,
如果我是被动申请的,我需要查找applyid,exp,approvetime,
这样的需求可以用一个sql语句完成吗?

作者: dreamzme   发布时间: 2011-12-12

select * from (
select approveid,exp,approvetime from tt
union
selec applyid,exp,approvetime
) a where approveid='a'

作者: wwwwb   发布时间: 2011-12-12

引用 11 楼 wwwwb 的回复:

select * from (
select approveid,exp,approvetime from tt
union
selec applyid,exp,approvetime
) a where approveid='a'

mysql> SELECT applyid,exp,applytime,state FROM friendship WHERE approveid = 1 UNION SELECT approveid,exp,applytime,state FROM friendship WHERE applyid = 1;
参考了UNION关键字,有个疑问,这样的一条语句,与同时使用两条select的语句效率相比如何,是两条语句的查询代价吗?或是优化点,还是说只是一条语句的查询代价?

作者: dreamzme   发布时间: 2011-12-12