Нужна подсказка по простому дизайну БД MySQL

Я пытаюсь создать простую базу данных предметов, используя MySQL для игры. Вот как будут выглядеть мои 3 таблицы

     Предметы
     itemId | имя элемента 
    -------------------
     0001 | часть груди
     0002 | меч
     0003   | шлем
     attribute (таблица поиска атрибутов)
     attributeId       | attributeName
     ---------------------------------
     01             | сила 02 | ловкость 03 | интеллект 04             | защита 05             | повреждение 06             | мана 07             | выносливость 08             | описание 09             | тип 
     item_attributes (таблица соединений)
     itemId  | attributeId   | значение (смешанный тип, плохо?)
     ------------------------------------
     0001   | 01            | 35
     0001   | 03            | 14
     0001   | 09            | броня
     0001   | 08            | созданный удивительными эльфами

     0002   | 09            | оружие
     0002   | 05            | 200
     0002   | 02            | 15
     0002   | 08            | ваш средний меч

     0003   | 04            | 9000
     0003   | 09            | броня
     0003   | 06            | 250

Моя проблема с этим дизайном заключается в том, что value колонка в item_attributes стол должен использовать varchar тип данных, так как данные значения могут быть int, char, varchar, Я думаю, что это плохой подход, потому что я не смог бы быстро сортировать свои предметы по определенным атрибутам. Это также приведет к снижению производительности при обработке запроса, например, получить элементы с силой атрибута, значение которой находится в диапазоне от 15 до 35.

Вот мое потенциальное решение. Я просто добавил data_type столбец к attributes Таблица. Так это будет выглядеть примерно так

     атрибуты (таблица поиска атрибутов)
     attributeId       | attributeName | тип данных
     -------------------------------------------------- -
     01 | сила | ИНТ
     09             | тип | голец
     08             | интеллект | VARCHAR

Тогда я бы добавил еще 3 столбца item_attributes Таблица, int, char, varchar, Вот как новый item_attributes стол будет выглядеть так.

     item_attributes (таблица соединений)
     itemId  | attributeId   | значение | Int | символ | VARCHAR
     -------------------------------------------------- ----------------------
     0002   | 09            | оружие | ноль | оружие | ноль
     0002 | 05             | 200 | 200 | ноль | ноль
     0002 | 02 | 15 | 15 | ноль | ноль
     0002 | 08             | ваш средний меч | ноль | ноль | ваш средний меч

Так что теперь, если бы я был сортировать элементы на основе его strength атрибут, я бы использовал int колонка. Или искать элемент на основе его описания, я бы поискал varchar колонка.

Однако я все еще считаю, что мой дизайн немного странный. Теперь я должен был бы посмотреть data_type колонка в attribute таблица и динамически определить, какой столбец в item_attributes Таблица имеет отношение к тому, что я ищу.

Любые материалы будут с благодарностью.

Заранее спасибо.

РЕДАКТИРОВАТЬ 29.11.2010 Вот подробный список моих товаров

