如果可以按日期标识记录,我是否需要数据库中的ID?


17

我正在为Android编写我的第一个应用程序,它将使用SQLite数据库,因此将尝试尽可能限制大小,但是我认为这个问题通常适用于数据库设计。

我打算存储将包含文本和创建日期的记录。该应用程序是一个独立的应用程序,即它不会链接到互联网,只有一个用户将对其进行更新,因此,在给定的日期,将不会有多个条目。

我的表格还需要一个ID列吗?如果是这样,使用ID作为记录标识符而不是日期有什么好处?


如果您未指定整数PK,则SQLite始终会为rowid创建一个整数列。因此,不要指望没有“ ID”列来节省空间。
Codism 2013年

我将在Android中添加一些类,这些类需要表具有_id列才能工作。有关信息的更多信息。
bigstones 2013年

5
如果您从手机本身获取日期,并且用户走到较早的时区(并且他/她的手机会自动更新时间),则极有可能您会多次获得同一时间戳。
尤金

Answers:


22

恕我直言,最好避免使用日期列作为主键。

我曾在将日期字段用作主键的系统上工作,如果要使用日期字段,编写查询以拉回数据的子集会有些麻烦。

您可能需要考虑的其他几点:

您可能会认为某个时间点是唯一的,但这取决于日期列的粒度。是分钟,秒,毫秒等。您是否可以绝对确定永远不会遇到主键冲突?

最后,如果您希望将数据库迁移到另一个平台,则在两个平台之间日期数据的粒度不同时,您可能会再次遇到问题。

当然,您确实必须在理想与工作目标之间取得平衡。如果真的很需要空间,那么使用date列可能会减少两种危害。那是您必须做出的设计决定。

编辑:

我应该指出,这绝不表示这是一个糟糕的设计决策。只是RDBMS的实用性可能存在问题。


自从我编写SQLite查询以来已经有一段时间了,但是除了绑定值的更详细的声明之外,按日期进行过滤是否与按整数进行过滤相同?
DougM 2013年

它只是比较冗长,而且在某些RDBMS上,您会遇到一个问题,即如果数据库以美国格式设置,则日期和月份元素将被反转。
罗比·迪

谢谢,这些都是很好的答案,但是您的工作经验肯定可以达成协议。
Nieszka 2013年

以此作为后记:直到今天,我才收到应用程序审核表的支持问题,由于两台客户端设备之间存在时差,因此他们遇到了员工编号和访问日期/时间PK的主键冲突。 ..
罗比·迪

13

不,如果您可以保证永远不会有重复的日期,则不必严格要求在架构中定义ID列。

但是 ...

...也就是说,您还是应该使用它。这里的小秘密是,SQLite已经为每个称为ROWID的表提供了唯一的,自动递增的ID。如果您在表格中将自动递增的整数列声明为PK,则SQLite不会创建新列-它将简单地为该预先存在的ROWID列添加别名。

在SQLite中,每个表的每一行都有一个64位带符号整数ROWID。在同一表的所有行中,每一行的ROWID是唯一的。

您可以使用特殊列名称ROWID,ROWID或OID 之一访问SQLite表的ROWID。除非您声明普通表列使用那些特殊名称之一,否则使用该名称将引用声明的列而不是内部ROWID。

如果表包含INTEGER PRIMARY KEY类型的列,则该列将成为ROWID的别名。然后,您可以使用以下四个不同的名称中的任何一个来访问ROWID:上述三个原始名称或为INTEGER PRIMARY KEY列指定的名称。所有这些名称都是彼此的别名,并且在任何情况下都可以很好地工作。

http://www.sqlite.org/autoinc.html

因此,不使用ID列就不会节省任何空间,因为无论您想要与否,每个表都会得到一个!


9

如果满足以下任一条件,请使用ID字段:

  1. 不存在自然键(日期将不是唯一的)
  2. 日期字段将经常更改
  3. 插入时可能不知道日期。
  4. 多列标识符超过三列,这会使连接过于冗长。

阅读以下问题:是否有规范的资料来源支持“所有替代品”?

编辑:

依我看来,以上似乎都不成立,因此您不需要使用和ID字段,但是您可以根据需要使用一个。


1
+1 ID列是模式代码的味道,表示您的数据确实不适合关系模型。
罗斯·帕特森

10
@RossPatterson我不太确定。我可以想到许多情况下可能不存在自然键,但数据仍然可以适合关系模型的情况。我脑海中只有一个案例:存储有关在世人员的信息。许多(并非全部!)国家/地区为每个公民分配了唯一的标识符,但这并不意味着使用该标识符是适当的,甚至可能的(在创建记录时可能不知道,可能未分配或使用它)可能会受到适用法规的禁止)。这是否意味着数据不适合关系模型?我不这么认为。
CVn

还有一点有趣的事实是,在有这种唯一标识符的地方,警察(等等)有时会使用伪造的ID作为伪造ID。而且,如果不是故意的,文书错误也将确保重复。
2013年

4
无论是内置的(甲骨文)还是善意的专栏,它们都非常有用。作为围墙两边的人(DBA和开发人员),对具有ID的表格进行重复数据删除要容易得多,您可以保证ID是唯一的。
罗比·迪

1
@RobbieDee你是对的。这不是主题。
图兰斯·科尔多瓦

2

请记住,您可能还希望将“ date”列的含义从更改created_atupdated_at或沿这些行进行任何其他更改,我发现这是非常常见的情况。

在某些情况下,添加id列将在您更改设计时为您提供更大的灵活性。


+1在表中添加date_created和date_modified对于跟踪何时创建和更新行非常有用。在调查存储库/数据仓库更新问题时,这是值得的。
罗比·迪
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.