SQLITE: одна таблица с 20 столбцами против 20 таблиц ключ-значение

Я разрабатываю систему, которая управляет объектами, состоящими из компонентов. Как лучше хранить их в базе данных SQLITE с точки зрения производительности? если есть 20 типов компонентов, каждый компонент представляет собой большой двоичный объект размером 1–10 КБ. Обычно каждый объект состоит из 4-6 различных компонентов.

Я вижу два варианта:

  1. Реализуйте его как одну таблицу с ключом и 20 столбцами больших двоичных объектов.
  2. Используйте 20 таблиц с ключом и одним столбцом больших двоичных объектов.

Единственные запросы, которые я буду делать к базе данных: получить данные компонента по идентификатору, записать данные и удалить данные.

PS: класс объекта выглядит так:

class Entity
{
    Component *components[20];
}

обычно массив компонентов имеет 4-6 не нулевых указателей


person Rem    schedule 07.03.2015    source источник
comment
1) Самый простой способ узнать это — сравнить оба для вашей рабочей нагрузки. 2) При бенчмаркинге убедитесь, что вы знаете, насколько вы заботитесь о задержке по сравнению с пропускной способностью. 3) Вопросы производительности почти всегда связаны с рабочей нагрузкой.   -  person merlin2011    schedule 07.03.2015
comment
Да, но я думаю, что мой вопрос больше о sqlite и о том, как он хранит несколько полей внутри. Будет ли это эффективно, если 75% значений в столбцах пусты?   -  person Rem    schedule 07.03.2015
comment
В этом случае вам, вероятно, следует а) перефразировать свой вопрос, чтобы спросить о структуре хранения sqlite и, возможно, б) продемонстрировать усилия, указав место в исходном коде, где вы смотрели и не поняли.   -  person merlin2011    schedule 07.03.2015
comment
Я думаю, что ответ, очевидно, зависит только от внутренних компонентов sqlite. И я задаю этот вопрос, потому что для ответа на него нужны либо огромные усилия по анализу источников sqlite, либо большой опыт работы с базами данных sqlite.   -  person Rem    schedule 07.03.2015
comment
Позвольте мне попытаться перефразировать, это правильно? У вас есть объекты, каждый из которых содержит набор компонентов. Существует ровно 20 различных возможных ComponentType. (Когда вы говорите ComponentType, означает ли это, что существует несколько различных компонентов, которые все являются ComponentType1? Если да, отличается ли версия ComponentType1 каждого объекта от версии ComponentType1 каждого другого объекта?) Каждый объект может опционально иметь либо ноль, либо один из каждого из 20 ComponentTypes, и это число 20 фиксировано и никогда не изменится? Если бы вы могли выразить это как классы и привести примеры, это помогло бы.   -  person MatBailie    schedule 07.03.2015
comment
MatBailie, да, вы абсолютно правы!   -  person Rem    schedule 07.03.2015
comment
(Когда вы говорите ComponentType, означает ли это, что существует несколько различных компонентов, которые все являются ComponentType1? Если да, отличается ли версия ComponentType1 каждого объекта от версии ComponentType1 каждого другого объекта?)< /б>   -  person MatBailie    schedule 07.03.2015
comment
1) для каждого типа есть только один компонент 2) да, данные каждого компонента уникальны   -  person Rem    schedule 07.03.2015


Ответы (1)


Вероятно, вам понадобится структура Entity Attribute Value для хранения больших двоичных объектов.

CREATE TABLE myObjectComponents (
   objectID          INTEGER,    -- Entity
   componentTypeID   INTEGER,    -- Attribute
   componentBLOB     BLOB,       -- Value
   PRIMARY KEY objectID, componentTypeID
)

Затем вы также можете добавить традиционную таблицу «myObject» с другими значениями, не относящимися к большим двоичным объектам, (такими как столбец идентификации, владелец, имя, временные метки создания и изменения и т. д. и т. д.) и обеспечить целостность с внешними ключевые ограничения.


Таблицы EAV очень гибкие и удобны для быстрого поиска столбца Value.

Они очень бедны в другом направлении; "учитывая значение (или комбинацию значений), у каких сущностей оно есть?" Но вы вряд ли будете искать поле BLOB.

Вы можете прочитать больше о достоинствах и недостатках EAV, в Интернете есть множество ссылок.


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

person MatBailie    schedule 07.03.2015
comment
Спасибо за ваш ответ. Но как вы думаете, EAV лучше, чем отдельная таблица для каждого типа? С отдельными таблицами у меня будут более быстрые и меньшие индексы, поэтому они должны работать быстрее. - person Rem; 07.03.2015
comment
Мне нужно больше узнать о вашем приложении, но в целом это будет считаться преждевременной оптимизацией. 20 таблиц снижают гибкость и дают очень незначительное преимущество в индексах. Проще говоря, ваше предложение может привести к необходимости выполнить 20 операторов для 20 разных таблиц (требуется 20 немного разных операторов), тогда как одна таблица выполнит это за один запрос - один поиск по индексу. За более чем 10 лет работы с БД я всегда обнаруживал, что меньшее количество таблиц (в пределах разумного) приводит к более короткому, более удобному/гибкому и часто более быстрому коду. - person MatBailie; 07.03.2015
comment
Вам может быть полезно записать все свои варианты использования, чтобы понять, какие операторы sql вы собираетесь выполнять. Вы можете обнаружить, что часто выполняете несколько запросов к своей структуре из 20 таблиц (или, что еще хуже, объединяете их все вместе) по сравнению с одним запросом к таблице EAV. Затем вы можете оценить выигрыш в производительности, который вам потребуется для каждого отдельного запроса, чтобы уменьшить накладные расходы, связанные с выполнением большего количества запросов. Трудно представить себе случай, когда ваша прибыль будет больше, чем ваши дополнительные накладные расходы. - person MatBailie; 07.03.2015
comment
На самом деле единственным важным вариантом использования является получение данных компонента по его типу и идентификатору, потому что данные компонента загружаются случайным образом по запросу. Вся моя структура у меня в памяти (не в базе данных) и только огромные компоненты загружаются из базы данных по мере необходимости - person Rem; 07.03.2015
comment
Я бы по-прежнему рекомендовал EAV. - person MatBailie; 07.03.2015