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

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

INT, INTEGER, SMALLINT, TINYINT DEC, DECIMAL LONGCHAR, LONGVARCHAR DATETIME, SMALLDATETIME 

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

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

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

  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 байт.

Большинство из них существуют для совместимости. У вас действительно есть только целое число, float, text и blob. Даты могут быть сохранены как число (время unix – целое число, время Microsoft – float) или как текст.

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, ...) 

что удобно, если вы используете заполнители, потому что вам не нужно обрабатывать такие ненулевые числовые поля. Примером использования модуля sqlite3 Python будет,

 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 а только конвертируемость в тип , он будет по-прежнему работать по желанию (т. TYPEOF SQLite либо сохранит его как числовое, либо не получится иначе).

  • Скорость вставки SQLite замедляется по мере увеличения количества записей из-за индекса
  • Как удалить или добавить столбец в SQLITE?
  • Как восстановить поврежденную базу данных SQLite3?
  • Вставка имени таблицы в запрос дает sqlite3.OperationalError: рядом с «?»: Синтаксическая ошибка
  • Как перечислить таблицы в файле базы данных SQLite, который был открыт с помощью ATTACH?
  • Исключение SQLite: SQLite Занято
  • Как конкатенировать строки с заполнением в sqlite
  • Как использовать модуль sqlite3 с электроном?
  • Измените тип столбца в sqlite3
  • ALTER COLUMN в sqlite
  • Параллельный доступ SQLite
  • Давайте будем гением компьютера.