Это плохо, чтобы не использовать нормализованные таблицы в этой базе данных? - PullRequest
6 голосов
/ 19 июня 2010

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

Некоторая информация о ней:

Упрощенная структура выглядитнемного похоже на следующее:

 player_id |  level | exp  | money | inventory
---------------------------------------------------------
    1      |    3   | 120  | 400   | {item a; item b; item c}

Хорошо.Как видите, я храню таблицу / массив в виде строки в столбце «инвентарь».Это против нормализации.

Но дело в том, что создание дополнительного стола для инвентаря игроков приносит мне только недостатки!

  • Единственные точки, гдеЯ получаю доступ к базе данных:
    • Когда игрок присоединяется к игре и его профиль загружается
    • Когда профиль игрока сохраняется

Когда игрок присоединяется, я загружаю его данные из БД и сохраняю их в памяти.Я пишу в БД только каждые пять минут, когда проигрыватель сохраняется.Так что в моем скрипте очень мало SQL-запросов.

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

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

. После сохранения:

  • Удалите все предметы из таблицы инвентаря, принадлежащие игроку X (игрок мог сбросить / продать некоторые предметы?)
  • Пройдите по столу и выполните запрос для каждого предметаигроку принадлежит

Если бы я хранил все данные игрока в одной таблице:

  • У меня был бы только один запрос на сохранение и загрузку
  • Все было быбыть в одном месте
  • Мне нужно было бы (де) сериализовать таблицы после загрузки и сохранения, в моем сценарии

Что мне теперь делать?

Мои аргументы и ситуацииМожно ли оправдать работу против нормализации?

Ответы [ 8 ]

12 голосов
/ 19 июня 2010

Вы говорите, что думаете, что разбор строки из "инвентаря" не требует времени или усилий?Потому что все, что вам нужно сделать для хранения / извлечения предметов инвентаря из вложенной таблицы, - это то, что вам нужно сделать с этой строкой, а со строкой у вас нет инструментов базы данных, которые могли бы помочь вам сделать это.

Кроме того, если у вас была отдельная подтаблица для элементов инвентаря, вы можете добавлять и удалять элементы в режиме реального времени, что означает, что в случае сбоя приложения или отключения пользователя они ничего не потеряют.

4 голосов
/ 19 июня 2010

Есть много возможных ответов, но тот, который работает для вас, - тот, который нужно выбрать. Имейте в виду, ваш выбор может потребоваться изменить с течением времени.

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

Обычно считается хорошей идеей наладить архитектуру данных на ранней стадии, но сегодня нет смысла сидеть на собраниях, пытаясь угадать, как вы будете использовать свое программное обеспечение через 5-10 лет. Лучше получить дизайн, который соответствует потребностям этого года, а затем запланировать повторную оценку дизайна через год.

4 голосов
/ 19 июня 2010

Нет, ваши аргументы неверны. Они сводятся к тому, что «я хочу выполнить всю эту обработку в моем клиентском коде, а не в SQL, а затем просто записать все это в одно поле», потому что вы все еще выполняете все те же самые обработки сгенерировать строку. Делая это, вы удаляете возможность легко загружать небольшую часть списка и теряете связи с реальной таблицей item, которая может содержать больше информации об элементах (я предполагаю, что вы жестко программируете все это на основе имен вместо используя внутренние идентификаторы предметов, что очень плохо, imo).

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

4 голосов
/ 19 июня 2010

Что произойдет, если у вас в инвентаре будет сто тысяч предметов, и вы захотите вернуть только два?

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

Однако, если над этим вы будете работать несколько месяцев, то вы 'Мы столкнемся с долгосрочными проблемами с этим дизайнерским решением.

3 голосов
/ 19 июня 2010

Еще один случай преждевременной оптимизации.

Вы пытаетесь оптимизировать то, что у вас нет показателей производительности. Какова целевая платформа? В наши дни даже самые грязные компьютеры могут выполнять по меньшей мере сотни операций чтения в секунду. Затем вы добавляете более качественное оборудование для большего количества пользователей, затем вы можете перейти в облако, и когда вы попадете в проблемное пространство, с которым имеют дело Google, Twitter и Facebook, вы можете рассмотреть вопрос о денормализации. Даже тогда лучшее решение - это какая-то база данных ключ-значение.

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

2 голосов
/ 19 июня 2010

Вы также должны подумать о предметах. Являются ли элементы уникальными для каждого пользователя или у user1 может быть item1, а у user2 - item1 to. Если вы хотите изменить элемент 1, вам нужно просмотреть всю таблицу и проверить, у какого пользователя есть этот элемент. Если бы вы нормализовали свой стол, это было бы намного проще.

Но это конец, я думаю, что ответ: это зависит

1 голос
/ 19 июня 2010

Оправдывают ли мои аргументы и ситуация работу против нормализации?

Не основано на том, что я видел до сих пор.

Нормализованные проекты баз данных (соответствующим образом проиндексированные и сэффективное использование базы данных с UPSERTS, транзакциями и т. д.) в механизмах общего назначения, как правило, превосходит код, за исключением случаев, когда код очень тщательно оптимизирован.Как правило, в таком коде некоторые функции ядра СУБД общего назначения игнорируются, такие как одно из свойств ACID или ссылочная целостность.

Если вы хотите иметь очень простой доступ к данным (вы просматриваете одну таблицу, один запрос)в качестве преимущества), возможно, вам следует обратиться к базе данных, ориентированной на документы, например mongodb или couchdb.

0 голосов
/ 20 июня 2010

Причина, по которой вы используете любую технологию, заключается в использовании ее преимуществ.У SQL есть много преимуществ, которые вы, похоже, не хотите использовать, и это прекрасно, если они вам не нужны.В фильме Нила Стивенсона «1001 * Зодиак» главный герой упоминает, что некоторые вещи, купленные в магазине, используются по прямому назначению.Софт тоже такой.Что важно, так это то, что он работает, и работает почти 100% времени, и работает достаточно быстро.

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

С должным образом нормализованной структурой базы данных это тривиальная задача.С денормализованной структурой все немного сложнее и медленнее.Нормализованную базу данных также будет легче расширять в будущем.

Так вы уверены, что не хотите нормализовать базу данных?

...