请问,如果需要 MySQL 存储几百个二进制位的数据,该用什么类型 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
awesomePower
V2EX    程序员

请问,如果需要 MySQL 存储几百个二进制位的数据,该用什么类型

  •  
  •   awesomePower 2024-09-07 16:49:20 +08:00 2787 次点击
    这是一个创建于 399 天前的主题,其中的信息可能已经有所发展或是发生改变。

    举个例子,有一类数据,它大概有几百多种属性,属性的正好也只有 0 和 1 这两种可能。

    在这种情况下,应该挑选哪个类型的字段来存储这个数据呢?需要满足以下条件:

    1. 空间占用尽量小
    2. 需要方便查询,比如我需要筛选出第 5 个、第 77 个、第 100 个属性...是 1 的数据(同时是 1 或者其中有一个是 1 这两种情况都需要查询)
    3. 用多个 BIGINT 存储可行么
    16 条回复    2024-09-10 10:13:42 +08:00
    yangg
        1
    yangg  
       2024-09-07 17:04:31 +08:00
    你存属性为啥 描述是第 5 个,第 77 个,而不是属性 a ,属性 b ?,后面这种属性直接存 json
    yangg
        2
    yangg  
       2024-09-07 17:10:16 +08:00
    哦,明白了, 多个 BIGINT 也可以, 就是不直观,你不赚麻烦也可以
    just1
        3
    just1  
       2024-09-07 17:29:55 +08:00 via Android
    bool?
    akira
        4
    akira  
       2024-09-07 17:45:29 +08:00
    你可以看一下 set 和 bitmap
    jy28520
        5
    jy28520  
       2024-09-07 17:45:37 +08:00
    用 JSON 格式,检索的时候直接按照键查询为 1 的
    mainjzb
        6
    mainjzb  
       2024-09-07 18:01:15 +08:00
    WHERE
    field&1<<5 >0 &&
    field&1<<77 >0 &&
    field&1<<100 >0
    hiboshi
        7
    hiboshi  
       2024-09-07 19:49:17 +08:00
    能不能将这些数据位图化看看能不能解决,创建一个字段类型是 blob , 关键词: mysql bitmap
    gainsurier
        8
    gainsurier  
       2024-09-07 20:15:36 +08:00
    > 用多个 BIGINT 存储可行么
    可行,field1 ,field2 ,field3......
    dode
        9
    dode  
       2024-09-07 22:16:39 +08:00
    使用 id,type,value 数据库增加一个属性列,简单明了,查询方便
    vibbow
        10
    vibbow  
       2024-09-08 02:47:44 +08:00
    @mainjzb 这么查就是性能地狱...
    wellerman
        11
    wellerman  
       2024-09-08 10:48:05 +08:00
    用多个字段存代价太大,这类属性大概还会动态增加,维护太不划算了。

    只用一个 string 字段就行,存成 1-0,3-1,4-0,5-1,22-0,77-1,100-1 等,后面想要增加也不用动数据库。

    查询条件 FIND_IN_SET('5-1', attrs) and FIND_IN_SET('77-1', attrs) and FIND_IN_SET('100-1', attrs)

    或者如楼上,增加一个属性表。
    ntedshen
        12
    ntedshen  
       2024-09-08 19:39:36 +08:00
    bigint 我之前测试过四五个属性的情况,可行而且位运算的性能在我这里比 mariadb 的 set 还优秀一些。。。
    就是维护比较地狱。。。
    也没测过几百个会是什么情况。。。

    find_in_set 我现在会用来存一些标签但是性能确实太不好看了,最近正在切到 json 。。。
    sagaxu
        13
    sagaxu  
       2024-09-08 20:25:40 +08:00
    存储用多个 BIGINT 可以,查但询很麻烦。如果检索条件是这些 bits ,用 mysql 不太适合,每次都扫全表 100 万行就不行了,这种要上搜索引擎。
    Donjote
        14
    Donjote  
       2024-09-09 13:22:11 +08:00
    好像容易出现慢 sql 。
    SQL: SELECT COUNT(1) FROM attendance_daily_report_08 WHERE is_deleted = 0 AND attend_org_id = 521 AND attend_date BETWEEN '20240801' AND '20240831' AND attend_status & (2 | 4 | 8 | 16 | 8192) > 0;
    最后一次出现时间:2024-09-09 13:10:41
    5.0 分钟内总计执行 1 次,平均执行 3.906956 秒,平均锁 0.000097 秒,最大执行 3.906956 秒, 最大扫描 68853 行, 最大返回 1 行。
    hhhhhccccc
        15
    hhhhhccccc  
       2024-09-09 15:10:16 +08:00
    这种我用的 json, 索引上用的 multi-value index, 但是几百个的我还真没整过, 可以试下


    属性就存 id, 有的话, 值为 1, 就把属性 id 放到 attrs 中,

    create table demo (
    id int unsigned primary key,
    name varchar(255) not null,
    attrs json, -- int[], id 从另外一张表来
    created_at xx,
    updated_at xx,
    index idx_attrs ((cast(attrs as unsigned array)))
    );


    你的要求
    1. 占用空间尽量小 [v]
    2. 查询方便 [v]
    同时是 1
    select json_contains(json_array(1,2,3), json_array(1,2)); -> 1
    select json_contains(json_array(1,2,3), json_array(1,2, 3)); -> 0
    select id, name from demo where json_contain(demo, '[1,2,3]');


    其中有一个是 1
    select json_overlaps(json_array(1,2,3), json_array(1,2,4)); -> 1
    select json_overlaps(json_array(1,2,3), json_array(4)); -> 0
    select id, name from demo where json_overlaps(demo, '[1,2,3]');

    只查一个的话, 可以用 member of


    项目中已经用了, 非常爽
    总共数据量几百万, 快上千万, 速度快, explain 就知道不是 ref, 是 range

    使用 json 的话, 写 sql 有时候会麻烦很多, 并且要做好前置的校验, 当然用 json 真的爽
    sngxx
        16
    sngxx  
       2024-09-10 10:13:42 +08:00
    1. 不管什么类型你都当成 bitmap 处理,空间都一样啊,除非你会做压缩去掉尾部的 0 ;
    2. mysql 没有 getbit 功能,你得先查出列的所有内容再 getbit ,用 mysql 的内置方法比如 SUBSTRING 执行时也是要查出整体才处理的;
    3. 可行,将 bitmap 分段,查询一个 bit 时只需要查出一个 bigint 再取 bit ;
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2730 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 07:36 PVG 15:36 LAX 00:36 JFK 03:36
    Do have faith in what you're doing.
    ubao 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