举个例子,有一类数据,它大概有几百多种属性,属性的正好也只有 0 和 1 这两种可能。
在这种情况下,应该挑选哪个类型的字段来存储这个数据呢?需要满足以下条件:
1
yangg 68 天前
你存属性为啥 描述是第 5 个,第 77 个,而不是属性 a ,属性 b ?,后面这种属性直接存 json
|
2
yangg 68 天前
哦,明白了, 多个 BIGINT 也可以, 就是不直观,你不赚麻烦也可以
|
3
just1 68 天前 via Android
bool?
|
4
akira 68 天前
你可以看一下 set 和 bitmap
|
5
jy28520 68 天前
用 JSON 格式,检索的时候直接按照键查询为 1 的
|
6
mainjzb 68 天前
WHERE
field&1<<5 >0 && field&1<<77 >0 && field&1<<100 >0 |
7
hiboshi 68 天前
能不能将这些数据位图化看看能不能解决,创建一个字段类型是 blob , 关键词: mysql bitmap
|
8
gainsurier 68 天前
> 用多个 BIGINT 存储可行么
可行,field1 ,field2 ,field3...... |
9
dode 68 天前
使用 id,type,value 数据库增加一个属性列,简单明了,查询方便
|
11
wellerman 68 天前
用多个字段存代价太大,这类属性大概还会动态增加,维护太不划算了。
只用一个 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) 或者如楼上,增加一个属性表。 |
12
ntedshen 67 天前
bigint 我之前测试过四五个属性的情况,可行而且位运算的性能在我这里比 mariadb 的 set 还优秀一些。。。
就是维护比较地狱。。。 也没测过几百个会是什么情况。。。 find_in_set 我现在会用来存一些标签但是性能确实太不好看了,最近正在切到 json 。。。 |
13
sagaxu 67 天前
存储用多个 BIGINT 可以,查但询很麻烦。如果检索条件是这些 bits ,用 mysql 不太适合,每次都扫全表 100 万行就不行了,这种要上搜索引擎。
|
14
Donjote 67 天前
好像容易出现慢 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 行。 |
15
hhhhhccccc 66 天前
这种我用的 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 真的爽 |
16
sngxx 66 天前
1. 不管什么类型你都当成 bitmap 处理,空间都一样啊,除非你会做压缩——去掉尾部的 0 ;
2. mysql 没有 getbit 功能,你得先查出列的所有内容再 getbit ,用 mysql 的内置方法比如 SUBSTRING 执行时也是要查出整体才处理的; 3. 可行,将 bitmap 分段,查询一个 bit 时只需要查出一个 bigint 再取 bit ; |