Какова относительная стоимость чтения строк и столбцов в SQLite? - PullRequest
0 голосов
/ 02 сентября 2011

Я пытаюсь создать оболочку для баз данных SQLite, которая позволила бы доступ без схем из приложений .net.Идея состоит в том, чтобы каждая сущность представляла собой просто пару значений коллекции или атрибута.

Приоритетом является простота и простота использования для разработчика, а не производительность, но я не хочу полностью игнорировать использование памяти ивремя чтения диска.

Архитектура моей оболочки будет означать, что все первичные ключи как минимум будут считываться для первого запроса (а затем кэшироваться), однако другие атрибуты могут быть прочитаны позже при необходимости.

Вопрос в том, лучше ли создавать (во время выполнения) столбец для каждого имени атрибута и извлекать столбцы, соответствующие запрошенным атрибутам, или иметь запись для каждого атрибута и извлекать записи.запрошенных атрибутов.

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

1 Ответ

0 голосов
/ 03 сентября 2011

Не изобретайте велосипед заново, особенно когда тот, который вы пытаетесь заменить, уже круглый.

Итак, давайте посмотрим, как существующее колесо сравнивается с тем, которое вы пытаетесь заново изобрести.

1) Существующее колесо (таблица со столбцами) У нас есть таблица Entity, которая имеет такую ​​структуру:

id    INTEGER PRIMARY KEY
attr1 INTEGER
attr2 REAL -- this holds a date
attr3 TEXT
attr4 TEXT

2) Изобретенное колесо, таблица атрибутов. Скажем, мы создадим таблицу EntityAttributes дляэто то, что мы будем хранить все атрибуты из Entity в 1), но вопрос в том, как это должно выглядеть?Должны ли мы использовать TEXT в качестве типа для всех значений атрибутов и обрабатывать обратное преобразование в приложении?Тогда таблица может выглядеть так:

entity_id  INTEGER
attr_name  TEXT
attr_value TEXT
           PRIMARY KEY(entity_id, attr_name)

Это на самом деле не такая уж большая драма, поскольку внутренне Sqlite хранит все как TEXT, но когда дело доходит до любой нормальной СУБД, это огромные потери.

Альтернативой является использование таблицы сложных атрибутов, которая поддерживает несколько типов.Это может выглядеть так:

entity_id  INTEGER
attr_name  TEXT
attr_int   INTEGER
attr_real  REAL
attr_text  TEXT
           PRIMARY KEY(entity_id, attr_name)

Существует еще одна возможность - использовать основную таблицу для пары (entity_id, entity_name) с суррогатным ключом и таблицу для каждого типа данных (который имеет в качестве PK суррогат)значение ключа из таблицы основных атрибутов), но это становится слишком много для этого обсуждения.

Самое главное, чтобы увидеть, что с самого начала есть проблемы, которые нам нужно обойти, когда мы выбираем колесо.

Теперь давайте продолжим и поговорим немного о производительности.Все значения в строке обычно хранятся рядом (или близко) друг к другу, поэтому стоимость ввода-вывода обычно низкая.Этого нельзя сказать о нескольких строках, особенно если они не вставляются одна за другой.Вы всегда можете переиндексировать файл базы данных, чтобы оптимизировать доступ, но это не сильно поможет, если строки не создаются одна за другой.
Еще один недостаток вашего решения заключается в том, что ему действительно нужно больше памяти, чем естественному решению (немного, но еще больше).

Все хорошо до сих пор?Как насчет этого: у вас есть следующий простой SQL-запрос:

SELECT id, attr1, attr2
  FROM Entity
 ORDER BY attr1;

Попробуйте сделать то же самое, используя подход атрибута на строку, посмотрите, насколько это просто.И это только пример, на ум приходят многие другие.

По сравнению с традиционной СУБД решение таблицы атрибутов выглядит в вашем случае только хуже (на этот раз, потому что они лучше справляются с сохранением значений столбца строкивместе и для другого, потому что они поддерживают разные типы в отличие от Sqlite).При использовании хранилища данных Key-value, такого как Redis, это совсем другое дело.

В целом, можно многое сказать против подхода атрибута на строку и на самом деле не имеет никакого преимущества, если вы можете сделать то же самое, используя несколькоколонны.Таблица атрибутов полезна, когда она вам действительно нужна, на ум приходит что-то вроде неизвестного количества (динамических) атрибутов, но в вашем случае я бы остановился на естественном решении.

...