mysql 建表问题,如何让查询能一层一层叠上去

2014-12-25 20:54:54 +08:00
 MaiCong

是这样的,最近做一套会员系统,其中有两个字段当前用户和推荐人。

我需要列出当前推荐人的所有父级推荐人

比如:

当前用户->推荐人->推荐人的推荐人->推荐人的推荐人的推荐人->推荐人的推荐人的推荐人的推荐人...

这样一直叠上去,请问数据库表该怎么写?

我总不能:

$ref1 ='select * form `user` where refname = 'xxx' limit 1;
$ref2 = select * form `user` where refname = '$ref1' limit 1;
$ref3 = select * form `user` where refname = '$ref2' limit 1;
...

求写法!:(

4448 次点击
所在节点    MySQL
27 条回复
abelyao
2014-12-25 23:26:34 +08:00
@MaiCong 用存储过程妥妥的基本满足需求了,而且是在数据库的服务器上去 while 所以性能问题不大,如果是在程序上 while 变成每往上一级就得查一次数据库那性能可能渣渣。拼字符串的方式也可以,但是检索是个问题,主要看你查询的频率了。综合之下,存储过程就是比较实际、性能又不会渣的选择。之前做过几个系统里面的无限级递归都用这个方法。
abelyao
2014-12-25 23:28:27 +08:00
@MaiCong
另外,ref 字段最好记录的是 user id 而不要用 user name,系统内部的关联最好都是用 id 来关联。
cye3s
2014-12-25 23:41:25 +08:00
oracle 倒是能一句sql搞定,普通构造树语句小改下就是这一串
DeutschXP
2014-12-26 00:03:40 +08:00
个人觉得这个应该是两种方式共同使用:存储过程加字符串字段,字符串的作用相当于缓存,
用空间换性能本来就是一个很划算的做法

我之前做这种多级代理之类的会员结构,是这样:
user 表下面两个字段
parentID: int 父会员的 ID,比如是1327
parentsID: text 所有父辈会员的 ID,用逗号间隔,比如是",1,152,927,1327,"

对于一个新会员注册添加,比如根据注册链接的 refID 读出 推荐者的记录row,那么新纪录的parentID 就是refID 或者是 row[ID],parentsID 也只不过是row[parentsID] & row[ID] & ","

这样做的最大好处,就是这个过程只需要操作一次数据库,而且不需要用到存储过程。所有父辈的 ID 本来就不能算是动态的值,为什么需要每次注册/登录的时候都需要查询一下这个用户有哪些父辈呢,当然应该缓存下来,无论是缓存在数据库里还是文件里。
包括楼主的需求,当前用户的所有父辈,直接把 parentsID 分割一下就行了,难道就这么个打注册之后就千百年不会再变的东西还得每次都去操作一次数据库?

然后是楼上有人提到的另一个需求:列出该用户所有的下级,这东西可以用 like 简单粗暴的搜,你已经几百万会员了吗?否则的话,右模糊 like 'parentsID,%'加上索引,影响没多少。当然也可以存储过程,具体就要看你的会员结构了,目前会员的层数是5层还是500层?会员是5W 还是500W,并不是所有时候都是存储过程效率更高的。

这个解决方案仅仅适合会员推荐这种应用,如果比如是新闻内容网站,因为所谓的子分类总是会移动来移动去的,比如今天这个结点在社会新闻下面,明天可能要移动到热点新闻下面去,那就会引起结构变化了,缓存都得重建。但是会员推荐,你把张三的下线都给挪到李四的下面去,你看张三可跟你急。
MaiCong
2014-12-26 00:36:02 +08:00
@markmx 二叉树啊...
@abelyao 明白,数字索引快嘛
@cye3s 关键是mysql...
@DeutschXP 感谢分析!字符串存储这招很好!已经使用上了,差不多就是这个意思。客户说会员达到一定数量就清空重来。2333。找到一个例子: http://mat1.gtimg.com/hb/js/common/demo/tree.html
markmx
2014-12-26 12:12:01 +08:00
@MaiCong http://mat1.gtimg.com/hb/js/common/demo/tree.html
这个第二个。就是我说的。。有个left right 值。。
datou552211
2014-12-26 12:13:43 +08:00
关系网用缓存吧

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/156712

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX