考虑下表:
CREATE TABLE user_roles(
pkey SERIAL PRIMARY KEY,
bit_id BIGINT NOT NULL,
name VARCHAR(256) NOT NULL,
);
INSERT INTO user_roles (bit_id,name) VALUES (1,'public');
INSERT INTO user_roles (bit_id,name) VALUES (2,'restricted');
INSERT INTO user_roles (bit_id,name) VALUES (4,'confidential');
INSERT INTO user_roles (bit_id,name) VALUES (8,'secret');
CREATE TABLE news(
pkey SERIAL PRIMARY KEY,
title VARCHAR(256),
company_fk INTEGER REFERENCES compaines(pkey), -- updated since asking the question
body VARCHAR(512),
read_roles BIGINT -- bit flag
);
read_roles 是一个位标志,它指定可以阅读新闻项目的某些角色组合。因此,如果我要插入一个可以被受限和机密阅读的新闻项目,我会将 read_roles 的值设置为2 | 4
或 6,并且当我想取回特定用户可以看到的新闻帖子时,我可以使用类似的查询。
select * from news WHERE company_fk=2 AND (read_roles | 2 != 0) OR (read_roles | 4 != 0) ;
select * from news WHERE company_fk=2 AND read_roles = 6;
通常在数据库列中使用位标志有什么缺点?我假设这个问题的答案可能是特定于数据库的,所以我有兴趣了解特定数据库的缺点。
我正在为我的应用程序使用 Postgres 9.1。
更新我了解到数据库不使用索引进行位操作,这将需要全表扫描,这会降低性能。所以我更新了这个问题以更准确地反映我的情况,数据库中的每一行都属于一个特定的公司,所以所有的查询都将有 WHERE 子句,其中包含一个 company_fk ,它上面会有一个索引。
更新我现在只有 6 个角色,将来可能会更多。
UPDATE角色不是互斥的,它们相互继承,例如,restricted 继承了分配给 public 的所有权限。