2012-01-27 64 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列将意味着一个额外的索引,这只是在这里开销。