此选项列表是不是可以接受数据库中的布尔标志?
Posted
技术标签:
【中文标题】此选项列表是不是可以接受数据库中的布尔标志?【英文标题】:Are boolean flags in a database acceptable for this list of options?此选项列表是否可以接受数据库中的布尔标志? 【发布时间】:2009-04-17 14:06:52 【问题描述】:我正在将用户提交的 cmets 添加到个人项目中。
评论有许多特殊用途的标志。出于审核目的,还对评论进行了版本控制,因此特定字段不需要时间戳。
这些是我目前在功能设计中的选项。 (列表不是最终的)这个列表会在某个时候改变,因为我知道我还没有弄清楚所有事情。
已换行(文本隐藏在 javascript 链接后面) 隐藏(评论文本对非版主隐藏) 已锁定(无法编辑) 已删除(评论已删除) 版主(隐藏发帖人姓名) 管理员(与版主相同,但版主无法编辑) Hellbanned(除海报外的行为已删除)有一些规则可以控制哪些标志可以一起存在。 (就显示而言。)
管理员/版主 cmets 不应被包装、隐藏、锁定或禁止。 (版主不能被封杀) 评论不能同时是管理员和版主评论。 Hellbanned 不应该被删除。 评论不能同时包装和隐藏 应锁定隐藏的 cmets。布尔标志是否足以在数据库中实现这一点? (我将 Ruby on Rails 与 SQLite/mysql 一起使用,因此数据库不能有触发器/约束)
【问题讨论】:
【参考方案1】:这是布尔标志的问题:它们只有两种状态。
事实证明,很多事情都有多个条件,而一个简单的布尔值证明是不够的。
有些东西实际上可能是布尔值。然而,这种情况很少见。
我建议不要使用布尔值,而是使用某种值枚举。
Wrapped(文本隐藏在 javascript 链接后面)。看起来是布尔值:有链接或没有链接。遗憾的是,您可能有不同类型的链接(内部、外部等),因此这可能会超过两个值。
隐藏(评论文本对非版主隐藏)。看起来是布尔值——隐藏与否。当然,除了非版主的定义可能会扩大,这会变得更加复杂。
已锁定(无法编辑)。看起来是布尔值,锁定或打开。除非您可能已锁定一类用户但未锁定另一类用户。布尔值分解。
已删除(评论已删除)。布尔值,直到您添加待删除或需要再次投票删除。
版主(隐藏发帖人的姓名)。布尔值,直到您拥有其他类别的用户、超级用户、更多特权用户和更少特权用户。
Hellbanned(除海报外的行为已删除)。这似乎是评论作者的一个特征,而不是评论本身。这甚至不属于这里,而是属于您模型的其他地方。
我投票支持枚举值而不是简单的真/假。
【讨论】:
@epochwolf:你的改变很好地强调了我的观点。感谢您发布。【参考方案2】:您可以将这些实现为布尔标志列,或者具有一个充当位掩码的 int 列。有些人可能会争辩(他们在技术上是正确的)数据库中的位掩码违反规范化(因为多个“值”存储在单个列中),但我发现它们在过去很有用。唯一的问题是它会降低代码的可读性。
不过,最后我想说你的方法没有错。
【讨论】:
鉴于在为视图选择行时需要忽略已删除和禁止的 cmets,我必须将它们设为布尔值。 不,SQL 有可以使用的位运算符(AND、OR 等)。例如,如果第一位是“已删除”,则所有未删除的消息都将是 select * from messages where (flags AND 1) = 0【参考方案3】:对于规则,您似乎有两个选择:
-
您可以尝试设置约束和触发器,以确保任何不良数据都不能进入数据库
您可以通过函数上的前置条件和后置条件(不一定是编码的前置和后置条件,但明确定义和遵守的条件)在应用代码中确保它们不会引入错误数据。然后,您可以定期运行 Bad Data 脚本,以提醒您任何违反规则的行为。
无论如何你都需要做一些#2,除非你打算在数据库中引发异常并在客户端处理它们(这对我来说很难闻......)但我想我会犹豫做#1,除非你涵盖所有情况,因为如果你不这样做,你会在那里强制执行一些,而有些则不会,这对我来说也很糟糕......
【讨论】:
发布更新,忘记了管理员 cmets,我正在使用 SQLite 进行开发,所以我不能做触发器。以上是关于此选项列表是不是可以接受数据库中的布尔标志?的主要内容,如果未能解决你的问题,请参考以下文章