我有问题。我应该如何实现可以不断添加/更改的权限?
现在我有了这个:
flags
SELECT * from some_table WHERE flags&'.FLAG_CLOSED|FLAG_ACTIVE.'='.FLAG_CLOSED|FLAG_ACTIVE;
示例代码,只是为了弄清楚我的意思(它不是真正的代码,它甚至没有经过测试):
class Sample {
const FLAG_ACTIVE = 0x01;
const FLAG_CLOSED = 0x02;
const FLAG_DELETED = 0x04;
private $db;
public function __construct(...) {
/* ... */
}
public function getClosed() {
$flags = self::FLAG_ACTIVE | self::FLAG_CLOSED;
$query = 'SELECT * FROM `test` WHERE `flags`&'.$flags.'='.$flags;
$stmt = $this->db->query($query);
return $stmt->fetch(\PDO::FETCH_ASSOC);
}
}
通过一次字段比较很容易获得过滤结果,但在代码中更改它会很烦人。
另一种方法是创建附加表,该表应具有标志和值。但什么会更有效?值应该具有基于位域的值(即1,2,4,8,...等)或其他类似值,例如“关闭”,“活动”等。 ?
在这两种情况下,表格行将如下所示:
id, description, flags
===============
1, 'test', 0x12
1, 'test', 'CLOSED,ACTIVE'
在第二种情况下,我需要通过`WHERE标志来过滤,例如'%CLOSED%'和标志像'%ACTIVE%' ?
哦..这是实现标志的另一种方法。制作包含Id
和Flag
的表格。像:
Id, flag
========
1, CLOSED
1, ACTIVE
可能在这里存在更高效的实施?
P.S。为了给您带来不便,这是第一个问题,请耐心等待
p.p.s。我不需要完全重复这个方案,我只是请求一个建议,如何以更有效的方式做到这一点,它可以是绝对简单的实现,没有任何位字段值。
答案 0 :(得分:2)
Don't use a single flag field for this, use a table with a separate row for each flag.
CREATE TABLE flags (
thing_id INT,
flag VARCHAR(32),
PRIMARY KEY (thing_id, flag),
FOREIGN KEY (thing_id) REFERENCES things (id),
INDEX (flag)
);
Rows will look like:
thing_id flag
1 active
1 closed
2 closed
3 deleted
3 active
Then to find all the things with a particular flag, you join the table:
SELECT t.*
FROM things AS t
JOIN flags as f ON f.thing_id = t.id
WHERE f.flag = 'closed';
To get all of a thing's flags, use GROUP_CONCAT
SELECT t.*, GROUP_CONCAT(f.flag) AS flags
FROM things AS t
JOIN flags as f ON f.thing_id = t.id
WHERE t.id = :thing_id
If you want to prevent creating flags that shouldn't exist, you could make the flag
column a foreign key into a flag_names
table.