zoukankan      html  css  js  c++  java
  • 「用户标签」在数据库设计时应该如何存储?

    业务逻辑是这样的:
    用户可以给自己贴标签,以供他人搜索。比如我给自己贴上“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比较好,这样很容易得出用户的标签 我不太会组织语言 不知道描述的清楚否

    其他参考:

    [实战]短视频打标签技术解析与应用

    解读电商搜索——如何让你买得又快又好

  • 相关阅读:
    objectARX 获取ucs的X方向
    passivedns 安装指南
    sql server手工注入
    libimobiledevice安装步骤
    CAD系统变量(参数)大全
    objectARX判断当前坐标系
    access手工注入
    网站自动跳转
    python黑帽子源码
    objectarx 卸载加载arx模块
  • 原文地址:https://www.cnblogs.com/yeahwell/p/11676480.html
Copyright © 2011-2022 走看看