在写一个新的网站系统,其中有一列“A”是帖子属性,大体存储访问权限、内容分级、编辑锁定等。因为使用的是SQLite,其Integer类型是可变字节,可以根据长度分为1,2,3,4,6,8等字节存储。为了最省数据库空间,我准备将属性列全部采用2字节存储。
针对帖子筛选,
访问权限包括:公开(↓) 审核(4) 私有(5) 回收(6)
公开内容分级:普通(0) 精选(1) 淡化(2) 隐藏(3)
所有内容等级加起来刚好6个分类。
这时候我就想到,2字节长度是65535,这样的话第一个字符“6”刚好用来存储访问权限。
那么在创建索引和查询的时候,使用如下SQL语句:
CREATE INDEX `test_index` ON `test_table` (CAST(SUBSTR(`A`, 1, 1) AS INTEGER));
SELECT * FROM `test_table` WHERE CAST(SUBSTR(A, 1, 1) AS INTEGER) = 2;
刨去最开头的6作为索引字符,后面还剩5535,大于4095,可以容纳12个二进制bit。
里面占用2bit用来存储内容分级的4种结果),防止头部“6”字符变更后分级信息丢失。
这样还剩10bit,可以用来存储其它开关属性,可以满足大部分选项要求。
我们在数据表上建立两条索引,分别是:
(A)-Time-ID
User-(A)-Time-ID
这样用户可以查看:个人私有内容/审核中的内容/回收站的内容
在公开列表中,部分内容处于被隐藏列(3-Time-ID),用户浏览时也可以额外查询(Uid-3-Time-ID)这部分内容,并将其与公开列表合并,给用户造成自己所发内容没有被隐藏的假象。