2012-07-31 20 views
4

我今天上午搜索了一個自己問自己的問題,但是找不到任何有關它的信息或文章。關於MySQL的理論情況

我想知道,在下列情況下,爲了提高性能(有點%仍然):

語境:我有兩個列:IDAddedAtAddedAt是當行的Unix時間戳創建)。

理論上,如果插入新行,ID將爲+1,而AddedAt將爲當前時間。

現在,假設在當前情況下不可能同時插入兩個,那麼使用AddedAt作爲PK並刪除ID列會更好嗎? AddedAt將只是一個並且是PKUNIX Timestamp的唯一列。所以在決賽中,我會有一列而不是兩列。

我看到的唯一不好的一面可能是將在AddedAt上創建的密鑰的大小,因爲unix時間戳現在是10位數字。

在這種情況下會更好嗎?你怎麼看 ?

編輯:怎麼樣使用時間戳+毫秒?

回答

4

時間戳以秒爲單位。雖然您可能沒有同時插入,但隨着世界趨於加速,您可能會在一秒鐘內插入多個插入。建立你的系統以正常工作 - 不要使用timesamps作爲主鍵。

此外,語句複製某些時間戳在整個dbs中是不一致的......基於行的複製緩解了這一點,但仍然是使用它們時需要關注的另一個原因。

從良好的約定的角度來看,主鍵應該對自己以外的其他人有一些明確的含義,如果它不是我們簡單的舊自動遞增ID字段。通常,人們期望鍵的數字或字符值,而不是像blob,時間戳,日期時間等的東西......如果以後它被用作另一個表中的外鍵,使用時間戳作爲外鍵可能會令人困惑給後來的開發者。當然,如果你有一個varchar GUID字段,你知道它是唯一的,那麼將它用作關鍵字。只要記住,當用作外鍵時,如果你有一個巨大的字符串,你也會吃掉很多內存。

2

假設您可以保證兩個事件不會在相同的1秒間隔內發生,那麼當然可以使用時間戳字段作爲PK。

這就是說,你爲什麼擔心密鑰大小?時間戳可能是10位數字,但其內部存儲要求僅爲4 bytes。相比之下,int也是4個字節,所以你不會丟失任何東西 - 除非你使用bigint,在這種情況下它是8個字節。

此外,請注意時間戳字段受y2038k問題。它們基本上是unix時間戳,可以自動格式化爲您可讀的日期。如果你的應用程序將在26年以上,那麼你應該堅持一個int/bigint,它具有「插入行數不管多快」的範圍,而不是固定的日期/時間。

+0

如果系統使用64位整數,y2038k問題不再是一個了,對吧? – 2012-07-31 14:29:56

+0

不,因爲無論底層操作系統如何,mysql時間戳字段都是4個字節。操作系統中的time_t可能是64位,但mysql是4字節,並且保留4個字節。 – 2012-07-31 14:30:47

+0

正如我上面所說的,int是4個字節,int大小是8.時間戳是4個字節,不管底層操作系統的位能力如何。 – 2012-07-31 14:39:34

0

我將離開ID列作爲主鍵,因爲可能會出現這樣的情況,其中unix時間戳會給您一個您不期望的值。一個可能會連續插入非常快的返回相同的時間戳,另一個是如果服務器管理員決定使用服務器時間設置。

做連接可能會更加明顯,因爲人們通常期望主鍵是某種唯一的ID,而不是時間戳。

0

是的,當然,但只有在增加新記錄時,性能增益纔會很小。 此外,您將被迫在所有相關對象中使用foreign_keys的時間戳。

只有當您期望每秒插入很多記錄(以保存id列和其索引中的存儲空間)時,才值得考慮,但正如您所說,時間戳將是唯一的,因此它每秒最多記錄1條記錄: - )

1

主鍵不僅僅是一個技術性的東西,它是一些東西的業務表示,使每個對象由一行代表唯一。

時間戳是對象的唯一字段,因爲您不能(在您的情況下)同時插入兩個對象,但它不是業務對象的主要定義(如果您有一個名爲「timestamp 「那麼是的,它被插入的時間應該是主鍵)

ID代表」我的客戶有一個物理ID代表他「:在過去,我們會給客戶在紙上,賬單上的號碼...

永遠不要忘記,計算機科學本身不是目標,而是達到目標的手段。

+0

我喜歡你如何在業務對象和簡單的時間戳之間建立關係,這是一種很好的方式來表示在任何情況下ID更好的原因。我喜歡。 +1 – 2012-07-31 14:41:16