mysql用户标签表设计_「用户标签」在数据库设计时应该如何存储?

业务逻辑是这样的:

用户可以给自己贴标签,以供他人搜索。比如我给自己贴上“90后 程序员”的标签,那么别人就能通过“90后”或者“程序员”搜到我。

用户最多可以给自己贴10个标签。标签可以随时更新。

方案一:在User表里设置一个tags字段,里面存的是“90后,程序员”这样的字符串,用逗号分隔不同标签。缺点:不便于搜索,建立索引的话会很低效,因为“90后,程序员”和“程序员,90后”被认为是不同的。

方案二:在User表里设置10个tag_n字段(n=1,2,3...10),每个字段存一个标签。缺点:不利于Update。比如我现在把我的标签改为“程序员,90后,帅哥”,那么我要逐个检查“程序员”、“90后”和“帅哥”是否已存在,不存在才能添加。

不知道有什么好方法。

我在问问题的时候想到可以先给标签排序在存到数据库里。

注1:存tag的id而不是存tag的内容这一点已经采用了,我在问题里直接用tag内容是为了表述方面。

注2:我使用的是关系型数据库。

解决方案1:多对多

这应该是一个多对多的问题。

对于小型系统,我的设计方案通常是这样

user表

=====================

userId userName

=====================

1 test

2 test2

...

tag表

=====================

tagId tagName

=====================

1 tag

2 tag2

...

relation表

=====================

relationId userId tagId

=====================

1 1 1

2 1 2

...

insert update 之类的应该都很简单,不是问题

查询可能有点麻烦,需要用到联合查询

语句一般是这样

SELECT userId, userName FROM user u

INNER JOIN relation r ON u.userId=r.userId

WHERE r.tagId = 1

这样就查出了所有tagId为1的用户。

索引对这个方案可能效果不是很明显,数据量小的时候,索引的提升不明显,数据量大的时候,索引对联合查询起不到什么提升作用。

其实你的方案1不失为一种可行方案,特别是数据量惊人的情况,你可以采用方案1配合NoSQL的方式。

解决方案2:倒排索引

我想简单说下我的观点。

对于标签这个问题,无论是用户的标签,还是内容的标签,这其实都属于搜索的范畴。

我认为都应该采用倒排表(inverted index)的数据结构来存储。

对于标签的数据结构,无论存储在文件中还是数据库中,格式为:

label1 -> [ id1, id2, id3, .... idN]

label2 -> [ id8, id9, id10, .... idM]

这样存储的好处是,当用户搜索标签时,可以迅速得到所有id集合,然后做交集操作即可。

同时,每个用户user表,可以设一个tags字段,里面存所有label。当想查看某个用户的标签时,也可以迅速获取。

解决方案3:NoSQL

数据量小,用mongodb,建个带索引的array列,里面放标签。

数据量大,用elasticsearch,标签就是关键词,按搜索引擎的套路走。

标签变更生效有一点延迟,不过从业务角度看,这应该不是问题。

Hbase

解决方案4:Bitmap

其实这个问题 nosql 当然能很好的解决,要是用mysql 也不是不行,数据存储方式要斟酌一下,建立一个标签表tag 字段 id(自增) ,users(申请bit空间 字符串方式) 然后用bitmap 进行映射,用户id1 对应第一位 用户2对应第二位 以此类推, 通过计算很容易得出1M大小空间可以存838w用户的映射关系,这样 得出的 结果是 id 1 =》 对应users “10001000....” 代表标签id1的用户有userid 1 和5 ,做标签统计时候 只要对标签求交集并集很轻易何以得出各种统计,同时位运算效率极快。同时用户表加一个字段,用同样方式映射一下 userid 的 标签映射关系,当然要是便于搜索的话,直接存标签id比较好,这样很容易得出用户的标签 我不太会组织语言 不知道描述的清楚否

其他参考:

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值