Lưu trữ giá trị boolean trong SQLite


284

Loại cho giá trị BOOL trong SQLite là gì? Tôi muốn lưu trữ trong bảng của mình các giá trị TRUE / FALSE.

Tôi có thể tạo một cột INTEGER và lưu trữ trong đó các giá trị 0 hoặc 1, nhưng đó sẽ không phải là cách tốt nhất để triển khai loại BOOL.

Là có một cách?

Cảm ơn.


Câu trả lời:


365

Không có kiểu dữ liệu boolean riêng cho SQLite. Theo tài liệu kiểu dữ liệu :

SQLite không có lớp lưu trữ Boolean riêng. Thay vào đó, các giá trị Boolean được lưu dưới dạng số nguyên 0 (sai) và 1 (đúng).


24
"INTEGER. Giá trị là một số nguyên đã ký, được lưu trữ trong 1, 2, 3, 4, 6 hoặc 8 byte tùy thuộc vào độ lớn của giá trị." Tôi đoán sử dụng 1 byte để lưu trữ BOOL không quá tệ.
joce

2
Trực tiếp từ miệng ngựa: "SQLite không có lớp lưu trữ Boolean riêng. Thay vào đó, các giá trị Boolean được lưu trữ dưới dạng số nguyên 0 (sai) và 1 (đúng)."
Tobias

3
Đó là tốt hơn về mặt hiệu suất! đúng / sai dưới dạng chuỗi hay số nguyên 0/1?
Muhammad Babar

9
@MuhammadBabar 0/1 chắc chắn nhất. Chuỗi chậm hơn và chiếm nhiều không gian hơn.
Thưởng thức

1
@joce Trên thực tế, số nguyên 0 và 1 (cũng như NULL) được mã hóa trực tiếp trong khai báo kiểu dữ liệu hàng. Vì vậy, nó là 0 byte cho mỗi boolean, nếu bạn chỉ tính lưu trữ dữ liệu thực tế, điều này thật tuyệt vời. Tuy nhiên, nếu bạn tính sổ sách theo từng cột trên mỗi hàng theo yêu cầu của định dạng tệp, tất cả các loại dữ liệu đều có thêm một byte cần thiết, điều này không tuyệt vời. :) (tham khảo: sqlite.org/fileformat.html#record_format )
tương

93

Trong SQLite, cách tốt nhất bạn có thể làm là sử dụng các số nguyên 0 và 1 để thể hiện sai và đúng. Bạn có thể khai báo kiểu cột như thế này:

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

Bỏ qua NOT NULLnếu bạn muốn cho phép NULLngoài 0 và 1.

Việc sử dụng tên loại BOOLEANở đây là để dễ đọc, đối với SQLite, đây chỉ là một loại có ái lực với SỐ .

Lưu ý rằng các ràng buộc CHECK đã được hỗ trợ kể từ SQLite 3.3.0 (2006).

Dưới đây là một số ví dụ INSERT sẽ hoạt động: (lưu ý cách chuỗi và số dấu phẩy động được phân tích cú pháp dưới dạng số nguyên)

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

và một số sẽ thất bại:

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 Boolean Datatype:
SQLite không có lớp lưu trữ Boolean riêng. Thay vào đó, các giá trị Boolean được lưu dưới dạng số nguyên 0 (sai) và 1 (đúng).

Bạn có thể chuyển đổi boolean sang int theo cách này:

int flag = (boolValue)? 1 : 0;

Bạn có thể chuyển đổi int trở lại boolean như sau:

 // 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;

Nếu bạn muốn khám phá sqlite, đây là một hướng dẫn .
Tôi đã đưa ra một câu trả lời ở đây . Nó đang làm việc cho họ.


13
dòng mã cuối cùng chỉ có thể là "Boolean flag2 = (intValue == 1)"
cja

16
Tôi đề nghịBoolean flag2 = (intValue != 0);
Hamzeh Soboh

hoặc bạn chỉ có thể làm cờ Boolean2 = (intValue> 0);
Efrain Sanjay Adhikary


5

Hơn nữa với câu trả lời của ericwa. Các ràng buộc KIỂM TRA có thể cho phép một cột boolean giả bằng cách thực thi một kiểu dữ liệu văn bản và chỉ cho phép các giá trị cụ thể của trường hợp TRUE hoặc FALSE, vd

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

Nhưng, nếu bạn muốn lưu trữ một loạt chúng, bạn có thể dịch chuyển chúng và lưu trữ tất cả chúng dưới dạng một int, giống như các chế độ / quyền của tập tin unix.

Ví dụ, đối với chế độ 755, mỗi chữ số đề cập đến một lớp người dùng khác nhau: chủ sở hữu, nhóm, công khai. Trong mỗi chữ số 4 được đọc, 2 là ghi, 1 được thực thi nên 7 là tất cả chúng giống như nhị phân 111. 5 được đọc và thực thi vì vậy 101. Tạo nên sơ đồ mã hóa của riêng bạn.

Tôi chỉ đang viết một cái gì đó để lưu trữ dữ liệu lịch truyền hình từ Lịch trực tiếp và tôi có các trường nhị phân hoặc có / không: stereo, hdtv, mới, ei, chú thích gần, dolby, sap trong tiếng Tây Ban Nha, ra mắt mùa. Vì vậy, 7 bit, hoặc một số nguyên có tối đa 127. Một ký tự thực sự.

Ví dụ AC từ những gì tôi đang làm việc bây giờ. has () là hàm trả về 1 nếu chuỗi thứ 2 nằm trong chuỗi thứ nhất. inp là chuỗi đầu vào của hàm này. misc là một char không dấu được khởi tạo thành 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;

Vì vậy, tôi đang lưu trữ 7 booleans trong một số nguyên có nhiều chỗ hơn.


Câu trả lời này thật ấm lòng trong viễn cảnh CS. :)
varun

2

Bạn có thể đơn giản hóa các phương trình trên bằng cách sử dụng như sau:

boolean flag = sqlInt != 0;

Nếu đại diện int (sqlInt) của boolean là 0 (false), boolean (cờ) sẽ sai, nếu không nó sẽ đúng.

Mã súc tích luôn đẹp hơn để làm việc với :)


-4

Một cách khác để làm điều đó là một cột văn bản. Và sau đó chuyển đổi giá trị boolean giữa Boolean và String trước / sau khi lưu / đọc giá trị từ cơ sở dữ liệu.

Ví dụ. Bạn có "boolValue = true;"

Đến chuỗi:

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

Và quay lại boolean:

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

6
@Craig McMahon đề nghị sử dụng Integer thay vào đó: các số nguyên tố đại diện cho đúng, không phải số nguyên tố đại diện cho sai
Berik

18
Tôi thấy điều đó rất khó chịu, @Berik. Giải pháp rõ ràng là hiển thị từ "TRUE" hoặc "FALSE" trên một hình ảnh và sau đó lưu nó trong hàng cơ sở dữ liệu dưới dạng BLOB được mã hóa JPEG. Sau đó, người ta có thể đọc lại giá trị bằng thuật toán trích xuất tính năng đơn giản.
Craig McMahon
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.