SQLite: PRIMARY KEY по умолчанию используется для ASC? - PullRequest
2 голосов
/ 03 июля 2019

Т.е. следующие два оператора SQL эквивалентны в SQLite?

CREATE TABLE posts (
  id INTEGER PRIMARY KEY
);

CREATE TABLE posts (
  id INTEGER PRIMARY KEY ASC
);

Ответы [ 2 ]

3 голосов
/ 04 июля 2019

Да они есть.

Нет необходимости указывать ASC и , остерегайтесь , что если вы зададите DESC , тогда NO они тогда не будут эквивалент (см. 4 ниже), поскольку id INTEGER PRIMARY KEY DESC является исключением из столбца, являющегося псевдонимом столбца rowid согласно: -

Исключением, упомянутым выше, является то, что если объявление столбца с объявленным типом «INTEGER» включает в себя предложение «PRIMARY KEY DESC», оно не становится псевдонимом для rowid и не классифицируется как целочисленный первичный ключ. Эта причуда не по замыслу. Это связано с ошибкой в ранних версиях SQLite. Но исправление ошибки может привести к обратная несовместимость. Следовательно, оригинальное поведение было сохранено (и задокументировано), потому что странное поведение в угловом случае далеко лучше, чем разрыв совместимости.

ROWID и INTEGER ПЕРВИЧНЫЙ КЛЮЧ

Вы можете использовать id INTEGER, PRIMARY KEY(id, DESC), но по-прежнему порядок по умолчанию равен ASC при извлечении столбца, поскольку он является псевдонимом rowid (см. 5 ниже)

Возможно, рассмотрим следующее: -

DROP TABLE IF EXISTS posts1;
CREATE TABLE posts1 (
  id INTEGER PRIMARY KEY
);

DROP TABLE IF EXISTS posts2;
CREATE TABLE posts2 (
  id INTEGER PRIMARY KEY ASC
);

DROP TABLE IF EXISTS posts3;
CREATE TABLE posts3 (
  id INTEGER PRIMARY KEY DESC
);

DROP TABLE IF EXISTS posts4;
CREATE TABLE posts4 (
    id INTEGER, PRIMARY KEY (id DESC)
);

INSERT INTO posts1 VALUES(null),(null),(null);
INSERT INTO posts2 VALUES(null),(null),(null);
INSERT INTO posts3 VALUES(null),(null),(null);
INSERT INTO posts4 VALUES(null),(null),(null);

SELECT * FROM sqlite_master WHERE name LIKE '%posts%';

SELECT * FROM posts1;
SELECT * FROM posts2;
SELECT * FROM posts3;
SELECT * FROM posts4;

Результаты

1

Запрос SELECT * FROM sqlite_master WHERE name LIKE '%posts%'; приводит к: -

enter image description here

Как видите, posts3 значительно отличается, так как индекс sqlite_autoindex_posts3_1 создан

Остальные не имеют определенного индекса, созданного, поскольку столбец id является псевдонимом rowid столбца

Данные для таблиц rowid хранятся в виде структуры B-Tree, содержащей одна запись для каждой строки таблицы, используя значение rowid в качестве ключа. это означает, что получение или сортировка записей по rowid выполняется быстро. поиск для записи с определенным rowid или для всех записей с rowid в указанном диапазоне примерно в два раза быстрее, чем аналогичный поиск сделано, указав любой другой ПЕРВИЧНЫЙ КЛЮЧ или индексированное значение.

ROWID и INTEGER ПЕРВИЧНЫЙ КЛЮЧ

2

Запрос SELECT * FROM posts1; приводит к: -

enter image description here

3

Запрос SELECT * FROM posts2; подтверждает первоначальный ДА ответ согласно: -

enter image description here

4

Запрос SELECT * FROM posts3;, может быть немного запутанным, но показывает, что id INTEGER PRIMARY KEY DESC не приводит к псевдониму rowid и в случае, если в столбец не вставляется значение или ноль , значение является нулевым, а не автоматически сгенерированным значением. Не существует УНИКАЛЬНОГО конфликта ограничений (поскольку нулевые значения рассматриваются как различные значения).

enter image description here

5

Запрос SELECT * FROM posts4; дает тот же результат, что и для 1 и 2, даже если был использован id INTEGER, PRIMARY KEY (id DESC). Подтверждение того, что даже если DESC применяется через определение столбца, что порядок сортировки по-прежнему равен ASC (если не используется предложение ORDER BY).

  • Обратите внимание, что эта особенность относится только к столбцу rowid или его псевдониму.

enter image description here

1 голос
/ 04 июля 2019

См. И https://www.sqlite.org/lang_createtable.html#rowid и https://www.sqlite.org/lang_createindex.html для более полного ответа. Ссылка Шона относится только к INTEGER PRIMARY KEY, что соответствует коду примера, но на более общий вопрос явно не дан ответ ни в одном месте, но его можно вывести, прочитав оба.

В ограничениях данных SQL первая ссылка говорит

В большинстве случаев ограничения UNIQUE и PRIMARY KEY реализуются путем создания уникального индекса в базе данных. (Исключения составляют INTEGER PRIMARY KEY и PRIMARY KEYS для таблиц ROWID БЕЗ.)

Страница CREATE INDEX объясняет, что первоначально порядок сортировки был проигнорирован, и все индексы были сгенерированы в порядке возрастания. * Начиная с версии 3.3.0 DESC порядок "понят". Но даже это описание несколько расплывчато, однако в целом очевидно, что ASC является значением по умолчанию .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...