设计可以标记多个db表的标记系统

时间:2010-03-02 02:57:46

标签: php database tags tagging

我希望允许用户标记项目,以便他们可以使用标记搜索它们。干净利落的最佳方法是什么?到目前为止,我提出的解决方案只涉及在我当前的数据库系统中添加两个额外的表。

<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 个答案:

答案 0 :(得分:2)

嗯,通常标签是用多对多关系实现的(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表),并创建两个交集表。所以你会有六张桌子。

确保使用正确的索引,否则它不会很好地扩展:)

更新:

或者,如果您希望能够使用相同的标记标记两种产品类型,请将另一个字段添加到包含产品组的交集表中,并将其添加到多主键(如mjv已经指出的那样))

答案 1 :(得分:1)

我建议您引入多列外键,而不是TagLink表中的多个“TrackableProd_N_id”列,例如

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

以这种方式出现其他产品来源时,您只需要为它们“发明”一个新的ProdGroup编号,并使用ProductId(或该表中的其他主键)。