2013-05-26 68 views
0

我有一個表,這個結構如何在3條記錄中實現交叉引用?

(int)id | (text)title | (text)description | (int)related 

,並與自身聯接表查詢

SELECT t1.*, t2.title as relatedTitle 
FROM mytable t1 LEFT JOIN mytable t2 ON t2.related=t1.id 

,以產生一個SELECT列表這樣

title:嗨,description:非正式問候,see also:你好

當一個新的記錄被存儲到表中,只有另外一個記錄可以參考

one-way reference

我試圖實現的是交叉引用

cross-reference

它可以是其中2 -5物體

multi cross-reference

Al l對象應該在每個組合中交叉引用。我想要這個功能:如果設置了related,腳本應該自動在相關記錄中創建交叉引用。如果記錄被刪除,腳本應更新相關記錄中的引用。

對於3+記錄相互參照,我正在考慮加入這個表

(int)id | (int)related 

但它是20條記錄5個交叉引用的對象。我也可以創建一列表

(varchar)relatedList 

但如何創建左連接以及如何刪除此結構中的關係?或者我應該嘗試一些其他方法,如觸發器,視圖或臨時表?我想避免冗餘,並儘可能簡單,只是不能弄清楚。

+0

請耐心等待:我現在必須離開一段時間,我需要專心思考你的答案。 (當我回來時,我會刪除這條評論。) –

回答

1

如果你的組通常大於2,那麼你應該創建一個組列表 - 如果A連接到B和C,它將創建一個組A,B,C。

因此,只要插入一個關係,就檢查相關項是否已經在一個組中。如果已設置,則「新」相關條目也在該組中。

如果不是,您剛剛創建了一個包含這兩個項目的新組。

因此,如果從您的示例「Hi」是單獨的,並且「Ho」連接到「Hi」,則兩者形成一個新組。 當「Ahoi」也連接到「Hi」時,它只需要複製Hi中的group_id。

編輯:根據評論要求選擇:

結構:

table groups: group_id int not null primary key auto_increment, created_tmstmp timestamp 
table items: item_id int, group_id int default null 

的選擇:

select * from items i1 
inner join items i2 on i2.item_id != i1.item_id 
     and i2.group_id = i1.group_id 
where i1.id = <given item>. 

的關係的插入物可以被連接到插入的其中一個項目,這取決於線程負責人的場景。如果它是兩個條目的新關係,則插入一個新組。

其他問題是:是否只在一個組中的項目?否則,需要一個item_group表將一個項目連接到多個組。

沒有加入字符串,抱歉有可能被如此殘酷地理解。;-)

+0

那麼選擇呢?在字符串比較的「組表」上加入單詞表兩次,對於我認爲的10K +記錄來說基準很差。或者,你會如何撰寫查詢? –

+0

沒有字符串連接,我添加了查詢。 – flaschenpost

+0

嗯,這是Jan本身,所以:你想問_if_兩個項目已連接或獲取連接項目列表?連接是不同的?我的意思是僅在_one_連接列表中有一個條目? – flaschenpost

0

轉到這一個:

(int)id | (int)related 

這是一個非常普遍的做法。

如果您使用列表方式,您的SQL查詢將會非常複雜。

通常,SQL引擎非常適合針對具有大量行的表優化查詢,因此在最合理的硬件上,您不必擔心此類表中的數百萬行。 (根據您要使用它,當然什麼。)

非定向模型邊,總是插在id列最低ID(你可以添加一個CHECK約束來此)。通過這樣做,你將消除一半的元組。

如果因爲要建模完整圖表而遇到性能問題,請考慮僅使用上表中的「鄰居」連接,計算圖的完成並將其插入包含所有項的分區的表中,每個完整子圖有一個分區:

(int)partition | (int)id 

讓我們來看一個例子。給定項目(1..8)和邊緣(1,2),(1,3),(4,3),(6,5),(6,7) - 不包括所需的邊緣完成圖表,你

(int)id | (int)related 
     1 |   2 
     1 |   3 
     3 |   4 
     5 |   6 
     6 |   7 

(並與項目8沒有記錄)

然後在分區表:

(int)partition | (int)id 
      1 |  1 
      1 |  2 
      1 |  3 
      1 |  4 
      2 |  5 
      2 |  6 
      2 |  7 
      3 |  8 

要檢查的項目是另一項只會是分區表上的自連接,但更改圖需要操作兩個表。

+0

假設我插入了一條ID爲10的記錄,該記錄應該與記錄1相關,記錄2與記錄2相關。已經有(1,2),(2 ,1)元組,我需要插入(1,10),(10,1),(2,10),(10,2)。反之亦然:刪除記錄2時,我需要刪除4個項目。這應該很簡單:'刪除關係WHERE id = 2 OR related = 2'。但如何插入元組? –

+0

所以邊緣總是非定向的? – mzedeler

+0

是的,圖形總是完整的 –

0

正如mzedeler所說,通常使用連接表來實現多對多關係。請考慮使用一個單獨的ID列,所以你會得到

Id,rel1,rel2 

這樣的框架,如休眠會知道該怎麼做。考慮到你正在談論一個傳遞和對稱關係的事實,這更有意義。因此,對於4個相關項目,如果您的腳本進行了一些基本推理,那麼3個條目就足夠了當然,如果連接條目被刪除,您需要填補給定關係鏈中的空白。