一个巧妙的数据结构设计的例子,bitmap的使用
需求
假设有这么一个需求
- 需要多次插入数据
- 能方便的导出每次插入的数据
- 用一张数据表完成需求
具体需求阐述
第一次插入10W条数据,第二次插入4W条数据,第三次插入5W条数据,第4次插入1W条数据,可能后面还有N次,注意每次插入的数据量级,这个是为什么不用主子表实现的关键因素,用主子表会导致子表记录数的快速膨胀,另一个重要的假设是上面的数据如果取并集,一共大概11W,远小于计次的20W。N越大,并集越小,这个设计的好处越明显。
假设插入数据的频率是一天一次,每次插入之后都会有其他程序按照主键来更新数据,比如爬虫。最终能方便的按次取数据。
实现
库表设计
sql
CREATE TABLE example_table (
id INT PRIMARY KEY AUTO_INCREMENT,
bitmap INT
-- 其他数据列省略...
);
INSERT INTO example_table (bitmap) VALUES
(5), -- 0101
(3), -- 0011
(7); -- 0111
插入数据的方法
每次插入数据如果主键重复则执行更新操作,bitmap列是加上2的N-1次方,如果是新记录则直接是2的N-1次方
取数据的方法
sql
-- 要导出第N次的数据,则直接查询bitmap列的第N-1位是否为1(表示第N次插入或者更新过这条数据);
-- 可以使用以下查询,序号是从右往左且从0开始的
SELECT id, bitmap
FROM example_table
WHERE bitmap & (1 << N) != 0;
最核心的设计就是这个 bitmap & (1 << N) != 0
,正常开发场景下极少用到位运算。