我有一堆布尔选项,比如“可接受的支付类型”,可以包括现金,信用卡,支票,贝宝等等,而不是在我的数据库中有半打布尔,我可以使用整数并为每个付款方式分配一个整数,如此
PAYMENT_METHODS = (
(1<<0, 'Cash'),
(1<<1, 'Credit Card'),
(1<<2, 'Cheque'),
(1<<3, 'Other'),
)
然后查询python中的特定位以检索标志。我知道这意味着数据库无法通过特定标志进行索引,但是还有其他缺点吗?
为什么我这样做:我已经有大约15个布尔值,分成3个不同的逻辑“集合”。这已经是很多领域,并且使用3个多对多表来保存很少变化的数据似乎效率低下。使用整数允许我为每个字段添加最多32个标志,而不必修改数据库。
答案 0 :(得分:6)
我能想到的主要缺点是可维护性。对数据库编写查询的人必须理解位约定,而不是能够追求更易读的一组列。此外,如果删除了“已接受的付款类型”之一,则必须迁移数据本身,而不是仅删除表中的列。
答案 1 :(得分:2)
这不是最糟糕的,但可能有更好的方法。
定义名为PaymentTypes的表
id, paymentId, key (string), value (boolean)
现在你只需用你想要的任何东西填充这个表。没有长列的布尔值,您可以动态添加新类型。这样做的缺点是所有布尔值的默认值都是NULL或false。
答案 2 :(得分:2)
不确定您使用的数据库,但MySQL有set type。
答案 3 :(得分:1)
如果您可以将用例限制为一次只能有一位真值的一组或多组值,那么您可以在数据库中使用枚举。你会得到两个世界中最好的,像btreat笔记一样可维护,并且比几个布尔都更小(也更简单)。
既然那是不可能的,我会同意你的初步建议,并选择一个位域。我会使用/创建一个位域包装器,所以在你的代码中你不直接处理翻转和移位 - 这变得难以维护和调试,正如btreat所说 - 而是像列表或字典一样处理它在需要时转换为/从位域转换。
答案 4 :(得分:1)
我认为之前的海报都是正确的。在“关系型”数据库中执行此操作的最简单方法是定义存储付款类型的新关系表。但在实践中,这通常比它的价值更麻烦。
在你的代码中使用枚举并在数据库中使用类似的东西(检查Oracle中的约束,AFAIK)应该有助于保持它的可维护性,并且对于那些工作的穷人而言显而易见的是,添加一种新类型,很多年之后你离开了