Как спроектировать базу данных, в которой основная таблица сущностей имеет более 25 столбцов, но столбцы одной сущности заполняются в среднем на <20%? - PullRequest
3 голосов
/ 17 апреля 2010

Сохраняемые объекты имеют более 25 свойств (столбцы таблицы). Сущности довольно разнообразны, что означает, что большинство столбцов пустые. В среднем, я бы сказал, менее 20% (<5) свойств имеют значение в любом конкретном элементе. Итак, у меня есть много лишних пустых столбцов для большинства строк таблицы. Почти все столбцы являются десятичными числами. </p>

Учитывая этот сценарий, вы бы предложили вместо этого сериализовать столбцы или, возможно, создать еще одну таблицу с именем «Свойство», которая будет содержать все возможные свойства, а затем создать еще одну таблицу «EntityProperty», которая отобразит свойство на объект используя внешние ключи? Или вы бы оставили все как есть?

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

У нас есть воображаемая вселенная с множеством планет. Мы создаем космическую игру, и каждая планета содержит 30 различных минеральных веществ. На большинстве планет всего 2-3 минерала.

Самое простое решение - создать одну таблицу «Планеты» с 30 столбцами, по одному на каждый минерал. Проблема здесь в том, что большинство строк в таблице «Планеты» имеют более 25 столбцов, в каждом из которых значение равно нулю или нулю. Таким образом, у нас много избыточных данных. Скажем, у нас будет 500k-1M записей. Я бы предположил, что для сохранения нулевого или нулевого десятичного значения стоит не более одного байта. Таким образом, мы тратим пространство 500 000-1 000 000 байт, т.е. максимум один мегабайт.

Другим решением будет создание двух дополнительных таблиц. Вместо того, чтобы хранить все минералы в таблице «Планеты», мы вынимаем их все и создаем таблицу для минералов под названием «Минералы». Это будет содержать только 30 строк, по одному для каждого типа минералов. Затем мы создаем таблицу под названием «PlanetMineral», которая содержит ссылку на ряд планет и ряд минералов, и дополнительно в этой таблице будет столбец, показывающий количество минерала, которое есть на планете. По-видимому, во многих системах баз данных это усложняет запросы, поскольку необходимо выполнить несколько соединений. Я использую сервер SQL с LINQ to SQL, который поддерживает ограничение внешнего ключа в свойстве объекта класса, доступного через код. (т.е. я могу просто получить доступ к минералам, которые есть на планете вместе с планетой. Минералы) Итак, с этой точки зрения это не добавляет сложности. Избыточность - это небольшая часть (примерно 1/15) первого решения. Причина по-прежнему в том, что внешние ключи нам нужно хранить.

Что касается эффективности запросов данных, я действительно не знаю, как бы сравнивались затраты на эти два решения.

Ответы [ 2 ]

0 голосов
/ 17 апреля 2010

Это зависит от:

  • Сколько объектов (строк) вы планируете иметь?
  • Какие запросы вы выполняете к этой таблице?
  • Будет ли много новых объектов в будущем?
  • Как вы планируете использовать свойства?

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

Если у вас небольшое количество строк, то, вероятно, лучше использовать одну таблицу (ее легче реализовать).

Если вы планируете создавать сложные запросы к свойствам (например, где property1 <123), тогда простая таблица, вероятно, проще. </p>

Если вы планируете добавить много новых свойств в будущем, тогда может пригодиться подход Property / EntityProperties.


Я бы пошел с простым подходом с одной таблицей, потому что у вас довольно небольшое количество строк (<1M), вы, вероятно, работаете с базой данных на серверах, а не с каким-либо портативным / мобильным устройством (SQLServer) и схемой вашей базы данных довольно жесткий </p>

0 голосов
/ 17 апреля 2010

Для цифр я бы лично оставил все как есть, в 1 таблице. Числа сжимаются в несколько байтов, и издержки, связанные с наличием таблицы EntityProperty, намного превышают это значение. Сериализация - это вариант, но это означает, что вы не можете использовать SQL для поиска или вычисления свойств, вам нужно получить данные, десериализовать и затем вычислить.

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