应该是什么样的标志/权限实现?

时间:2016-08-31 16:41:00

标签: php mysql

我有问题。我应该如何实现可以不断添加/更改的权限?

现在我有了这个:

  • 我的数据库表方案有字段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%' ?

哦..这是实现标志的另一种方法。制作包含IdFlag的表格。像:

Id,  flag
========
1, CLOSED
1, ACTIVE

可能在这里存在更高效的实施?

P.S。为了给您带来不便,这是第一个问题,请耐心等待

p.p.s。我不需要完全重复这个方案,我只是请求一个建议,如何以更有效的方式做到这一点,它可以是绝对简单的实现,没有任何位字段值。

1 个答案:

答案 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.