2012-01-27 95 views
1

我有一個獨特的用戶名和一串字符串數據我跟蹤。每個用戶將有1000行,當我選擇它們時,我想按照它們添加的順序返回它們。在下面的代碼這樣做的必要和正確的方法:SQLite:訂購我的選擇結果

CREATE TABLE foo (
    username TEXT PRIMARY KEY, 
    col1 TEXT, 
    col2 TEXT, 
    ... 
    order_id INTEGER NOT NULL 
); 

CREATE INDEX foo_order_index ON foo(order_id); 

SELECT * FROM foo where username = 'bar' ORDER BY order_id; 

回答

1

如果每個用戶將有1000行,那麼用戶名不應該是主鍵。一種選擇是使用所有表具有的int標識列(由於它通常按照該順序存儲,因此優化了I/O讀取)。

閱讀下「的ROWIDs和整數主鍵」 @http://www.sqlite.org/lang_createtable.html

在SQLite的每個表中的數據被存儲爲包含每個錶行中的條目的B樹結構 ,使用ROWID值作爲 的關鍵。這意味着通過rowid檢索或排序記錄的速度很快。

因爲它是按照B樹結構的順序存儲的,所以按int主鍵排序應該很快。 確保它是rowid的別名,儘管 - 在該文章中更多。

此外,如果您要查詢哪裏的用戶名='bob',您應該考慮用戶名列上的索引 - 特別是會有很多用戶因爲高選擇性而使索引生效。相比之下,在像1和0這樣的值列上添加索引僅導致選擇性低,並且使索引非常無效。所以,如果你有3個用戶:)這是不值得的。

+1

如果沒有指定主鍵,我會看到rowid自動成爲自動增量'主鍵'。我從表中刪除了PRIMARY KEY和order_id,並通過rowid執行select * from table order並獲得我想要的!謝謝。 – Mark 2012-01-28 16:54:09

2

添加DateAdded領域,其默認的日期/時間加入該行的和排序上。

如果你絕對必須使用order_ID,我不建議。那麼至少讓它成爲一個身份專欄。我建議不要這樣做的原因是因爲你依靠副作用來做你的排序,它會讓你的代碼更難閱讀。

+0

由於int的上界,你不推薦它的原因是什麼? – Ilion 2012-01-27 03:01:17

+1

否。如果您想跟蹤輸入日期,您可以使用適當命名的日期字段。在您跟蹤OrderID後,明確建模它應該只是一個唯一的ID,而不是用於獲取訂單年表的雙重目的方式。 – JohnFx 2012-01-27 03:06:42

0

您可以完全刪除order_id列&索引(除非您需要它們以外的其他內容)。

SQLite表總是有一個整數主鍵 - 在這種情況下,你的用戶名列默默地被做成一個唯一的鍵,所以表只有一個整數主鍵。關鍵列被稱爲rowid。爲了您的排序目的,您需要明確地使其成爲AUTOINCREMENT,以便每一行的rowid總是比舊行更高。

你可能想閱讀http://www.sqlite.org/autoinc.html

CREATE TABLE foo (
    rowid INTEGER PRIMARY KEY AUTOINCREMENT, 
    username TEXT UNIQUE KEY, 
    ... 

那麼你的選擇成爲這種做法的

select * from foo order by rowed; 

一個優點是,你重新使用SQLite就已經被上放置索引你表。 date或order_id列將意味着一個額外的索引,這只是在這裏開銷。