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

Php 应该是什么样的标志/权限实现?,php,mysql,Php,Mysql,我有个问题。我应该如何实现可以不断添加/更改的权限 现在我有这个: 我的数据库表方案具有字段标志 我可以通过以下方式选择所需内容:例如,select*从某个_表中选择标志&'.FLAG_CLOSED | FLAG_ACTIVE'='.FLAG_CLOSED | FLAG_ACTIVE 所有标志都是代码中的常量 示例代码,仅用于理解我的意思(它不是真正的代码,甚至没有经过测试): 仅通过一个字段比较就可以很容易地得到过滤结果,但在代码中更改它却很烦人 另一种方法是制作额外的表,该表应该有标志和

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

现在我有这个:

  • 我的数据库表方案具有字段
    标志
  • 我可以通过以下方式选择所需内容:例如,
    select*从某个_表中选择标志&'.FLAG_CLOSED | FLAG_ACTIVE'='.FLAG_CLOSED | FLAG_ACTIVE
  • 所有标志都是代码中的常量
示例代码,仅用于理解我的意思(它不是真正的代码,甚至没有经过测试):

仅通过一个字段比较就可以很容易地得到过滤结果,但在代码中更改它却很烦人

另一种方法是制作额外的表,该表应该有标志和值。但是什么会更有效率呢?值应该有基于位字段的值(即1、2、4、8等等)还是其他值,如“关闭”、“活动”

在这两种情况下,表行如下所示:

id, description, flags
===============
1, 'test', 0x12
1, 'test', 'CLOSED,ACTIVE'
在第二种情况下,我需要按“WHERE标志,如“%CLOSED%”和“%ACTIVE%”进行筛选

哦。。下面是实现标志的另一种方法。创建具有
Id
标志的表的步骤。比如:

Id,  flag
========
1, CLOSED
1, ACTIVE
这里可能存在更高效的实施

p、 这是第一个问题,请耐心等待


p、 另外,我不需要完全重复这个方案,我只是请求一个建议,如何用更有效的方法实现,它可以是绝对简单的实现,没有任何位字段值。

不要使用单个标志字段,使用一个表,每个标志有单独的行

CREATE TABLE flags (
    thing_id INT,
    flag VARCHAR(32),
    PRIMARY KEY (thing_id, flag),
    FOREIGN KEY (thing_id) REFERENCES things (id),
    INDEX (flag)
);
行将如下所示:

thing_id flag
1       active
1       closed
2       closed
3       deleted
3       active
然后,要查找具有特定标志的所有内容,请加入表:

SELECT t.* 
FROM things AS t
JOIN flags as f ON f.thing_id = t.id
WHERE f.flag = 'closed';
要获取某事物的所有标志,请使用
GROUP\u 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

如果要防止创建不应该存在的标志,可以将
标志
列作为外键放入
标志名称
表中。

如果确实要这样做,请查看
数据类型。但我建议您只创建一个表,其中每个标志位于单独的行中,而不是将它们作为位组合,因为这样的位字段不能被索引。@Barmar,谢谢您的建议,看起来我需要它,但是我可以通过新标志扩展集合而不受任何影响吗?例如,假设该表有700k条记录?我可以从数据库中检索所有的设置值吗?至于效率呢,尽管我可以使用缓存……只要不改变
集合
元素的顺序,就可以毫无问题地扩展它
SET
在内部作为一个位字段实现,就像您正在做的一样。但是想要扩展
SET
并获得所有这些值的列表,这两个都是使用@Barmar建议的相关表而不是在模式定义中嵌入这些特征的重要原因。
SET
效率不高,它们不能被索引。在内部,它就像您的
WHERE
子句一样,因此它必须进行完整的表扫描以匹配元素。这就是为什么我建议你使用一个单独的表格,而不是这两种方法中的任何一种。谢谢你的回答。这就是我想要听到的全部(甚至更多)。。非常感谢。作为建议-如果值为int(1,2,4…32),可以通过一些限制进行改进。我们可以不使用
concat
而使用
sum
获得所有标志。限制-在不支持bigint的情况下,每个
对象的标志不能超过32/64。事实上,我们公司有一个带有numeric
flags
列的表,当溢出时,我们切换到这个方法。为了使用数字标志编写的所有应用程序,我们添加了一个存储函数进行转换。
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