SQLite3 оптимизация хранения

SQL во всех проявлениях - от ANSI-92 до TSQL.

Модераторы: Yurich, Absurd

Ответить
tonchikp
Сообщения: 3
Зарегистрирован: 16 июл 2016, 20:04
Откуда: Россия

27 авг 2017, 15:01

Уважаемые форумчане! Требуется ваша помощь!

Есть таблица-словарь SQLite3, где перечисляется что-то (не важно что, суть не в этом)

Ранее создавал так:

Код: Выделить всё

CREATE TABLE table (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        obj TEXT UNIQUE
);
Задумался, ведь тут по сути 3 поля с UNIQUE (rowid, id, obj), 2 с AUTOINCREMENT (rowid, id). Получается дублируются роли полей, выполняется возможно ненужная работа, нерациональность. Насколько я понимаю PRIMARY KEY в себе несёт UNIQUE и NOT NULL.

Может лучше так:

Код: Выделить всё

CREATE TABLE table (
    obj TEXT PRIMARY KEY
) WITHOUT ROWID;
Подскажите пожалуйста, какие могут быть подводные камни нового подхода? Иными словами, какие минусы?
Аватара пользователя
AiK
Сообщения: 2273
Зарегистрирован: 13 фев 2004, 18:14
Откуда: СПб
Контактная информация:

27 авг 2017, 15:52

Между двумя соседними целыми числами нельзя вставить третье. Поэтому операции вставки для текстов в качестве первичного ключа будут происходить медленнее. Для редких добавлений записей это не критично.

Кроме того, размеры полей типа TEXT и типа INTEGER существенно отличаются. Поэтому если БД не плоская, а реляционная и большого размера, то большинство выборок во втором случае будут происходит более быстро, т.к. больше значений уместится в оперативную память.

А если таблица одна из нескольких сотен записей, то разницы не будет никакой.
Даже самый дурацкий замысел можно воплотить мастерски
Absurd
Сообщения: 1213
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

27 авг 2017, 16:00

Сравнение интов имеет сложность O(1), строк - O(N).

Инты имеют фиксированный размер и поэтому структуры данных для работы с ними намного проще - их можно в упаковать в плоский массив. Строки надо сваливать в пул и в дальнейшем работать с указателями на объекты в этом пуле. Это медленнее и ведет к дополнительным расходам на содержание этого пула и увеличивает фрагментацию памяти в куче.

Идет вразрез с имеющейся практикой. Захочешь прицепить REST интерфейс например и обнаружишь что фреймворк хочет работать только с урлами вида http://myserver:8080/rest/table/10, а http://myserve:8080/rest/table/ДядяВася не катит и надо надо делать кучу работы руками вместо того чтобы заюзать какой-нибудь spring-data-rest-webmvc и сгенерировать методы GET/POST/PUT/PATCH/DELETE автоматически.
2B OR NOT(2B) = FF
Ответить