【问题标题】:MySQL: tagging systemMySQL:标记系统
【发布时间】:2012-01-07 05:42:40
【问题描述】:

假设我有一个可以有 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 中描述的此类表,是否存在“适当的”数据库术语?

【问题讨论】:

标签: php mysql database database-design tagging


【解决方案1】:

请参阅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 已经是一条记录并且有一个tag_id,比如10。当尝试再次插入bar 时,返回什么? 10???这就是我想要的。
  • 是 10,LAST_INSERT_ID(tag_id) 将是 LAST_INSERT_ID(10) 然后,将最后一个插入 id 设置为 10。调用 mysqli_insert_id(或来自 C API last_insert_id() 的等效项)将返回该 10 值然后。只是测试它。请注意,这是特定于 MySQL 的。
【解决方案2】:

#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];
}

【讨论】:

    【解决方案3】:

    如果我没有遗漏任何内容,如果您的问题是 #2 在您的问题中遇到此标记系统的问题,即插入一个新标签“bar”(如果它不存在),请尝试使用 @ 987654321@ 这将跳过插入标签(如果存在),我认为这是您在 #3 中寻找的术语,如下所示:

    INSERT IGNORE INTO Tag set name = 'bar';
    

    【讨论】:

    • 我需要担心INSERT IGNORE 的任何“陷阱”?对于#3,我正在寻找一个“适当的”术语来指代此类表格。例如,我听说人们将“foo_tag”称为“映射表”。正在寻找类似的东西。
    • 我认为使用它没有“陷阱”,请参见:stackoverflow.com/questions/548541/…,对于#3,如果您只是询问命名约定,我认为它可能只是命名为 @987654326 @查看本页右侧的数据库结构:data.stackexchange.com/stackoverflow/query/new.
    猜你喜欢
    • 2014-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-21
    • 1970-01-01
    • 2011-07-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多