在SQLite中存储布尔值


Answers:


365

SQLite没有本地布尔数据类型。根据数据类型doc

SQLite没有单独的布尔存储类。而是将布尔值存储为整数0(假)和1(真)。


24
“ INTEGER。该值是一个有符号整数,根据值的大小存储在1、2、3、4、6或8个字节中。” 我想用1个字节来存储BOOL并不太坏。
09年

2
直接从马口中得出:“ SQLite没有单独的布尔存储类。相反,布尔值存储为整数0(假)和1(真)。”
Tobias

3
在性能方面哪个更好!是/否是字符串还是0/1整数?
穆罕默德·巴巴尔

9
@MuhammadBabar绝对是0/1。字符串速度较慢,占用更多空间。
Davor

1
@joce实际上,整数0和1(以及NULL)直接在行数据类型声明中编码。因此,如果仅计算实际数据存储量,则每个布尔值为零字节,这真是太棒了。但是,如果算上文件格式所需的每列每行记帐,则所有数据类型都需要一个额外的字节,这并不好。:)(参考:sqlite.org/fileformat.html#record_format
相对

93

在SQLite中,最好的办法是使用整数0和1表示false和true。您可以这样声明列类型:

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

NOT NULL如果要允许NULL除0和1之外的其他值,请省略。

BOOLEAN这里使用类型名称是为了提高可读性,对于SQLite来说,它只是具有NUMERIC相似性的类型。

请注意,自SQLite 3.3.0(2006)起已支持CHECK约束

以下是一些可以使用的示例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

86

SQLite 布尔数据类型:
SQLite没有单独的布尔存储类。取而代之的是,布尔值存储为整数0(假)和1(真)。

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

int flag = (boolValue)? 1 : 0;

您可以将int转换回布尔值,如下所示:

 // 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,请参阅以下教程
在这里给了一个答案。它为他们工作。


13
代码的最后一行可能只是“ Boolean flag2 =(intValue == 1)”
2014年

16
我建议Boolean flag2 = (intValue != 0);
Hamzeh Soboh,2015年

或者您可以只执行Boolean flag2 =(intValue> 0);
Efrain Sanjay Adhikary,2013年


5

进一步回答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

5

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

例如,对于模式755,每个数字表示不同类别的用户:所有者,组,公共。在每个数字中读取4个数据,写入2个数据,执行1个数据,以便它们7都像二进制111。读取和执行5个数据,所以101。构成您自己的编码方案。

我正在写一些东西来存储Schedules Direct中的电视时间表数据,并且我具有二进制或是/否字段:立体声,hdtv,new,ei,隐藏字幕,杜比,汁液在西班牙语中,本季首播。所以是7位,或者是最大为127的整数。实际上是一个字符。

我现在正在研究的交流示例。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的角度来看,这个答案是如此令人兴奋。:)
varun

2

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

boolean flag = sqlInt != 0;

如果布尔值的int表示形式(sqlInt)为0(false),则布尔值(flag)将为false,否则为true。

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


-4

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

例如 你有"boolValue = true;

要字符串:

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

回到布尔值:

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

5
@Craig McMahon建议改用Integer:素数代表真,非素数代表假
Berik 2014年

16
我发现这很令人反感,@ Berik。显而易见的解决方案是将单词“ TRUE”或“ FALSE”呈现到图像上,然后将其另存为JPEG编码的BLOB。然后可以使用一种简单的特征提取算法将值读回。
Craig McMahon 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.