2012-12-22 66 views
7

所以我有一個有趣的問題,我不確定是否被認爲是'黑客'。我查看了一些問題,但沒有找到重複的東西,所以在這裏。基本上,我需要知道這是不可靠還是被認爲是不好的做法。有問題的SQL練習 - 按ID而不是創建時間

我有一個非常簡單的表,具有唯一的自動遞增ID和created_at時間戳。 (我的問題的簡化版本,以澄清有關的概念)

+-----------+--------------------+ 
| id  |created_at   | 
+-----------+--------------------+ 
| 1   |2012-12-11 20:35:19 | 
| 2   |2012-12-12 20:35:19 | 
| 3   |2012-12-13 20:35:19 | 
| 4   |2012-12-14 20:35:19 | 
+-----------+--------------------+ 

這兩列的動態添加,因此可以說是一個新的「插入」將總是有較大的ID和ALWAYS有一個更大的日期。

目的 - 非常簡單地抓取通過created_at下令結果降序排列

解決方案的一個 - 查詢按日期順序降序排列

SELECT * FROM tablename 
ORDER BY created_at DESC 

解法 - 按ID降序排列的查詢

SELECT * FROM tablename 
ORDER BY id DESC 

解決方案二被認爲是不好的做法?或者解決方案二是做事的正確方式。任何關於你的推理的解釋都會非常有幫助,因爲我試圖理解這個概念,而不僅僅是簡單地得到答案。提前致謝。

+0

那麼,按id排序可以並將利用索引。您應該將相關部分的模式包含到問題中。 – Perception

+0

雖然我不知道是否有'官方的方式'去解決這個問題,'order by'查詢的存在就是爲了做到這一點。按列排序。我看到的唯一缺點是,時間戳可能有重複(兩個插入在同一秒內),並且由於缺少索引,查詢可能會變慢。 – ATaylor

回答

6

在典型的實踐中,您幾乎總是可以假定autoincrement id可以按照創建順序(任一方向)進行排序以爲您提供記錄。但是,您應該注意,根據您的數據,這不被視爲可移植。您可能會將數據移動到另一個系統,其中密鑰被重新創建,但created_at數據是相同的。

實際上這個問題其實很不錯StackOverflow discussion

基本總結是第一個解決方案,通過created_at排序,被認爲是最佳實踐。但是,請確保正確地索引created_at字段以提供最佳性能。

+0

感謝您參與討論的鏈接,我的研究 –

+2

+1中考慮到以後會發生什麼事情,一定是錯過了它。 – Javier

+0

爲什麼downvote?我喜歡至少看到未來參考的解釋。 – davidethell

4

這兩種選擇之間有一些差異。


首先是他們可以給出不同的結果。

created_at的值可能受服務器上的時間調整影響,但id列不受影響。如果時間向後調整(通過時間同步軟件手動或自動調整),則可以獲取稍後插入的記錄,但插入先前插入的記錄之前的時間戳記。在這種情況下,您將根據您訂購的列獲得不同的訂單。您認爲哪種訂單「正確」取決於您。


二是表現。 ORDER BY您的clustered index可能會更快。

聚集索引如何加快查詢

通過聚簇索引訪問行是快的,因爲行數據是在索引搜索會導致在同一頁上。

默認情況下,聚簇鍵是主鍵,在你的情況下,它可能是id列。您可能會發現ORDER BY idORDER BY created_at稍快。

+0

MySQL不關心聚簇索引。 InnoDB表不可能在創建順序中存儲記錄。 – Javier

+0

@Javier:謝謝你的評論。我已經添加了關於聚簇索引的文檔的鏈接,並從文檔中引用。 –

+0

哼哼......我站好了。他們必須已經進入InnoDB實施,而我沒有看。 – Javier

3

主鍵,尤其是代理類型的主鍵通常不代表任何有意義的數據,只是它們的功能是允許唯一可識別的記錄。由於這種情況下的日期確實表示有意義的數據,它的主要功能之外的意義我會說根據日期排序是一個更合乎邏輯的方法。

3

訂單id訂單插入訂單。

如果您有插入可能會延遲的用例,例如批處理,那麼您必須按照created_at的順序按時間排序。

兩者都可以接受,如果他們滿足您的需求。

5

除了唯一標識行之外,您不應該依賴ID進行其他任何操作。這是一個任意數字,只是恰好與創建記錄的順序相對應。

說你有這個表

ID creation_date 
1 2010-10-25 
2 2010-10-26 
3 2012-03-05 

在這種情況下,ID而不是CREATION_DATE作品排序。

現在將來你會意識到,哦,哎呀,你必須將記錄ID#2的創建日期更改爲2010-09-17。您的各種使用ID現在報告以相同的順序記錄:

1 2010-10-25 
2 2010-09-17 
3 2012-03-05 

即使與新的日期,他們應該是:

2 2010-09-17 
1 2010-10-25 
3 2012-03-05 

短版:使用數據列的目的,他們創建。不要依賴數據的副作用。