--------------------------------------
http://wow.allakhazam.com/ihtml?27718
Ножные латы защитника Алдора
Персональный при поднятии
LegsPlate
Броня 802
+21 к силе
+14 к ловкости
+21 к выносливости
Уровень предмета 99
Если на персонаже: рейтинг меткости +14.
--------------------------------------
http://wow.allakhazam.com/ihtml?17967
Изысканная чешуя ониксии
Натуральная кожа
Уровень предмета 60
--------------------------------------
http://wow.allakhazam.com/ihtml?27719
Алдорские леггинсы счастья
Персональный при поднятии
LegsLeather
Броня 202
+15 к ловкости
+21 к выносливости
Уровень предмета 99
Если на персонаже: сила атаки +28.
Если на персонаже: рейтинг меткости +20.
--------------------------------------
http://wow.allakhazam.com/ihtml?5005
Emberspark Pendant
Становится персональным при надевании
NeckMiscellaneous
+2 к выносливости
+7 Дух
Требуется уровень 30
Уровень предмета 35
--------------------------------------
http://wow.allakhazam.com/ihtml?23234
Синий Брианит Ловкости
Драгоценные камни
Требуется уровень 2
Уровень предмета 10
+8 к ловкости
--------------------------------------
http://wow.allakhazam.com/ihtml?32972
Пивные очки
Персональный при поднятии
уникальный
HeadMiscellaneous
Уровень предмета 10
Если на персонаже: Гарантировано Belbi Quikswitch, чтобы КАЖДЫЙ выглядел привлекательно! 
--------------------------------------
http://wow.allakhazam.com/ihtml?41118
Gadgetzan Present
Персональный при поднятии
уникальный
Уровень предмета 5
"Пожалуйста, вернитесь к организатору сезона"
--------------------------------------
http://wow.allakhazam.com/ihtml?6649
Обжигающий тотемный свиток
уникальный
Квестовый предмет
Требуется уровень 10
Уровень предмета 10
Использование:  
--------------------------------------
http://wow.allakhazam.com/ihtml?6648
Тотем свитка каменной кожи
уникальный
Квестовый предмет
Требуется уровень 4
Уровень предмета 4
Использование:  
--------------------------------------
http://wow.allakhazam.com/ihtml?27864
Brian's Bryanite расширенного копирования стоимости
Драгоценные камни
Уровень предмета 10
чары для драгоценного камня
--------------------------------------

