В чем разница между связанными типами данных SQLite, такими как INT, INTEGER, SMALLINT и TINYINT?
Когда я создаю таблицу в SQLite3, я запутываюсь, когда сталкиваюсь со всеми возможными типами данных, которые подразумевают схожее содержимое, поэтому кто-нибудь может сказать мне разницу между следующими типами данных?
INT, INTEGER, SMALLINT, TINYINT
DEC, DECIMAL
LONGCHAR, LONGVARCHAR
DATETIME, SMALLDATETIME
Есть ли где-нибудь документация, где перечислены мин./ Макс. емкости различных типов данных? Например, я думаю, smallint
имеет большее максимальное значение, чем tinyint
, но меньшее значение, чем целое число, но я понятия не имею, что это за возможности.
5 ответов
SQLite
технически не имеет типов данных, есть классы хранения в системе манифестирования манифестов, и да, это сбивает с толку, если вы привыкли к традиционным RDBMS
эс. Все внутри хранится в виде текста. Типы данных принудительно / преобразуются в различные места хранения на основе сходства (аля типы данных, назначенные столбцам).
Лучшее, что я бы порекомендовал вам сделать, это:
Временно забыть все, что вы знали о типах автономных баз данных
Прочитайте приведенную выше ссылку с
SQLite
сайт.Возьмите типы, основанные на вашей старой схеме, и посмотрите, на что они будут отображаться в
SQLite
Перенесите все данные в
SQLite
база данных.
Примечание. Ограничения типа данных могут быть обременительными, особенно если вы добавляете продолжительность времени или даты, или вещи такого рода в SQL
, SQLite
имеет очень мало встроенных функций для такого рода вещей. Тем не мение, SQLite
предоставляет вам простой способ создания собственных встроенных функций для добавления временных интервалов и тому подобного через sqlite3_create_function
библиотечная функция. Вы бы использовали это средство вместо традиционных хранимых процедур.
Разница в синтаксическом сахаре. Только несколько подстрок имен типов имеют значение для соответствия типов.
- Сходство INT, INTEGER, SMALLINT, TINYINT → INTEGER, потому что все они содержат "INT".
- LONGCHAR, LONGVARCHAR → TEXT сродство, потому что они содержат "CHAR".
- DEC, DECIMAL, DATETIME, SMALLDATETIME → NUMERIC, потому что они не содержат подстрок, которые имеют значение.
Правила определения соответствия перечислены на сайте SQLite.
Если вы настаиваете на строгой типизации, вы можете реализовать это с CHECK
ограничения:
CREATE TABLE T (
N INTEGER CHECK(TYPEOF(N) = 'integer'),
Str TEXT CHECK(TYPEOF(Str) = 'text'),
Dt DATETIME CHECK(JULIANDAY(Dt) IS NOT NULL)
);
Но я никогда не беспокоюсь об этом.
Что касается вместимости каждого типа:
INTEGER
всегда подписан 64-битным. Обратите внимание, что SQLite оптимизирует хранение небольших целых чисел за кулисами, поэтому TINYINT в любом случае не будет полезен.REAL
всегда 64-битный (double
).TEXT
а такжеBLOB
иметь максимальный размер, определяемый макросом препроцессора, который по умолчанию равен 1 000 000 000 байтов.
Большинство из них есть для совместимости. У вас действительно есть только целое число, число с плавающей запятой, текст и блоб. Даты могут быть сохранены в виде числа (время unix - целое число, время microsoft - число с плавающей запятой) или в виде текста.
NULL
, Значение является значением NULL.
INTEGER
, Значение представляет собой целое число со знаком, сохраняемое в 1, 2, 3, 4, 6 или 8 байтах в зависимости от величины значения.
REAL
, Значение является значением с плавающей запятой, хранящимся как 8-байтовое число с плавающей запятой IEEE.
TEXT
, Значение представляет собой текстовую строку, сохраненную с использованием кодировки базы данных (UTF-8, UTF-16BE или UTF-16LE).
BLOB
, Значение представляет собой блок данных, хранящийся в точности так, как он был введен.
В качестве дополнения к ответу от dan04, если вы хотите вслепую вставить NUMERIC
кроме нуля, представленного TEXT
но убедитесь, что текст может быть преобразован в число:
your_numeric_col NUMERIC CHECK(abs(your_numeric_col) <> 0)
Типичный вариант использования в запросе от программы, которая обрабатывает все данные как текст (для единообразия и простоты, поскольку SQLite уже делает это). Хорошая вещь об этом - то, что это позволяет конструкции как это:
INSERT INTO table (..., your_numeric_column, ...) VALUES (..., some_string, ...)
что удобно, если вы используете заполнители, потому что вам не нужно специально обрабатывать такие ненулевые числовые поля. Пример использования Python sqlite3
модуль будет,
conn_or_cursor.execute(
"INSERT INTO table VALUES (" + ",".join("?" * num_values) + ")",
str_value_tuple) # no need to convert some from str to int/float
В приведенном выше примере все значения в str_value_tuple
будет экранирован и указан в виде строки при передаче в SQlite. Однако, поскольку мы не проверяем явно тип через TYPEOF
но только с возможностью преобразования в тип, он все равно будет работать по желанию (т. е. SQLite либо сохранит его как числовое, либо не выполнит иначе).