2014-01-07 25 views
0

這是一個比一對多連接更復雜的想法。我有一堆像照片,帖子,用戶等可以評論的表格。我的意見表中包含3個字段,可以幫助識別評論:一個相當複雜的自動增量

item-id - 評論屬於
table項目的ID - 這item-id的第(保存爲一個整數表,但顯示如下名稱,以避免混亂)
id - 評論的ID,相對於item-id

一種更好的理解示例:

id item-id table 

1 1  photos 
2 1  photos 
1 1  posts 
2 1  posts 
1 2  posts 
1 1  users 

現在的問題是插入。我覺得很難確定當前的最後一個ID。鑑於上面的表格,如果用戶要對item-id = 1的照片發表評論,那麼新評論需要有一個3的ID。唯一能想到的方式是在插入時運行子查詢,但我是不是一個子查詢的粉絲。有沒有建立在MySQL的一些機制,可以幫助我實現這一點,或任何其他簡單而強大的方式?

+2

對每個父代使用「自然外觀」序列(如1-2-3)的優勢是什麼,而不是僅僅依賴數據庫服務器提供的序列?好的,這些會變得更大,並且它們不會像1-2-3那麼整齊,但它們快速,堅固並且保證能夠防碰撞? – fvu

+1

當我將表名稱看作列時,我想從這樣的架構中逃離 –

+0

此架構設計在試圖確定該ID時會遇到競爭條件,以及如果刪除了某個帖子會發生什麼情況,這些數字是否都會遞減?我的直覺是,模式設計立即需要改變以不同的方式滿足需求,例如是什麼推動了這種連續數字的需求,而不是使用時間戳來提供評論的排序? – Andrew

回答

1

MyISAM allows you to do this easily

對於MyISAM和BDB表,您可以在多列索引中的 輔助列上指定AUTO_INCREMENT。

但是,它僅限於兩列,所以您仍然需要將其歸一化以刪除其中一列。

否則,你可以插入下一個用戶(第1項)排這樣的:

INSERT INTO table1 (id, `item-id`, `table`) 
SELECT MAX(id) + 1, 1, 'users' FROM table1 WHERE `item-id` = 1 AND `table` = 'users' 

把它擴大一點,在IFNULL一部分,還可以使用相同的條款插入的第一行。

INSERT INTO table1 (id, `item-id`, `table`) 
SELECT IFNULL(MAX(id), 0) + 1, 2, 'users' FROM table1 WHERE `item-id` = 2 AND `table` = 'users' 

在這種情況下,您可能會有一個多列主鍵,由所有三列組成。

2

你應該考慮一件事,爲什麼這對你很重要?一個ID的目的是成爲一個唯一的標識符。當然,它可以代表順序,因爲它是單調遞增的,但是對於每對(item-id, table)而言,是否有任何理由必須從1到2變爲3?如果它是1,6,20,它會是有害的嗎?

如果你使用PHP,你仍然會收到以相同的順序數據,並在PHP這將是很容易的知道哪個是1,2和3

+0

我已經想出了這個,因爲害怕獨特的ID用完了。我知道mysql可以存儲的最大整數值是1 * 10到19,這是一個可笑的大數字,但不是無限的。以及巨大的數字佔用更多的空間?這真的是一個難題。 –

+0

所以只需使用'insert。 。 。選擇'語法。無論如何,它更加靈活。 –

+1

在您點擊10^19條目之前,您將遇到很多其他問題需要解決。該數量的標稱20字節行將約爲170 Exabytes。 – Andrew

2

從您的評論:我想出這個的,因爲唯一的ID跑出來的恐懼

。我知道mysql可以存儲的最大整數值是1 * 10到19,這是一個可笑的大數字,但不是無限的。以及巨大的數字佔用更多的空間?

MySQL的簽名INT類型可以達到2 -1。一個無符號的INT可以達到2 -1,這是4,294,967,295。

你說得對,這不是無限的,但42億是相當高的,並且很容易處理大多數需求。

您還可以使用帶符號或無符號的BIGINT,它是8個字節,是INT大小的兩倍,但如果您需要的值大於INT,則必須存儲它們。

無符號BIGINT上升到2 -1或18,446,744,073,709,551,615。即使您每小時多次重新加載整個數據庫,您實際上也確實不太可能在您的一生中耗盡這些值。


重新發表您的評論。

是的,大多數數據類型是固定大小的,這意味着它們在每一行上都使用相同的字節數,而不管您在任何給定行中存儲的值如何。原因是你可以稍後改變這個值,如果MySQL必須找到更多的空間來將一個小的數值增長到一個大的數字值,那麼這會導致其他類型的性能問題。

有關MySQL用於每種數據類型的字節數的更多信息,請參閱http://dev.mysql.com/doc/refman/5.6/en/storage-requirements.html

異常是一些字符串數據類型(VARCHAR,VARBINARY,TEXT,BLOB),根據您實際使用的字符串的長度,每行使用可變數量的空間。

但是沒有數字日期/時間 MySQL中數據類型的大小有所不同。

另一種評論:你應該問問自己,你花了多少時間來優化這個功能,以及只是爲了獲得更大的磁盤是否更經濟。如果你有一個大型的數據庫,每個整數每行增加4個字節是合理的,但是在它真正重要之前你需要存儲數十億行。

+0

就像一個側面的問題,如果我將該列定義爲BIGINT而不是INT,那麼在INT限制之前是否會有更多空間保留用於數字?換句話說,保存爲BIGINT的數字'5'會佔用比INT保存的相同數量更多的空間嗎? –

+0

非常感謝您提供的詳細信息和建議,Karwin先生! –