一般用户表的用户 ID,是不是设计成字符串的比较多 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
cjbi
V2EX    数据库

一般用户表的用户 ID,是不是设计成字符串的比较多

  •  
  •   cjbi 2023-03-01 13:17:49 +08:00 5319 次点击
    这是一个创建于 963 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如题,请说明理由,表关联也是用字符串吗?

    ktqFDx9m2Bvfq3y4
        1
    ktqFDx9m2Bvfq3y4  
       2023-03-01 13:21:34 +08:00 via iPhone
    整型自增。

    放心,系统下线了用户都不会有那么多。
    zoharSoul
        2
    zoharSoul  
       2023-03-01 13:23:52 +08:00
    不是, 基本都是整形
    shyangs
        3
    shyangs  
       2023-03-01 13:30:06 +08:00
    和百度吧踩同一坑。

    哪天品拍袋, 百度(用名)要可以使用者自由地更名, 你要吧在 username 加各符避免重?
    shyangs
        4
    shyangs  
       2023-03-01 13:34:10 +08:00   3
    承上,所以分 id 和 name,

    id 用整型自增,系定,使用者不可更改 id ,只能改 name 。
    justfindu
        5
    justfindu  
       2023-03-01 13:36:32 +08:00
    自增, 如果你要避免被扫, 那就 uuid 呗
    op351
        6
    op351  
       2023-03-01 13:36:40 +08:00
    因为用主键的整型自增列会暴露其他用户,所以不会用主键的整型自增列
    而是自增列之外设计一个单独的用户 ID 列 使用三方库根据日期之类的生成不会重复的字符串
    xiaoliu926
        7
    xiaoliu926  
       2023-03-01 13:44:28 +08:00
    @op351 我这边的项目都是雪花算法生成主键 id 的,安全的很
    LeegoYih
        8
    LeegoYih  
       2023-03-01 13:48:38 +08:00
    bigint
    实际接口都会鉴权,不存在通过 ID 被暴力遍历的情况
    op351
        9
    op351  
       2023-03-01 13:54:13 +08:00
    @xiaoliu926
    不用整型自增就行
    我也是之前用 fiddler 分析某 app 的接口才意识到直接使用自增会导致用户信息泄露-。-
    NoKey
        10
    NoKey  
       2023-03-01 13:57:38 +08:00
    有时候对外叫 userID ,他实际不是 id ,用户 id ,要区分业务层面的 id ,和数据层面的 id ,你讲的是哪一个?
    cjbi
        11
    cjbi  
    OP
       2023-03-01 14:00:21 +08:00
    @NoKey 上面都提到了,主要怕被看出规则,我目前有个项目是用自增做关联字段,另外弄个字段+随机字符串作为用户唯一 ID ,总感觉很奇怪
    chendy
        12
    chendy  
       2023-03-01 14:05:51 +08:00
    自增,怕被爆破就在接口层加一层编码规则处理,变成火星文(比如加上固定前后缀然后取字节然后翻转然后 base64 啥的)
    superedlimited
        13
    superedlimited  
       2023-03-01 14:09:25 +08:00
    为什么 mongodb 自动生成的_id 是一串字符串呢
    abelyao
        14
    abelyao  
       2023-03-01 14:09:45 +08:00
    已经习惯了能用 uuid 就用 uuid 了,或者 nanoid - https://github.com/ai/nanoid
    god7d
        15
    god7d  
       2023-03-01 14:10:55 +08:00 via iPhone
    guid
    melkor
        16
    melkor  
       2023-03-01 14:11:14 +08:00 via iPhone   1
    用自增 ID 的这些建议,不考虑横向 sharding 问题吗?雪花生成全局唯一 ID 就行了
    fiypig
        17
    fiypig  
       2023-03-01 14:13:10 +08:00
    我第一家公司就用字符串的 用户账号, 现在的用自增,也有用 UUID ,我还没遇到过。。
    manasheep
        18
    manasheep  
       2023-03-01 14:13:59 +08:00
    无脑 GUID ( UUID )就可以了,MongoDB 的话用它自己的 ObjectID 也行
    dk7952638
        19
    dk7952638  
       2023-03-01 14:15:17 +08:00
    id 是给系统用的编码,no 是给人用的编码
    id 最好是自增,如果是分布式可以用雪花算法,自增可以提高数据库性能,还能实现游标分页
    no 一般都是有意义的,比如快递单号
    tool2d
        20
    tool2d  
       2023-03-01 14:17:43 +08:00
    爆破很好处理的,你 api 加密一下就可以了。或者加个一次性访问权限,nonce 那种参数。

    只要索引建的好,字符串查找速度也不慢的。
    LeegoYih
        21
    LeegoYih  
       2023-03-01 14:24:14 +08:00   3
    @superedlimited MongoDB 的 ObjectId 也是根据 Timestamp 和 MachineID 自增的 bigint ,只不过它是 12 字节 96 位的整数,用字符串方便展示
    superedlimited
        22
    superedlimited  
       2023-03-01 14:32:33 +08:00
    @LeegoYih #21 谢谢,我查了一下文档,原来它是 16 进制的数字。我是直接用的 mongodb 的免费 cloud 数据库,还没仔细看文档。
    vitoliu
        23
    vitoliu  
       2023-03-01 14:34:57 +08:00
    BIGINT 毋庸置疑,具体生成规则,看用户 ID 包含不包含对外业务含义,包含对外业务含义生成规则不能包含趋势递增。
    xuanbg
        24
    xuanbg  
       2023-03-01 14:37:17 +08:00
    我选择雪花 ID 。用字符串是什么鬼? UUID ?
    ktqFDx9m2Bvfq3y4
        25
    ktqFDx9m2Bvfq3y4  
       2023-03-01 15:04:42 +08:00 via iPhone
    @melkor
    有太多系统到废弃那天用户到不了那么多。自增没什么不好。
    ktqFDx9m2Bvfq3y4
        26
    ktqFDx9m2Bvfq3y4  
       2023-03-01 15:09:09 +08:00
    @chendy
    @cjbi
    @op351

    有种叫 hashid 的技术你可以了解一下,安全起见你还可以将数组化[id, randomId]这样,第 1 个是真正的 Id ,后面那个是验证码。
    acvrock
        27
    acvrock  
       2023-03-01 15:15:07 +08:00
    BIGINT +1,UID 大概率是其他业务表的索引,越短越好,最好趋势递增
    但是不能简单的自增,否则用户规模会被外部猜测出来,或者被扫描爆破
    pkoukk
        28
    pkoukk  
       2023-03-01 15:19:22 +08:00
    内部系统用数据库自增
    对外系统用雪花,UUID 太长了,占存储太多了,而且最主要的坑是如果拿 uuid 当主键,插入性能太差了
    虽然用户不太可能用户注册有太高并发,但是如果你需要用备份恢复一个库或者增加一个从库的时候就要疯
    chendy
        29
    chendy  
       2023-03-01 15:26:00 +08:00
    @Chad0000 学习了,原来有现成的东西可以用
    allinoneok
        30
    allinoneok  
       2023-03-01 15:30:51 +08:00
    如果你的 ID 需要写入 cookie 并加密就选择随机生成 id
    melkor
        31
    melkor  
       2023-03-01 15:40:59 +08:00 via iPhone
    @Chad0000 直接用雪花成本也不算高,关键是一旦要 sharding 那就很痛苦了,成本太高
    RICKEYGONG
        32
    RICKEYGONG  
       2023-03-01 15:47:34 +08:00
    Guid userId = new Guid();
    leeraya
        33
    leeraya  
       2023-03-01 15:52:56 +08:00
    bigint 够够的
    b821025551b
        34
    b821025551b  
       2023-03-01 15:53:26 +08:00
    @melkor 雪花成本应该是最高的,在大部分引擎下,无序主键会导致查询性能降低,以及空间浪费
    youisme
        35
    youisme  
       2023-03-01 15:57:23 +08:00
    @b821025551b 雪花算法是有序的
    afstyle
        36
    afstyle  
       2023-03-01 16:03:16 +08:00
    @b821025551b 建议你好好看看雪花 id 算法
    Ashore
        37
    Ashore  
       2023-03-01 16:08:18 +08:00 via Android
    你离职了以后都不会有那么多的用户的。放心吧
    cnbattle
        38
    cnbattle  
       2023-03-01 16:10:56 +08:00
    推荐雪花 id , 需要注意的数 如果前端是 js ,json str 转 json 对象 数字 大于 17 位时会丢失精度 得前端或后端特殊处理下
    karloku
        39
    karloku  
       2023-03-01 16:14:10 +08:00
    字符串的索引性能不行, 作为主键还是用整型好

    不管是 mongodb 的 ObjectId 还是 UUID 本质上也只是被表示为 16 进制的定长 bits, 在数据库里可以用 binary(12) 或者 binary(16) 存取. mysql8 里有直接用于转换字符串的函数 `UUID_TO_BIN()` / `BIN_TO_UUID()` 和生成用的 `UUID()` . postgres 则是直接支持 uuid 类型的字段, 支持在 sql 里用字符串进行写入和查询.
    不需要满足可排序性的时候可以用 uuidv4. 需要满足可排序性的时候可以用 mongodb 的 ObjectId 和 128 位的 ulid.
    litchinn
        40
    litchinn  
       2023-03-01 16:16:29 +08:00
    准确来说,雪花算法那个叫单调递增。
    参与的有一个项目,最开始是自增,但是后面有个客户有个需求,他部署了两套系统,A 、B ,但是每天要将 B 系统的数据全部同步到 A ,然而这些数据里有关联 id ,于是只能改成雪花算法生成的 id ,bigint
    也用过字符串类型的 id ,但是因为没办法单调递增且自己 debug 很不方便所以个人并不喜欢
    目前使用雪花算法 id ,数据库 bigint 并且设置自增
    BeforeTooLate
        41
    BeforeTooLate  
       2023-03-01 16:34:15 +08:00
    整数自增问题用户容易被爬虫遍历吧,比如你是 id1 ,我是 2 ,只要一个个试过去就行了
    liuidetmks
        42
    liuidetmks  
       2023-03-01 17:13:16 +08:00
    @BeforeTooLate 不成熟的想法,自增一个比较大的素数就行了。uint64 溢出也不要紧,正好相当于取模了
    realpg
        43
    realpg  
    PRO
       2023-03-01 17:19:42 +08:00
    unsigned uint64 自增
    多库分布系统就他自己自增 然后复合唯一索引带 node_id ,合并一起做 userid
    realpg
        44
    realpg  
    PRO
       2023-03-01 17:20:28 +08:00
    @BeforeTooLate
    数据库 ID 和前端显示 ID 为什么要统一?
    发送前和获取后过一个 o(n)复杂度的简单变换,别人不知道算法就完事
    Danfi
        45
    Danfi  
       2023-03-01 17:24:24 +08:00 via Android
    数据库查询用 bigint ,对外输出 hashid
    hulala1021
        46
    hulala1021  
       2023-03-01 17:31:07 +08:00   1
    职业生涯遇到过好几次数据库迁移,得到的教训就是数据库尽量不要用自增 id ,不然迁移表数据简直是灾难
    polo3584
        47
    polo3584  
       2023-03-01 17:58:01 +08:00
    区分 uid 和 uname 就行
    zzzzz001
        48
    zzzzz001  
       2023-03-01 20:39:49 +08:00
    @BeforeTooLate 平时写接口注意点,带上当前登录人的标记去数据库查,只查当前登录人的信息,不就避免被刷了吗。这样的思路很多
    ccagml
        49
    ccagml  
       2023-03-01 20:46:58 +08:00 via Android
    用户 id 直接数据库自增?都不分表的吗?
    lovelylain
        50
    lovelylain  
       2023-03-01 20:53:03 +08:00
    整型自增,对外加密,就像微信的 openid 一样,虽然不清楚具体实现,但应该是可以解密得到整型自增 uid 的
    lovelylain
        51
    lovelylain  
       2023-03-01 20:56:06 +08:00
    @ccagml 分库分表也可以自增呀,例如百库十表,取 uid 低 10 位标识在哪个表,右移 10 位得到在具体表中的自增 id
    hsuyeung
        52
    hsuyeung  
       2023-03-01 22:31:06 +08:00 via iPhone
    bigint ,然后对外 hashid
    wangritian
        53
    wangritian  
       2023-03-01 22:52:04 +08:00
    用了很多年 uuid ,完全代替了自增数字,并且封装在所有使用过的框架中
    除了一点点性能问题,好像没什么缺陷了吧
    zhaogaz
        54
    zhaogaz  
       2023-03-01 23:12:24 +08:00
    看需求吧。。

    首先看你这个用户 id 定义成什么,还有就是个人习惯,公司习惯,代码项目习惯啥的。

    有的是 us-xxxxx ;有的是 uuid ;有的是自增数;有的是长整数,这和 是不是字符串都没关系。。。

    你想问的是数据库的实现,和 用户 id 设计没啥关系。。数据库层面,一般用 固定 char 就行。。你数据库存成数字有什么优势么?你想一想

    然后再解释下自增 id:自增 id 相当于把 id 生成的事情扔到 db 了。看你们个人习惯和项目习惯,不是不可以。如果数据关联的逻辑也扔给 db ,这么做都没啥问题。

    其实都挺新手的问题,大概能猜到 op 工作环境。
    twofox
        55
    twofox  
       2023-03-01 23:38:17 +08:00
    无脑雪花主键啊。。UUID 不建议,太长和分散,不适合索引
    cjbi
        56
    cjbi  
    OP
       2023-03-02 00:15:40 +08:00
    @zhaogaz 你牛逼,这都能扯到工作环境
    ZhiyuanLin
        57
    ZhiyuanLin  
       2023-03-02 11:21:48 +08:00
    为了防爬虫丢掉自增 ID 有点小题大做了,用户量不大的话完全可以给进出 API 接口的自增 ID 跑个对称加密,防爬+性能兼得。这年头 AES 加解密的开销比 DB lookup 一个字串 ID 小多了。
    wind8866
        58
    wind8866  
       2023-03-02 12:00:01 +08:00
    用字符串作为 ID 的要注意一下数值特别大的情况,接口返回 JSON 格式时要用程序转成字符串,别超过最大安全数。吃过这方面的亏
    melkor
        59
    melkor  
       2023-03-02 17:32:01 +08:00 via iPhone
    @b821025551b 主键都是聚簇索引,都排好序的,为啥会影响读性能?
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5870 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 40ms UTC 03:22 PVG 11:22 LAX 20:22 JFK 23:22
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86