Skip to content

一个巧妙的数据结构设计的例子,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,正常开发场景下极少用到位运算。