Дизайн базы данных: пары имя-значение - хорошо или плохо? - PullRequest
4 голосов
/ 30 ноября 2010

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

Вариант 1 (пары имя-значение):

===========================
 field
===========================
- field_id
- category_id (FK, referring to category like "book")
- name
- value

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

Вариант 2 (отдельные таблицы):

===========================
 book_field
===========================
- book_field_id
- book_id (FK, referring to the actual book)
- author
- title
- publisher
- date_published
...

Это означает, что мне нужна таблица для каждой категории.

ПРИМЕЧАНИЕ: не то, чтобы я думал, что это имеет значение, но категория будет исходить из иерархии категорий (например, электроника -> DVD-плееры -> портативные DVD-плееры).

Ответы [ 3 ]

4 голосов
/ 30 ноября 2010

Мои $ 0,02 - одна таблица на категорию. Если вещи действительно разные, то примите это и настройте свои таблицы соответственно.

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

1 голос
/ 30 ноября 2010

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

Ну, в любом случае, вот одно решение, которое может быть вам полезно:

ОБНОВЛЕНИЕ (несколькодобавлены слои)

========
products
========
- product_id
- name

====================
categories_products
====================
- category_product_id
- product_id (FK)
- category_id (FK)

===========
categories
===========
- category_id
- name

=============================
products_detail_values_types
=============================
- product_detail_value_type_id
- product_id (FK)
- detail_value_type_id (FK)

====================
detail_values_types
====================
- detail_value_type_id
- detail_value_id (FK)
- detail_type_id (FK)

===============
detail_values
===============
- detail_value_id
- value

=============
detail_types
=============
- detail_type_id
- name

У вас есть тип, называемый "Director":

 detail_type:
   detail_type_id: 100
   name: "director"

И некоторые значения:

detail_value:
  detail_value_id: 200
  value: "James Cameron"      

Отображение типа и значения:

detail_value_type:
  detail_value_type_id: 300
  detail_value_id: 200
  detail_type_id: 100

Какие детали принадлежат продукту:

product_detail_value_type:
  product_detail_value_type: 400
  product_id: 500
  detail_value_type_id: 300

Тогда у нас есть категории:

category:
  category_id: 600
  name: "movie"

И отображение категории продукта:

category_product:
  category_product_id: 700
  product_id: 500
  category_id: 600

И, наконец, сам продукт:

product:
  product_id: 500
  name: "Aliens"
0 голосов
/ 30 ноября 2010

Я бы посоветовал вам основывать свой дизайн на том, на котором основан интернет-тег.

Позвольте мне объяснить вам:

Вам понадобится еще 4 таблицыВаша главная таблица объектов.

Первая : таблица тегов имен, это базовый идентификатор таблицы |имя, в котором будет храниться атрибут объекта: «автор», «размер», «вес»;все, что может описать объект

tag_table
id    varchar(36)
tag   varchar(36)

Второй : эта таблица будет сопоставлять значение с именами тегов, сохраненными в значении tag_table.Он имеет тот же дизайн

value_table
id    varchar(36)
value varchar(36)

Третий : определит, какое значение является каким тегом.

tag_value
id_pair  varchar(36)
id_tag   varchar(36)
id_value varchar(36)

Четвертый :присоединится к объекту с его данными, которые заботятся о нем

object_tag_value
id_object  varchar(36)
id_pair    varchar(36)

и, наконец, к вашей таблице объектов.

Реализация иерархической системы :

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

object_relation
id_parent varchar(36)
id_son    varchar(36)

Для многих-к-одному (например, таблица Employee с manager_id) просто добавьте id_parentкак член вашего объекта.

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

Надеюсь, я был достаточно ясен и что вам это поможет,

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