В чем разница между связанными типами данных SQLite, такими как INT, INTEGER, SMALLINT и TINYINT?

Когда я создаю таблицу в SQLite3, я запутываюсь, когда сталкиваюсь со всеми возможными типами данных, которые подразумевают схожее содержимое, поэтому кто-нибудь может сказать мне разницу между следующими типами данных?

INT, INTEGER, SMALLINT, TINYINT

DEC, DECIMAL

LONGCHAR, LONGVARCHAR

DATETIME, SMALLDATETIME

Есть ли где-нибудь документация, где перечислены мин./ Макс. емкости различных типов данных? Например, я думаю, smallint имеет большее максимальное значение, чем tinyint, но меньшее значение, чем целое число, но я понятия не имею, что это за возможности.

5 ответов

Решение

SQLite технически не имеет типов данных, есть классы хранения в системе манифестирования манифестов, и да, это сбивает с толку, если вы привыкли к традиционным RDBMS эс. Все внутри хранится в виде текста. Типы данных принудительно / преобразуются в различные места хранения на основе сходства (аля типы данных, назначенные столбцам).

Лучшее, что я бы порекомендовал вам сделать, это:

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

  2. Прочитайте приведенную выше ссылку с SQLite сайт.

  3. Возьмите типы, основанные на вашей старой схеме, и посмотрите, на что они будут отображаться в SQLite

  4. Перенесите все данные в 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 либо сохранит его как числовое, либо не выполнит иначе).

Другие вопросы по тегам