3

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

<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 张桌子,它应该证明可以很好地工作,不是吗?

4

2 回答 2

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 已经指出的那样;))。

于 2010-03-02T03:08:54.423 回答
1

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

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

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

于 2010-03-02T03:09:46.273 回答