【问题标题】:Store boolean value in SQLite在 SQLite 中存储布尔值
【发布时间】:2010-10-25 00:48:06
【问题描述】:

SQLite 中 BOOL 值的类型是什么?我想在我的表中存储 TRUE/FALSE 值。

我可以创建一个 INTEGER 列并在其中存储值 0 或 1,但这不是实现 BOOL 类型的最佳方式。

有办法吗?

【问题讨论】:

标签: sqlite


【解决方案1】:

SQLite 没有本机布尔数据类型。根据Datatypes doc:

SQLite 没有单独的布尔存储类。相反,布尔值存储为整数 0(假)和 1(真)。

【讨论】:

  • "INTEGER。该值是一个有符号整数,根据值的大小存储在 1、2、3、4、6 或 8 个字节中。"我想使用 1 个字节来存储 BOOL 还不错。
  • 在性能方面哪个更好! true/false 作为字符串还是 0/1 整数?
  • @MuhammadBabar 0/1 绝对是。字符串速度较慢并占用更多空间。
  • @joce 实际上,整数 0 和 1(以及 NULL)直接编码在行数据类型声明中。因此,如果您只计算实际的数据存储,那么每个布尔值为零字节,这太棒了。但是,如果您计算文件格式所需的每列每行簿记,则 all 数据类型需要额外的字节,这并不好。 :)(参考:sqlite.org/fileformat.html#record_format)
  • @Davor char(1) 呢,还是比 int 差吗?
【解决方案2】:

SQLite Boolean Datatype:
SQLite 没有单独的布尔存储类。相反,布尔值存储为整数 0(假)和 1(真)。

您可以通过这种方式将 boolean 转换为 int:

int flag = (boolValue)? 1 : 0;

您可以按如下方式将 int 转换回 boolean:

 // Select COLUMN_NAME  values from db. 
 // This will be integer value, you can convert this int value back to Boolean as follows
Boolean flag2 = (intValue == 1)? true : false;

如果你想探索 sqlite,here is a tutorial。
我已经给出了一个答案here。它对他们有用。

【讨论】:

  • 最后一行代码可能只是“Boolean flag2 = (intValue == 1)”
  • 我建议Boolean flag2 = (intValue != 0);
  • 或者你可以做 Boolean flag2 = (intValue > 0);
【解决方案3】:

使用值为 0 和 1 的整数数据类型是最快的。

【讨论】:

    【解决方案4】:

    另一种方法是使用 TEXT 列。然后在保存/从数据库中读取值之前/之后在布尔值和字符串之间转换布尔值。

    例如。你有"boolValue = true;"

    到字符串:

    //convert to the string "TRUE"
    string StringValue = boolValue.ToString;  
    

    然后返回布尔值:

    //convert the string back to boolean
    bool Boolvalue = Convert.ToBoolean(StringValue);
    

    【讨论】:

    • @Craig McMahon 建议改用整数:素数表示真,非素数表示假
    • 我觉得这很冒犯,@Berik。显而易见的解决方案是将单词“TRUE”或“FALSE”渲染到图像上,然后将其作为 JPEG 编码的 BLOB 保存在数据库行中。然后可以使用一种简单的特征提取算法读回该值。
    【解决方案5】:

    在 SQLite 中,你能做的最好的事情就是使用整数 0 和 1 来表示 false 和 true。您可以像这样声明列类型:

    CREATE TABLE foo(mycolumn BOOLEAN NOT NULL CHECK (mycolumn IN (0, 1)));
    

    如果您想在 0 和 1 之外允许 NULL,请省略 NOT NULL。

    这里使用类型名称BOOLEAN 是为了便于阅读,对于SQLite 它只是一个类型with NUMERIC affinity。

    请注意,CHECK constraints 自 SQLite 3.3.0 (2006) 以来一直受支持。

    以下是一些可以使用的示例 INSERT:(注意字符串和浮点数如何被解析为整数)

    sqlite> INSERT INTO foo VALUES(0);
    sqlite> INSERT INTO foo VALUES(1);
    sqlite> INSERT INTO foo VALUES(0.0);
    sqlite> INSERT INTO foo VALUES(1.0);
    sqlite> INSERT INTO foo VALUES("0.0");
    sqlite> INSERT INTO foo VALUES("1.0");
    sqlite> select mycolumn, typeof(mycolumn) from foo;
    0|integer
    1|integer
    0|integer
    1|integer
    0|integer
    1|integer
    

    还有一些会失败的:

    sqlite> INSERT INTO foo VALUES("-1");
    Error: constraint failed
    sqlite> INSERT INTO foo VALUES(0.24);
    Error: constraint failed
    sqlite> INSERT INTO foo VALUES(100);
    Error: constraint failed
    sqlite> INSERT INTO foo VALUES(NULL);
    Error: foo.mycolumn may not be NULL
    sqlite> INSERT INTO foo VALUES("true");
    Error: constraint failed
    sqlite> INSERT INTO foo VALUES("false");
    Error: constraint failed
    

    【讨论】:

    • 注意 - 如果您设置了 DEFAULT,则必须在某些机器上将其设置为 DEFAULT 0 或 DEFAULT 1 而不是 FALSE/TRUE。显然某些版本的 Linux 不喜欢这样,尽管它在 Groovy 上运行良好。
    • 一个小补充。在ver.3.28.0中,不带引号的真/假插入将被成功执行:INSERT INTO foo VALUES(true);插入 foo 值(假);也可以在 CHECK 和 DEFAULT 中使用不带引号的真/假
    【解决方案6】:

    您可以使用以下公式简化上述方程:

    boolean flag = sqlInt != 0;
    

    如果boolean的int表示(sqlInt)为0(false),则boolean(flag)为false,否则为true。

    简洁的代码总是更好用:)

    【讨论】:

      【解决方案7】:

      进一步了解 ericwa 的回答。 CHECK 约束可以通过强制 TEXT 数据类型启用伪布尔列,并且只允许 TRUE 或 FALSE 大小写特定值,例如

      CREATE TABLE IF NOT EXISTS "boolean_test"
      (
          "id" INTEGER PRIMARY KEY AUTOINCREMENT
      ,   "boolean" TEXT NOT NULL 
              CHECK( typeof("boolean") = "text" AND
                     "boolean" IN ("TRUE","FALSE")
              )
      );
      
      INSERT INTO "boolean_test" ("boolean") VALUES ("TRUE");
      INSERT INTO "boolean_test" ("boolean") VALUES ("FALSE");
      INSERT INTO "boolean_test" ("boolean") VALUES ("TEST");
      
      Error: CHECK constraint failed: boolean_test
      
      INSERT INTO "boolean_test" ("boolean") VALUES ("true");
      
      Error: CHECK constraint failed: boolean_test
      
      INSERT INTO "boolean_test" ("boolean") VALUES ("false");
      
      Error: CHECK constraint failed: boolean_test
      
      INSERT INTO "boolean_test" ("boolean") VALUES (1);
      
      Error: CHECK constraint failed: boolean_test
      
      select * from boolean_test;
      
      id  boolean
      1   TRUE
      2   FALSE
      

      【讨论】:

        【解决方案8】:

        但是,如果您想存储一堆它们,您可以对它们进行位移并将它们全部存储为一个 int,有点像 unix 文件权限/模式。

        以模式 755 为例,每个数字代表不同的用户类别:所有者、组、公共。在每个数字中,读取 4,写入 2,执行 1,因此 7 都是二进制 111。读取并执行 5,因此 101。制定自己的编码方案。

        我只是在写一些东西来存储来自 Schedules Direct 的电视节目表数据,我有二进制或是/否字段:立体声、hdtv、新、ei、隐藏字幕、杜比、西班牙语中的 sap、季节首映。所以 7 位,或者一个最大为 127 的整数。真的是一个字符。

        我现在正在研究的一个 C 示例。 has() 是一个函数,如果第二个字符串在第一个字符串中,则返回 1。 inp 是此函数的输入字符串。 misc 是一个初始化为 0 的无符号字符。

        if (has(inp,"sap='Spanish'") > 0)
          misc += 1;
        if (has(inp,"stereo='true'") > 0)
          misc +=2;
        if (has(inp,"ei='true'") > 0)
          misc +=4;
        if (has(inp,"closeCaptioned='true'") > 0)
          misc += 8;
        if (has(inp,"dolby=") > 0)
          misc += 16;
        if (has(inp,"new='true'") > 0)
          misc += 32;
        if (has(inp,"premier_finale='") > 0)
          misc += 64;
        if (has(inp,"hdtv='true'") > 0)
          misc += 128;
        

        所以我将 7 个布尔值存储在一个整数中,还有更多空间。

        【讨论】:

        • 从 CS 的角度来看,这个答案非常暖心。 :)
        【解决方案9】:

        带有 SQLAlchemy 的 Flask 具有布尔值。

        https://overiq.com/flask-101/database-modelling-in-flask/

        【讨论】:

          猜你喜欢
          • 2021-12-04
          • 2019-02-10
          • 1970-01-01
          • 1970-01-01
          • 2012-03-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-11-11
          相关资源
          最近更新 更多