РЕДАКТИРОВАТЬ № 2

  1. Эти 10 примеров не являются репрезентативными для всех 35316 данных, которые я собрал.
  • "Разное" означает, что предмет относится к обеим категориям: "шея" и "разное".
  • Уникальный означает, что только один предмет может быть использован для персонажа.
  • Не читайте слишком много в "Действие", это просто описание квеста
  • Когда предмет говорит: "Надеть: увеличить силу атаки на 28", это просто означает +28 к силе атаки персонажа игрока. Это +15 к ловкости.
  • Всего имеется 241884 записей атрибутов "один ко многим", что составляет 241884/35316 ~= 8 средних атрибутов на элемент. Также данные добываются с сайта в гигантский текстовый файл. НЕТ "правильно сформированной" информации для определения типа или категории предмета. Таким образом, если слово "меч" появляется в 3-й или 4-й строке, оно автоматически классифицируется как меч.
  • Предмет может меняться при каждом новом обновлении игры.
  • У элемента нет общего универсального атрибута, кроме `name`
  • Данные элемента доступны через веб-приложение. Неясно, что вы подразумеваете под битами и векторами?
  • Регулярное выражение используется на этапе интеллектуального анализа данных для очистки специального символа и поиска определенного ключевого слова для классификации элементов. Также для извлечения имени и значения атрибута. Например, +15 к ловкости будет иметь строковую ловкость, извлеченную как имя атрибута, и 15 как значение. (Я не очень разбираюсь в вопросах 6 и 6.1. Слог здесь обозначает журнал сервера? Перевести регулярные выражения в SQL?)
  • Модельная диаграмма

    Вот пример того, как выглядит запрос

    Выбрать *
    от itemattributestat
    где item_itemId=251
    
    item_itemId | attribute_attributeId | значение | listOrder
    =======================================================
    "251", "9", "0", "1"
    "251", "558", "0", "2"
    "251", "569", "0", "3"
    "251", "4", "802", "4"
    "251", "583", "21", "5"
    "251", "1", "14", "6"
    "251", "582", "21", "7"
    "251", "556", "99", "8"
    "251", "227", "14", "9"
    

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

    создать представление itemDetail as
    выберите Item_itemId в качестве идентификатора, i.name в качестве элемента, a.name в качестве атрибута, значение
    from ((itemattributestat присоединяет элемент как i к Item_itemId=i.itemId) 
        Атрибут объединения как атрибут Attribute_attributeId=a.attributeId)
    упорядочить по Item_itemId asc, listOrder asc;
    

    Приведенный выше вид производит следующее с

    Выбрать *
    из предмета детали
    где id=251;
    id | элемент | атрибут | значение
    '251', 'Ножные латы Алдора Защитника', 'Персональный при поднятии', '0'
    "251", "Ножные латы Алдора Защитника", "Ноги", "0"
    "251", "Ножные латы Алдора Защитника", "Тарелка", "0"
    '251', 'Ножные латы Алдора Защитника', 'Броня', '802'
    "251", "Ножные латы Алдора Защитника", "Сила", "21"
    "251", "Ножные латы Алдора Защитника", "Ловкость", "14"
    "251", "Ножные латы Алдора Защитника", "Выносливость", "21"
    '251', 'Ножные латы Алдора Защитника', 'Уровень предмета', '99'
    "251", "Ножные латы Алдора Защитника", "Если на персонаже: Повышает рейтинг меткости на @@.", "14"
    

    Атрибут со значением 0 означает, что имя атрибута представляет тип элемента. 'Equip: Improves hit rating by @@.', '14' @@ здесь заполнитель, обработанный вывод в браузере будет 'Equip: Improves hit rating by 14.'

    3 ответа

    Решение

    Почему у вас есть attribute стол?

    Атрибуты - это столбцы, а не таблицы.

    Ссылка на сайт ничего не говорит нам.

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

    (надрез)

    Не добавляйте префиксы к именам ваших атрибутов (имен столбцов). Это станет ясно вам, когда вы начнете писать SQL, который использует более одной таблицы: тогда вы можете использовать имя таблицы или псевдоним для добавления префиксов к любым именам столбцов.

    Исключением является PK, который отображается полностью и используется в этой форме, где бы он ни был FK.

    Просмотрите сайт и прочитайте несколько вопросов по SQL.

    После этого вы можете подумать, хотите ли вы strength а также defense быть атрибутами (столбцами) type; или нет. И так далее.

    Ответы на комментарии 30 ноября 10

    ,
    Отлично, вы понимаете свои данные. Правильно. Теперь я понимаю, почему у вас была таблица атрибутов.

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

      • Тип: Драгоценный камень Имя:Emberspark Pendant ... Или это шейка Разное?
      • Является ли Unique истинным ItemType? Думаю, нет
      • Action.Display "Пожалуйста, вернитесь к организатору сезона"
      • Где находятся Атрибуты для AttackPower а также HitRating?
        ,
    2. Сколько существует различных типов товаров (из 35000), например, мой Кластер продуктов. Другой способ сформулировать этот вопрос - сколько существует вариантов. Я имею в виду, по сути, а не 3500 предметов ÷ 8 атрибутов?

    3. Изменится ли item_attributes без выпуска программного обеспечения (например, нового Inner Strength атрибут)?

    4. По элементу, какие атрибуты повторяются (более одного); пока вижу только экшн?

    5. Это игра, поэтому вам нужен жесткий и очень быстрый БД, может быть, полностью сохраняющий память, верно. Нет нуля. Нет VAR ничего. Кратчайшие типы данных. Никогда ничего не дублируйте (не повторяйте себя). Вы довольны битами (логическими значениями) и векторами?

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

      6.1 Или, может быть, все наоборот: база данных находится на диске; вы загружаете его в память один раз; вы запускаете регулярные выражения для этого во время игры; изредка записываю на диск. Поэтому нет необходимости переводить регулярные выражения в SQL?

    Вот модель данных о том, куда я направляюсь, это не совсем точно; это будет модулироваться вашими ответами. Чтобы было ясно:

    • Шестая нормальная форма - строка состоит из первичного ключа и, самое большее, одного атрибута.

    • Я нарисовал (6.1), а не (6), потому что ваши данные подтверждают мое убеждение, что вам нужна чистая 6NF реляционная база данных

    • Моя модель данных кластера продуктов, пример лучше, чем EAV, имеет значение 6NF, затем снова нормализуется (не в смысле нормальной формы) с помощью DataType, чтобы уменьшить число таблиц, которые вы уже видели. (EAV люди обычно идут за один или несколько гигантских столов.)

    • Это прямой 5NF, только в 6NF только 2 таблицы справа.

    Ссылка на модель данных игры

    Ссылка на нотацию IDEF1X для тех, кто не знаком со стандартом реляционного моделирования.

    Ответ на Edit #2 05 декабря 10

    1.1. Хорошо, исправлено.

    1.2. Тогда Is Unique является индикатором (логическим) для Item.

    1.3. Действие. Я понимаю. Так где вы собираетесь хранить его?

    1.4. NeckMiscellaneous означает, что товар находится в обеих категориях Neck а также Misc , Это означает, что два отдельных Item.Name=Emberspark Pendant каждый с другой категорией.

    ,
    2. и 5. Так что вам нужен быстрый быстрый резидентный дБ. Вот почему я пытаюсь перевести вас через линию, от GridLand, в RelationalLand.
    ,
    3. Хорошо, мы остаемся с пятой нормальной формой, нет необходимости в 6NF или кластере продуктов (таблицы на тип данных). Софар Values все целые числа.
    ,
    4. Я могу видеть дополнительно: Level, RequiredLevel, IsUnique, BindsPickedUp, BindsEquipped,
    ,
    5. Биты логические { 0 | 1 } Векторы необходимы для (реляционных) проекций. Мы доберемся до них позже.
    ,
    6. Хорошо, вы объяснили, что вы не переводите регулярные выражения в SQL. (Слог означает тяжелый труд).,
    7. Что такое Category.ParentId? Родительская категория? Это не подходило раньше.
    ,
    8. Attribute.GeneratedId?

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

    я имею Action как таблица, с ItemAction держа Value:
    Equip: increase attack power by 28 является Action.Name знак равно Increase attack power by а также ItemAction.Value =28.

    Я думаю, что имея data_type Колонка еще больше усложняет конструкцию. Почему бы просто не иметь type а также description быть колоннами на items Таблица? Само собой разумеется, что каждый элемент будет иметь каждое из этих значений, а если нет, то null будет хорошо в текстовом столбце.

    Вы можете еще больше нормализовать type имея item_types стол и type колонка в items будет числовой внешний ключ к этой таблице. Может быть необязательным, но может облегчить выбор типа на items Таблица.

    Изменить: Думая об этом дальше, кажется, что вы, возможно, пытаетесь, чтобы ваши таблицы данных соответствовали модели предметной области. Ваши предметы будут иметь ряд атрибутов в логике приложения. Это отлично. Имейте в виду, что логика вашего приложения и схема сохранения базы данных могут отличаться. На самом деле, они не должны полагаться друг на друга на уровне дизайна. Во многих небольших приложениях они, вероятно, будут одинаковыми. Но есть и исключения. Код (предположительно объектно-ориентированный, но не обязательно) и реляционные данные имеют разный дизайн и разные ограничения. Разделение их друг с другом позволяет разработчику использовать преимущества их проектов, а не ограничиваться их ограничениями.

    Вы имеете дело с двумя общими проблемами:

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

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

    В этом случае я бы лично выбрал решение на полпути между реляционным и EAV. Я бы взял общие столбцы и добавил их в виде столбцов либо в таблицу элементов, либо, если элементы представляют виды элементов, а не отдельные элементы, в таблицу items_owners. Эти столбцы будут включать описание и, возможно, тип, а в приведенном вами примере они будут в значительной степени соответствовать текстовым столбцам. Затем я бы сохранил существующий макет для тех атрибутов, которые являются числовыми рейтингами, делая тип значения int. Это дает вам проверку типов и правильную нормализацию целочисленных атрибутов (вы не будете хранить много NULL) за счет случайного типа или описания NULL.

    Другие вопросы по тегам