2011-11-27 68 views
3

假设我有一个可以有0个或多个标签的表:MySQL的:标签系统

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”。如果“酒吧”不存在,将其添加到tag表中并返回最后插入的ID。如果“bar”确实存在,请不要添加它并返回tag_id。
  3. 对于在#2中描述的这样的表,是否存在“适当”的DB术语?
+0

几乎相同:http://stackoverflow.com/questions/20856/how-do-you-recommend-implementing-tags-or-tagging –

+0

链接可能回答问题#1。问题#2和#3对我来说也很重要。 – StackOverflowNewbie

回答

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需要是一个唯一的密钥。

+0

'tag.name'将是唯一的。如果'bar'已经是一条记录并且具有例如10的'tag_id'。当再次尝试插入'bar'时,返回的是什么? 10 ???这就是我想要的。 – StackOverflowNewbie

+0

是的10,'LAST_INSERT_ID(tag_id)'将是'LAST_INSERT_ID(10)',然后将最后一个插入id设置为10.调用mysqli_insert_id(或者来自C API'last_insert_id()'的等价物)将返回10值然后。只是测试它。请注意,这是MySQL特定的。 – hakre

0

如果我不想念的东西,如果这个标签系统的问题是#2在你的问题是插入一个新的标签“栏”如果不存在的话,那么请尝试使用INSERT IGNORE这将跳过插入标记,如果它存在,我认为这是你正在寻找#3这样的术语:

INSERT IGNORE INTO Tag set name = 'bar'; 
+0

任何“陷阱”我需要担心与'插入IGNORE'?而对于#3,我正在寻找一个“适当”的术语来指代这些表格。例如,我听说有人称“foo_tag”为“映射表”。寻找类似的东西。 – StackOverflowNewbie

+0

我认为没有“陷阱”使用它只是看到这一点:http://stackoverflow.com/questions/548541/insert-ignore-vs-insert-on-duplicate-key-update,和#3如果你只是询问关于命名约定我认为它可能是因为它命名为'Tags'参见本页右侧的Db结构:http://data.stackexchange.com/stackoverflow/query/new。 –

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