使用整数作为位域的缺点?

时间:2010-06-16 23:13:15

标签: django database-design bit-manipulation

我有一堆布尔选项,比如“可接受的支付类型”,可以包括现金,信用卡,支票,贝宝等等,而不是在我的数据库中有半打布尔,我可以使用整数并为每个付款方式分配一个整数,如此

PAYMENT_METHODS = (
    (1<<0, 'Cash'),
    (1<<1, 'Credit Card'),
    (1<<2, 'Cheque'),
    (1<<3, 'Other'),
)

然后查询python中的特定位以检索标志。我知道这意味着数据库无法通过特定标志进行索引,但是还有其他缺点吗?

为什么我这样做:我已经有大约15个布尔值,分成3个不同的逻辑“集合”。这已经是很多领域,并且使用3个多对多表来保存很少变化的数据似乎效率低下。使用整数允许我为每个字段添加最多32个标志,而不必修改数据库。

5 个答案:

答案 0 :(得分:6)

我能想到的主要缺点是可维护性。对数据库编写查询的人必须理解位约定,而不是能够追求更易读的一组列。此外,如果删除了“已接受的付款类型”之一,则必须迁移数据本身,而不是仅删除表中的列。

答案 1 :(得分:2)

这不是最糟糕的,但可能有更好的方法。

定义名为PaymentTypes的表

id, paymentId, key (string), value (boolean)

现在你只需用你想要的任何东西填充这个表。没有长列的布尔值,您可以动态添加新类型。这样做的缺点是所有布尔值的默认值都是NULL或false。

答案 2 :(得分:2)

不确定您使用的数据库,但MySQL有set type

答案 3 :(得分:1)

如果您可以将用例限制为一次只能有一位真值的一组或多组值,那么您可以在数据库中使用枚举。你会得到两个世界中最好的,像btreat笔记一样可维护,并且比几个布尔都更小(也更简单)。

既然那是不可能的,我会同意你的初步建议,并选择一个位域。我会使用/创建一个位域包装器,所以在你的代码中你不直接处理翻转和移位 - 这变得难以维护和调试,正如btreat所说 - 而是像列表或字典一样处理它在需要时转换为/从位域转换。

Some commentary on enums/bitfields in Django

答案 4 :(得分:1)

我认为之前的海报都是正确的。在“关系型”数据库中执行此操作的最简单方法是定义存储付款类型的新关系表。但在实践中,这通常比它的价值更麻烦。

在你的代码中使用枚举并在数据库中使用类似的东西(检查Oracle中的约束,AFAIK)应该有助于保持它的可维护性,并且对于那些工作的穷人而言显而易见的是,添加一种新类型,很多年之后你离开了