布尔标志字段的模式设计(数据库体系结构)

时间:2013-12-25 09:46:00

标签: python sql database-design django-models database-schema

背景

该架构适用于附近餐馆的个人应用程序。我正在用两种方法来存储单值布尔值(true / false)。

我在机器人技术方面的背景迫使我考虑减少数据库占用空间。我可能是非常错的。

项目

这个应用程序将有餐厅名称和某些单个标志字段。这些固定属性不会很快改变:

选项1:同一表格中的单个标志或与餐厅ID相关联的特定1:1属性表。

Rest ID  | hasOutdoor | hasDelivery | hasWifi
Rest1    |  1         |  1          |  1     
Rest2    |  0         |  1          |  0

以编程方式,选项1很容易;为每家餐馆提取个人财产。

选项2:包含所有属性的一个字符串字段。

Rest ID | Property
Rest1   |  "111"             
Rest2   |  "010"  

这将占用较小的数据库占用空间,但在编程上非常需要处理

python中的示例:

PropertySet = ['hasOutDoors', 'hasDelivery', 'hasWifi'] 
for eachChar in Rest1.Property:
    if int(eachChar):
        PropertySet.pop()

输出:

'hasOutDoors'
'hasDelivery'

备选方案2的主要缺点:

  1. 代码和数据库对象是混合的。如果在DB中添加了新属性并且需要在代码中进行相同的更改,则可能会终止系统。

  2. 难以编码(并且处理繁重)“获得具有hasOutdoor属性的所有休息”!

  3. 有更好的存储0/1值的方法还是选项1最好?

2 个答案:

答案 0 :(得分:3)

使用布尔字段。它们存在是有原因的。你真的认为保存几个字节(可能你可能没有做,因为数据库确实优化存储)在查询速度方面真的值得折衷吗?

查询数据库比检索所有结果要快得多,然后使用Python来限制这些结果。

数据库比这更聪明。假设你有20条记录。其中5个hasDelivery是真的。如果您运行SELECT * from restaurants WHERE hasDelivery。然后(使用适当的索引)它将不会从磁盘读取所有20条记录。它将读取5条记录并将其返回。显然,我只是在进行推广和手工操作。但请阅读您决定使用的数据库实现。

结论:在Python中进行处理意味着EACH查询必须将整个数据集读入内存。这是一项昂贵的操作。对布尔值设置为true / false的记录进行数据库查询只会读取磁盘上的那些记录。

答案 1 :(得分:0)

首先,字符串不太可能需要较小的存储空间。在直接支持布尔类型的DBMS上,它实际上可能更大 1

其次,更重要的是,如果您必须单独搜索,读取或写入任何标志,将它们一起存储在同一字段中将违反atomicity原则,因此违反1NF原则。这会阻止您索引单个标志,并且通常会使操作数据的方式变得复杂。

  

有更好的存储0/1值的方法还是选项1最好?

如果你的DBMS支持布尔数据类型,那就去吧。

如果没有,你可能仍然最好只为每个标志使用CHAR(1)之类的东西。但是,如果您的存储要求非常严格,并且您确信不会违反1NF,则可以在同一整数字段内将多个标记打包在一起(使用按位操作)。


1 例如,MS SQL Server可以将多个BIT字段打包到同一个存储字节中。相反,字符串中的1个字符将至少 1个字节(取决于字符编码,可能需要更多)。即使在没有“本机”支持布尔数据类型(例如Oracle)的DBMS上,每个“模拟”布尔字段也可能只花费一个字节,这仍然不会更糟。