Проектирование базы данных (улучшение предметов RPG) - PullRequest
0 голосов
/ 07 ноября 2018

Я пытаюсь выяснить, как составить таблицы базы данных, чтобы улучшить элементы (+0, +1, ...).

Что у меня есть: StatType (hp, str, ...) -> ItemStat (ItemId, StatId, Value) <- Item (Id, name, ...) </p>

Дело в том, что я хочу улучшить предметы, поэтому я подумал:

1 - в ItemStat (ItemId, StatId, EnhanceLevel, Value) Проблема: Как я могу обеспечить, чтобы каждый уровень улучшения давал значение каждому параметру предмета

2 - Для решения проблемы было бы иметь новую таблицу: ItemBaseStats (ItemId, StatId), чтобы были все базовые характеристики элемента и, чем в ItemStat (ItemId, StatId, EnhanceLevel, Value) до вставка, которую я бы проверил ItemBaseStats.

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

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

И, между прочим, я использую C # с EF Core (SQL Server), поэтому все будет сделано с помощью кода, но мне нужно понять это, потому что это изменит способ построения и записи модели).

1 Ответ

0 голосов
/ 07 ноября 2018

Прежде всего, взглянув на свою таблицу ItemStat, вы используете дизайн под названием EAV, Entity-Attribute-Value. Первый пост, который я нашел о плюсах и минусах этого, этот , и, короче говоря, он может быть полезен, когда атрибуты сущности являются динамическими, но реляционными базами данных (какой сервер sql является) не предназначены для этого. И действительно, я думаю, что вместо этого вам подойдет реляционная модель.

Также имейте в виду, что я совсем не знаю ef-core, так что это все с точки зрения базы данных.

Чтобы выяснить характеристики предмета, вам необходимо знать а) предмет и б) уровень его улучшения. Таким образом, я предлагаю:

1) Таблица Item, как у вас уже есть

2) Таблица ItemStat, которая будет иметь ItemId, ссылающуюся на Item.Id, EnhanceLevel и вместо упомянутых вами столбцов, имеет один столбец для каждого возможного значения статистики. Primary Key этой таблицы будет (ItemID,EnhanceLevel).

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

Пример в вашем комментарии будет выглядеть так:

[Table Item]
Id, name

Item1, 'Sword of StackOverflow'

[Table ItemStat]
ItemID, EnhanceLevel, stat1, stat2

Item1, 0, 2, 0
Item1, 1,10, 0
Item1, 2,15, 5

Учитывая комментарии, EAV-решение, которое я бы предложил:

Делайте в точности то, что вы описываете в своей точке "2 -" (т.е. добавьте столбец EnhanceLevel в ItemStat), но нет необходимости в таблице ItemBaseStats. Вы просто вставите все базовые характеристики в ItemStats, где EnhanceLevel = 0.

Я не знаю nosql. Однако, как вы сами заявили в комментарии, я бы предложил пересмотреть мой первый ответ. Размер таблицы, скажем, 300 элементов * 100 уровней улучшения = 30000 строк * 200 столбцов, возможно, будет невероятно низким для того, что вы можете иметь в виду (я ожидаю несколько МБ). И для чтения по ним будет использоваться поиск по кластерному индексу, поскольку каждый раз вы наверняка знаете как элемент, так и его усовершенствование. По моему мнению, процессор, сэкономленный благодаря тому, что ему не нужно присоединяться ко ВСЕМ атрибутам, необходимым при каждом чтении, будет предпочтительным ресурсом, которого следует избегать.

...