Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 布尔标志字段的模式设计(数据库体系结构) 背景_Python_Sql_Database Design_Django Models_Database Schema - Fatal编程技术网

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

Python 布尔标志字段的模式设计(数据库体系结构) 背景,python,sql,database-design,django-models,database-schema,Python,Sql,Database Design,Django Models,Database Schema,该体系结构是为附近餐馆开发的个人应用程序。我正在尝试两种存储单值布尔(真/假)标志值的方法 我在机器人方面的背景迫使我考虑更小的数据库占用空间。我可能大错特错了 项目 此应用程序将包含餐厅名称和某些单一标志字段。这些固定属性短期内不会更改: 选项1:同一个表中的单个标志或与餐厅ID连接的特定1:1属性表。 休息ID | hasOutdoor | hasDelivery | hasWifi Rest1 | 1 | 1 | 1 Rest2 | 0 | 1 | 0 从编程角度来说,选项1很容易;为每

该体系结构是为附近餐馆开发的个人应用程序。我正在尝试两种存储单值布尔(真/假)标志值的方法

我在机器人方面的背景迫使我考虑更小的数据库占用空间。我可能大错特错了

项目 此应用程序将包含餐厅名称和某些单一标志字段。这些固定属性短期内不会更改:

选项1:同一个表中的单个标志或与餐厅ID连接的特定1:1属性表。
休息ID | hasOutdoor | hasDelivery | hasWifi
Rest1 | 1 | 1 | 1
Rest2 | 0 | 1 | 0
从编程角度来说,选项1很容易;为每家餐厅提取个人财产

选项2:一个包含所有属性的字符串字段。
Rest ID|属性
Rest1 |“111”
Rest2 |“010”
这将占用很小的数据库空间,但在编程上很难处理

python中的示例:

PropertySet=['hasOutdoor','hasDelivery','hasWifi']
对于Rest1.属性中的每个CHAR:
如果int(每个字符):
PropertySet.pop()
输出:

'hasOutDoors'
'hasDelivery'

方案2的主要缺点:
  • 代码和数据库对象是混合的。如果在DB中添加了新属性,并且需要在代码中进行相同的更改,那么这可能会杀死系统

  • 难以编码(且处理繁重)“获取所有具有属性的剩余内容”


  • 是否有更好的方法存储0/1值,或者选项1是最好的?

    使用布尔字段。它们的存在是有原因的。您真的认为节省几个字节(可以说您可能不会这样做,因为数据库确实优化了存储)真的值得在查询速度方面进行权衡吗

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

    数据库要比这聪明得多。假设你有20张唱片。其中5例
    hasDelivery
    为真。如果您在有送货服务的餐厅运行
    选择*
    。然后(通过适当的索引),它不会从磁盘读取所有20条记录。它将读取5条记录并返回它们。很明显,我只是一种概括和手工操作。但是请仔细阅读您决定使用的数据库实现


    一句话:用Python进行处理意味着每个查询都必须将整个数据集读入内存。这是一个昂贵的手术。对于布尔值设置为true/false的记录的DB查询将仅从磁盘读取这些记录

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

    第二,也是更重要的一点,如果您必须单独搜索、读取或写入任何标志,将它们存储在同一字段中将违反1NF的原则。这将阻止您对单个标志进行索引,并且通常会使您操作数据的方式复杂化

    是否有更好的方法存储0/1值,或者选项1是最好的

    如果您的DBMS支持布尔数据类型,请使用它

    如果不是这样,您最好还是对每个单独的标志使用类似CHAR(1)的内容。但是,如果您的存储要求非常严格,并且您确信这样做不会违反1NF,那么您可以将多个标志打包到同一整数字段中(使用位操作)



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

    如果我不得不维护一段代码,上面说“这个长度20 varchar代表我们模型的所有布尔选项”,我可以想象一路笑到精神病院的情景. 嗯,事实上。我只是重写它并将所有数据迁移到一个合理的模式。但我知道了。因为我在这个小项目中使用SQLite。我将使用整数(1,0)来存储它,因为它目前不支持布尔值。因此,对底层数据库实现进行了抽象。只需使用
    models.BooleanField
    。在某个时刻,您可能会切换db引擎。感谢Branko,在经历了1NF关系之后,我已经到了一个点,我必须定义某些属性是否永远是布尔的,或者是否可能有第三个。例如,hasDelivery实际上可能是(hasDelivery、NoDelivery和TakeAway)。