Хранить логическое значение в SQLite

284

Какой тип значения BOOL в SQLite? Я хочу сохранить в моей таблице значения TRUE / FALSE.

Я мог бы создать столбец INTEGER и сохранить в нем значения 0 или 1, но это не лучший способ для реализации типа BOOL.

Есть ли способ?

Спасибо.

Илья Суздальницкий
источник
2
Возможный дубликат Есть ли логический литерал в SQLite?
Джошуа Пинтер

Ответы:

365

Для SQLite нет собственного логического типа данных. Согласно документу Datatypes :

SQLite не имеет отдельного булева класса хранения. Вместо этого логические значения хранятся как целые числа 0 (ложь) и 1 (истина).

Лассе В. Карлсен
источник
24
«INTEGER. Значением является целое число со знаком, сохраняемое в 1, 2, 3, 4, 6 или 8 байтах в зависимости от величины значения.» Я думаю, использование 1 байта для хранения BOOL не так уж плохо.
Джос
2
Прямо из уст Лошади: «SQLite не имеет отдельного класса логического хранения. Вместо этого логические значения хранятся в виде целых чисел 0 (ложь) и 1 (истина)».
Тобиас
3
Что лучше с точки зрения производительности! истина / ложь как строки или 0/1 целое число?
Мухаммед Бабар
9
@MuhammadBabar 0/1 определенно. Строки медленнее и занимают больше места.
Давор
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-сходством .

Обратите внимание, что ограничения CHECK поддерживаются начиная с 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
ericwa
источник
86

Тип логики
SQLite : SQLite не имеет отдельного класса логического хранения. Вместо этого логические значения хранятся как целые числа 0 (ложь) и 1 (истина).

Вы можете преобразовать логическое значение в 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)"
cja
16
Я предлагаюBoolean flag2 = (intValue != 0);
Hamzeh Soboh
или вы можете просто сделать Boolean flag2 = (intValue> 0);
Эфрайн Санджай Адхикари
7

использование типа данных Integer со значениями 0 и 1 является самым быстрым.

Логвинов Алексей
источник
5

В дополнение к ответу Эриквы. Ограничения 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, с субтитрами, dolby, sap по-испански, премьера сезона. Так что 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. :)
Варун
2

Вы можете упростить приведенные выше уравнения, используя следующее:

boolean flag = sqlInt != 0;

Если представление int (sqlInt) логического значения равно 0 (false), логическое значение (flag) будет false, в противном случае оно будет истинным.

Сжатый код всегда приятнее работать :)

Голодный Андройдер
источник
-4

Еще один способ сделать это - столбец TEXT. А затем преобразуйте логическое значение между Boolean и String до / после сохранения / чтения значения из базы данных.

Ex. У вас есть "boolValue = true;"

Нанизывать:

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

И вернемся к логическому:

//convert the string back to boolean
bool Boolvalue = Convert.ToBoolean(StringValue);
Нильс Шмидт
источник
6
@Craig McMahon предлагает вместо этого использовать целое число: простые числа представляют истину, а не простые числа представляют ложь
Берик
19
Я считаю это очень оскорбительным, @Berik. Очевидное решение состоит в том, чтобы отобразить слово «ИСТИНА» или «ЛОЖЬ» на изображении, а затем сохранить его в строке базы данных как BLOB-код в формате JPEG. Затем можно прочитать значение обратно, используя простой алгоритм извлечения признаков.
Крейг МакМахон