MySQL:标签系统

3
假设我有一张表格,它可以有0个或多个标签:
TABLE: foo
- foo_id (PK)

TABLE: tag
- tag_id (PK)
- name

TABLE: foo_tag
- foo_tag_id (PK)
- foo_id (FK)
- tag_id (FK)

问题:

  1. 我看到上面提到的标签系统是最常见和最简单的实现方式。我知道标记系统在可扩展性方面存在潜在的问题。这里会有这个问题吗?
  2. 在PHP或SQL中是否有一种方法可以像这样做:插入一个新的标签“bar”。如果“bar”不存在,则将其添加到tag表中并返回最后插入的id。如果“bar”已经存在,则不要将其添加并返回tag_id。
  3. #2中描述的这种表是否有“适当”的数据库术语?

请将以下与编程有关的内容从英语翻译为中文。仅返回已翻译的文本:与此类似:https://dev59.com/l3VD5IYBdhLWcg3wTZ1m - Kamil Lach
可能链接回答问题#1。问题#2和#3对我也很重要。 - StackOverflowNewbie
3个回答

0
如果我没有漏掉什么,如果您对这个标记系统的问题是在您的问题中的#2插入一个新标记"bar",如果它不存在,那么尝试使用INSERT IGNORE,这将跳过插入标记,如果它已经存在,我认为这是您在#3中寻找的术语,就像这样:
INSERT IGNORE INTO Tag set name = 'bar';

使用INSERT IGNORE时需要注意什么问题?至于第三点,我正在寻找一个“适当”的术语来指代这样的表。例如,我听说过人们将“foo_tag”称为“映射表”。寻找类似的东西。 - StackOverflowNewbie
我认为使用它没有任何“陷阱”,只需查看此链接:https://dev59.com/dHRB5IYBdhLWcg3wtJCF,至于#3,如果您只是询问命名约定,我认为它可能就像SO所命名的那样,只是`Tags`,请参见此页面右侧的Db结构:http://data.stackexchange.com/stackoverflow/query/new。 - Mahmoud Gamal

0

#2 我会将 唯一键 设置为 tag.name。假设你在 tag_id 上有自动递增,你可以尝试这样做:

function tagId($tag) {
  mysql_query("INSERT IGNORE INTO tag SET name='$tag'");
  if(mysql_affected_rows()) return mysql_insert_id();
  $result = mysql_query("SELECT tag_id FROM tag WHERE name='$tag'");
  if(!$result) return null;
  $data = mysql_fetch_row($result);
  if($data) return $data[0];
}

0
请参考http://dev.mysql.com/doc/refman/4.1/en/insert-on-duplicate.html获取更新时的最后一个ID的解决方法:
INSERT INTO table (a,b,c) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3;

这将把最后插入的 ID 更新为更新值的值。在您的情况下:

INSERT INTO tag (name) VALUES ('bar')
  ON DUPLICATE KEY UPDATE tag_id=LAST_INSERT_ID(tag_id);

tag.name 需要是一个唯一的键。


tag.name 将是唯一的。如果 bar 已经是一条记录,并且具有标签 ID 为 10。当尝试再次插入 bar 时,会返回什么?10???这就是我想要的。 - StackOverflowNewbie
是的,10,LAST_INSERT_ID(tag_id) 将会变成 LAST_INSERT_ID(10),然后将最后插入的 ID 设置为 10。调用 mysqli_insert_id(或等效的 C API last_insert_id())将返回该值 10。只需测试即可。请注意,这是 MySQL 特定的。 - hakre

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接