Разработка системы тегов, которая может маркировать несколько таблиц БД - PullRequest
3 голосов
/ 02 марта 2010

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

<db Trackable product 1>
int id;
info etc
</>

<db Trackable product 2>
int id;
info etc
</>

//defines the M:M relationship between Tag and various types of Trackable products
<db TagLink>
int trackableProd1Id
int trackableProd2Id
int tagId
</>

<db Tag>
int tagId
tag name etc
</>

Это хороший способ сделать это? Преимущество этого подхода заключается в том, что он должен хорошо масштабироваться, а также позволяет мне добавлять больше отслеживаемых продуктов в будущем, просто добавив столбец в таблицу TagLink. Очевидно, что это не очень хорошая идея, если я планирую отслеживать 10 таблиц, но для 3-4 таблиц это должно хорошо работать, не так ли?

Ответы [ 2 ]

2 голосов
/ 02 марта 2010

Ну, обычно теги реализуются с отношением «многие ко многим» (отношение m: n, если хотите). Есть три таблицы:

tags
    id INT NOT NULL AUTO INCREMENT
    name VARCHAR NOT NULL
    .
    .
    .
    possibly other fields
    .
    .
    .
    PRIMARY KEY (id)

items_you_want_to_tag
    id INT NOT NULL AUTO INCREMENT PRIMARY KEY
    name VARCHAR NOT NULL
    .
    .
    .
    possibly other fields
    .
    .
    .
    PRIMARY KEY (id)

xref
    tag_id INT NOT NULL
    item_id INT NOT NULL
    FOREIGN KEY (tag_id) REFERENCES tags(id)
    ON UPDATE CASCADE ON DELETE CASCADE,
    FOREIGN KEY (item_id) REFERENCES items_you_want_to_tag(id)
    ON UPDATE CASCADE ON DELETE CASCADE,
    PRIMARY KEY (tag_id, item_id)

Вышеприведенная схема, конечно, в псевдокоде.

Таким образом, ваша схема выглядит примерно как мне, за одним исключением. Если вы хотите пометить две таблицы, я бы создал отдельные таблицы тегов для каждого типа продукта (таблицы «Отслеживаемый продукт 1» и «Отслеживаемый продукт 2» в вашем случае), а также создал две таблицы пересечений. Таким образом, у вас будет шесть столов.

Убедитесь, что вы используете правильные индексы, иначе это не будет так хорошо масштабироваться:)

UPDATE:

Или, если вы хотите иметь возможность пометить оба типа продуктов одним и тем же тегом, добавьте другое поле в таблицу пересечений, содержащую группу продуктов, и добавьте его в первичный ключ multi (как уже указывалось mjv;)) .

1 голос
/ 02 марта 2010

Вместо нескольких столбцов «TrackableProd_N_id» в таблице TagLink я предлагаю вам ввести внешний ключ из нескольких столбцов, например

   TagLink table
      int ProdGroup    -- "points" to table 1 vs. table 2 etc.
      int ProductId
      int TagId

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

...