背景
该架构适用于附近餐厅的个人应用程序。我正在考虑两种存储单值布尔(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的主要缺点:
代码和数据库对象是混合的。如果在数据库中添加一个新属性,并且需要在代码中进行相同的更改,这可能会导致系统崩溃。
很难编码(并且处理量很大)"获取所有具有Outdoor属性的Rest"!
是否有更好的存储0/1值的方法,或者选项1是最好的
使用布尔字段。它们的存在是有原因的。你真的认为节省几个字节(可以说你可能没有这样做,因为数据库确实优化了存储)在查询速度方面真的值得权衡吗?
查询数据库比检索所有结果并使用Python限制这些结果要快得多。
数据库比这聪明得多。假设你有20张唱片。其中CCD_ 1为真。如果运行SELECT * from restaurants WHERE hasDelivery
。然后(通过适当的索引)它不会从磁盘中读取所有20条记录。它将读取5条记录并返回它们。很明显,我只是有点泛泛和手工。但是请仔细阅读您决定使用的数据库实现。
一句话:用Python进行处理意味着EACH查询必须将整个数据集读取到内存中。这是一项昂贵的手术。对于布尔值设置为true/false的记录的DB查询将只从磁盘上读取这些记录。
首先,字符串不太可能需要更小的存储空间。在直接支持布尔类型的DBMS上,它实际上可能更大1。
第二,也是更重要的一点,如果你必须单独搜索、读取或写入任何标志,那么将它们存储在同一个字段中将违反原子性原则,从而违反1NF。这将阻止您对单个标志进行索引,并且通常会使处理数据的方式复杂化。
是否有更好的存储0/1值的方法,或者选项1是最好的?
如果您的DBMS支持布尔数据类型,请选择它。
如果没有,您可能仍然最好对每个单独的标志使用CHAR(1)之类的东西。但是,如果您的存储要求非常严格,并且您确信这样做不会违反1NF,则可以在同一整数字段中将多个标志打包在一起(使用逐位操作)。
1例如,MS SQL Server可以将多个BIT字段打包到同一字节的存储中。相反,字符串中的1个字符至少需要1个字节(根据字符编码,可能需要更多)。即使在"本机"不支持布尔数据类型的DBMS(如Oracle)上,每个"模拟"布尔字段也可能只花费一个字节,这仍然不会更糟