Тип (сходство типов) с одним исключением не имеет никакого значения.
Исключением является the_column_name INTEGER PRIMARY KEY
(с или без AUTOINCREMENT), которое определяет столбец как псевдоним столбца rowid .INT PRIMARY KEY этого не делает.
так что the_column_name CHAR_INT PRIMARY KEY
, the_column_name INT CHAR PRIMARY KEY
или даже the_column_name INT PRIMARY KEY
на самом деле одинаковы, the_column_name RUMPLESTILTSKIN PRIMARY KEY
может даже использоваться (хотя последний будет иметь различное сходство типов).
Это правила, которые определяютродство типов.Есть 5. Правило с наивысшим приоритетом: если у типа есть INT, то сродство с типом - INTEGER.RUMPLESTILTSKIN как тип пропускает все правила, кроме последнего, т. Е. Если ни одно из предыдущих правил не применимо, то сходство типов равно NUMERIC.
3.1.Определение сродства столбца
Сходство столбца определяется объявленным типом столбца в соответствии со следующими правилами в указанном порядке:
Если объявленный тип содержитстрока "INT", тогда ей присваивается сходство INTEGER.
Если объявленный тип столбца содержит какие-либо из строк "CHAR", "CLOB" или "TEXT", то этот столбец имеет сходство TEXT.Обратите внимание, что тип VARCHAR содержит строку «CHAR» и, таким образом, ему присваивается сходство TEXT.
Если объявленный тип для столбца содержит строку «BLOB» или если тип не указан, столбец имеет сходство BLOB.
Если объявленный тип для столбца содержит какие-либо из строк «REAL», «FLOA» или «DOUB», тогда столбец имеет РЕАЛЬНОЕ сходство.
В противном случае сходство является ЦИФРОВЫМ.
Обратите внимание, что порядок правил для определения соответствия столбцов важен.Столбец с объявленным типом «CHARINT» будет соответствовать обоим правилам 1 и 2, но первое правило имеет приоритет, и поэтому сходство столбцов будет INTEGER.
Типы данных в SQLite
Сказать, что сходство типов не определяет способ хранения данных.Каждый столбец хранится в соответствии с классом хранения, который зависит от хранимых данных.
Ноль хранится как ноль, строка чисел (заключенная или не в виде строки) как целое число.Короче говоря, данные будут храниться в соответствии с определением SQLite, и SQlite будет пытаться хранить данные настолько эффективно, насколько это возможно, и в как можно меньшем пространстве, вплоть до байта, являющегося наименьшей из сохраняемых единиц.
Рассмотримследующее: -
DROP TABLE IF EXISTS mytable1;
DROP TABLE IF EXISTS mytable2;
DROP TABLE IF EXISTS mytable3;
CREATE TABLE IF NOT EXISTS mytable1 (c1 CHAR_INT PRIMARY KEY);
CREATE TABLE IF NOT EXISTS mytable2 (c1 INT PRIMARY KEY);
CREATE TABLE IF NOT EXISTS mytable3 (c1 RUMPLEstiltSkin PRIMARY KEY);
-- INSERT INTO mytable1 VALUES(12345),('12345'),('a_12345'),('1_12345'),(x'0102030405'); -- fails due to unique constraint 12345 and '12345' are the same
-- INSERT INTO mytable2 VALUES(12345),('12345'),('a_12345'),('1_12345'),(x'0102030405'); -- fails due to unique constraint 12345 and '12345' are the same
-- INSERT INTO mytable3 VALUES(12345),('12345'),('a_12345'),('1_12345'),(x'0102030405'); -- fails due to unique constraint 12345 and '12345' are the same
INSERT INTO mytable1 VALUES(12345),('54321'),('a_12345'),('1_12345'),(x'0102030405');
INSERT INTO mytable2 VALUES(12345),('54321'),('a_12345'),('1_12345'),(x'0102030405');
INSERT INTO mytable3 VALUES(12345),('54321'),('a_12345'),('1_12345'),(x'0102030405');
SELECT c1, typeof(c1) FROM mytable1;
SELECT c1, typeof(c1) FROM mytable2;
SELECT c1, typeof(c1) FROM mytable3;
- Закомментированные INSERTS (если они не закомментированы и выполнены) завершаются неудачно с УНИКАЛЬНЫМ конфликтом, поскольку SQLite считает 12345 таким же, как и 12345.
функция typeof возвращает тип столбца (тип хранения НЕ сродство к столбцу)
Результаты выглядят так: -
Использование чего-либо кроме INTEGER PRIMARY KEY (есть некоторые производные) и, таким образом, псевдоним rowid равен
- примерно вдвое быстрее
имеет два индекса: rowid (если таблица не определена как ROWID) и первичный ключ.
Поиск записи с определенным rowid или для всех записей с rowid вуказанный диапазон примерно вдвое быстрее, чем аналогичный поиск, выполняемый путем указания любого другого PRIMARY KEY или индексированного значения. ROWID и INTEGER PRIMARY KEY
обработка чисел в отличие от строк займет больше места и, следовательно, сократит объем данных, которые могутбудет храниться в буфере, таким образом, это окажет некоторое влияние.
Поиск по индексу выполняется относительно быстро, по сравнению с самими данными относительно мало данных и сами данныетолько чтение.
Возможно, рассмотрим следующее: -
DROP TABLE IF EXISTS mytable1;
DROP TABLE IF EXISTS mytable2;
DROP TABLE IF EXISTS mytable3;
CREATE TABLE IF NOT EXISTS mytable1 (pk INT PRIMARY KEY, name TEXT);
CREATE TABLE IF NOT EXISTS mytable2 (pk CHAR_INT PRIMARY KEY, name TEXT);
CREATE TABLE IF NOT EXISTS mytable3 (pk INT PRIMARY KEY, name TEXT) WITHOUT ROWID;
INSERT INTO mytable1
WITH RECURSIVE cte1(a,b) AS (
SELECT 'ABC_'||CAST(abs(random()) AS TEXT),'some data' UNION ALL
SELECT DISTINCT (substr(a,1,4))||CAST(abs(random()) AS TEXT),'some data' FROM cte1 LIMIT 1000000
)
SELECT * FROM cte1
;
INSERT INTO mytable2
WITH RECURSIVE cte1(a,b) AS (
SELECT '1_'||CAST(abs(random()) AS TEXT),'some data' UNION ALL
SELECT DISTINCT (abs(random()) % 100)||'_'||CAST(abs(random()) AS TEXT),'some data' FROM cte1 LIMIT 1000000
)
SELECT * FROM cte1
;
INSERT INTO mytable3 SELECT * FROM mytable1;
SELECT * FROM mytable1 WHERE name LIKE('%me data%');
SELECT * FROM mytable2 WHERE name LIKE('%me data%');
SELECT * FROM mytable3 WHERE name LIKE('%me data%');
SELECT * FROM mytable3 WHERE name LIKE('%me data%');
SELECT * FROM mytable1 WHERE name LIKE('%me data%');
SELECT * FROM mytable2 WHERE name LIKE('%me data%');
SELECT * FROM mytable2 WHERE name LIKE('%me data%');
SELECT * FROM mytable3 WHERE name LIKE('%me data%');
SELECT * FROM mytable1 WHERE name LIKE('%me data%');
Это создает 3 перестановки с 1 000 000 строк
mytable1 имеет первичный ключ как ABC _ ???? например : -
mytable2 имеет первичный ключ как ?? _ ???? например : -
mytable3 является копией mytable1 НО таблица была определена с использованием БЕЗ ROWID
Задержка
ВЫБОРЫ для всех 3 довольно близки (многократные выборки выполнены и в другом порядке для выравнивания кэширования). Сообщения, которые включают время: -
SELECT * FROM mytable1 WHERE name LIKE('%me data%')
> OK
> Time: 0.672s
SELECT * FROM mytable2 WHERE name LIKE('%me data%')
> OK
> Time: 0.667s
SELECT * FROM mytable3 WHERE name LIKE('%me data%')
> OK
> Time: 0.702s
SELECT * FROM mytable3 WHERE name LIKE('%me data%')
> OK
> Time: 0.7s
SELECT * FROM mytable1 WHERE name LIKE('%me data%')
> OK
> Time: 0.675s
SELECT * FROM mytable2 WHERE name LIKE('%me data%')
> OK
> Time: 0.673s
SELECT * FROM mytable2 WHERE name LIKE('%me data%')
> OK
> Time: 0.676s
SELECT * FROM mytable3 WHERE name LIKE('%me data%')
> OK
> Time: 0.709s
SELECT * FROM mytable1 WHERE name LIKE('%me data%')
> OK
> Time: 0.676s
- Я полагаю, что mytable3 выполняет небольшую попытку, потому что сканирование (в данном случае) выполняется на ПЕРВИЧНОМ КЛЮЧЕ, а не на rowid, который подходит / предпочтителен для двух других.
В дополнение к предыдущим ссылкам, вы также можете посмотреть: -