2011-11-27 66 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]; 
}