用户信息的标签化
《漫画:Bitmap算法 整合版》写的非常好,一定要拜读下。这里,我想把文中提到的“用户信息的标签化”这个需求用代码实现一下。
系统维护一个标签字典表t_tag,可能有成百上千个标签,这里仅定义10个标签示意:
id | tag |
---|---|
1 | 男 |
2 | 女 |
3 | 90后 |
4 | 00后 |
5 | 程序员 |
6 | 学生 |
7 | 苹果 |
8 | 三星 |
9 | 小米 |
10 | 华为 |
用户信息表t_user:
id | user_name |
---|---|
1 | 小灰 |
2 | 小黄 |
3 | 小白 |
标签id、用户id关联表t_tag_user(多个用户id以英文逗号分割,无序):
tag_id | user_ids |
---|---|
1 | 1,2 |
2 | 3 |
3 | 1,2 |
4 | 3 |
5 | 2,1 |
6 | 3 |
7 | 1 |
8 | 2 |
9 | 3 |
import org.junit.Test;
import java.util.BitSet;
public class BitSetTest {
/**
* 统计总数:90后、且是程序员
*/
@Test
public void test4() {
// TODO: 如何初始化nbits,待完善
int nbits = 8;
BitSet bitSet1 = new BitSet(nbits);
// 1. select user_ids from t_tag_user where tag_id = 3
// 2. 得到1,2
bitSet1.set(1);
bitSet1.set(2);
// 3. select user_ids from t_tag_user where tag_id = 5
// 4. 得到2,1
BitSet bitSet2 = new BitSet(nbits);
bitSet2.set(2);
bitSet2.set(1);
bitSet1.and(bitSet2);
System.out.println("### 90后、且是程序员的总数:" + bitSet1.cardinality());
}
/**
* 统计总数:00后、且是程序员
*/
@Test
public void test5() {
// TODO: 如何初始化nbits,待完善
int nbits = 8;
BitSet bitSet1 = new BitSet(nbits);
// 1. select user_ids from t_tag_user where tag_id = 4
// 2. 得到3
bitSet1.set(3);
// 3. select user_ids from t_tag_user where tag_id = 5
// 4. 得到2,1
BitSet bitSet2 = new BitSet(nbits);
bitSet2.set(2);
bitSet2.set(1);
bitSet1.and(bitSet2);
System.out.println("### 00后、且是程序员的总数:" + bitSet1.cardinality());
}
/**
* 统计总数:使用苹果手机、且是程序员
*/
@Test
public void test6() {
// TODO: 如何初始化nbits,待完善
int nbits = 8;
BitSet bitSet1 = new BitSet(nbits);
// 1. select user_ids from t_tag_user where tag_id = 7
// 2. 得到1
bitSet1.set(1);
// 3. select user_ids from t_tag_user where tag_id = 5
// 4. 得到2,1
BitSet bitSet2 = new BitSet(nbits);
bitSet2.set(2);
bitSet2.set(1);
bitSet1.and(bitSet2);
System.out.println("### 使用苹果手机、且是程序员的总数:" + bitSet1.cardinality());
}
/**
* 统计总数:男性,或者00后
*/
@Test
public void test7() {
// TODO: 如何初始化nbits,待完善
int nbits = 8;
BitSet bitSet1 = new BitSet(nbits);
// 1. select user_ids from t_tag_user where tag_id = 1
// 2. 得到1,2
bitSet1.set(1);
bitSet1.set(2);
// 3. select user_ids from t_tag_user where tag_id = 4
// 4. 得到3
BitSet bitSet2 = new BitSet(nbits);
bitSet2.set(3);
bitSet1.or(bitSet2);
System.out.println("### 男性,或者00后的总数:" + bitSet1.cardinality());
}
/**
* 统计总数:非90后
* 等效于:90后 异或 全量用户
*/
@Test
public void test8() {
// TODO: 如何初始化nbits,待完善
int nbits = 8;
BitSet bitSet1 = new BitSet(nbits);
// 1. select user_ids from t_tag_user where tag_id = 3
// 2. 得到1,2
bitSet1.set(1);
bitSet1.set(2);
// 3. select distinct id from t_user
// 4. 得到1,2,3
BitSet bitSet2 = new BitSet(nbits);
bitSet2.set(1);
bitSet2.set(2);
bitSet2.set(3);
bitSet2.xor(bitSet1);
System.out.println("### 非90后的总数:" + bitSet2.cardinality());
}
}
如何初始化BitSet(int nbits)中的nbits
以t_tag_user表user_ids列中,最大的那个user_id,作为nbits。