更少的桌子比更好吗?

时间:2009-06-27 22:38:31

标签: database database-design sqlite

我正在实施一个小时间跟踪应用程序,我不能在两个数据库设计之间做出决定。

第一个包含单个表中的所有日志条目,即

TimeLog
-------------
job_id   :  long
timestamp
start    :  boolean [or perhaps 'type : enum']
_id      :  long

另一种选择是有两个表,一个用于'开始',另一个用于'停止'条目。

StartLog                     StopLog
-------------                -------------
job_id   :  long             job_id   :  long
timestamp                    timestamp
id      :  long              id      :  long

每种方法的优缺点是什么?还有另一种选择吗?

我的特定应用程序将在SQLite上运行,我想优化它以提高速度 - 但我对通用参数感兴趣。

5 个答案:

答案 0 :(得分:7)

我会选择第一个(单表,类型区分)设计,不是特别因为表太多,而是因为数据库实体非常相似,并且会有类似的约束和操作。

答案 1 :(得分:5)

我会使用第一个设计:单个数据库表。正如Cade Roux所说,实体非常相似,并且会有类似的约束和一组共同的操作。此外,我建议将start字段重命名为type,其数据类型为enum

假设在某些时候你想记录其他时间,而不仅仅是开始和停止时间。最明显的例子是雇主记录员工的休息时间。一些雇主向员工支付短暂休息时间,可能持续15分钟或更短时间。你希望他们完全打出来(即“熄灭”),但你想表明他们已经开始休息时间这一事实,用于工资计算和法律目的(例如,法律要求每n小时强制休息一次)。

Table "TimeLog"
---------------
job_id     :  LONG
timestamp  :  TIMESTAMP
type       :  ENUM [ "punch-in", "punch-out", "break-start", "break-stop" ]
_id        :  LONG

使用数据类型为type的{​​{1}}字段可以轻松完成此操作。在上述示例中,您可以拥有enumpunch-inpunch-outbreak-start

答案 2 :(得分:3)

我认为这取决于您将使用更多的查询。

如果您仅查询开始条目或停止条目的大部分时间,而不是两者,则您将受益于较小的表格大小。

另一方面,如果你在同一个查询中大多使用这两个部分,那么合并结果可能会减慢你的速度。

另外,您确定要优化速度吗?大多数时候,速度不是问题,你应该担心什么方法更有意义。

答案 3 :(得分:3)

第一种选择是迄今为止最好的选择。两个操作(开始/停止)共享公共属性。使用此设计,如果需求发生变化,您将处于更好的位置(例如,如果创建了“取消”操作)。

答案 4 :(得分:0)

在LOGICAL设计层面,毫无疑问“两桌”选项是正确的。

在物理设计水平上,如果经常需要开始/停止时间,您可能会从单桌设计中受益。

你可能想知道为什么要做出这种区分。保持逻辑设计的清晰视图有助于您更好地了解数据库中实际记录的数据类型。在一个表中具有布尔属性并不“明显地”告诉您它是关于开始时间与停止时间的关系。拥有两个不同的“表”(在逻辑层面)可能会更好地完成这项工作,特别是如果他们有“start”resp这个词。在他们的名字中“停止”。

物理设计水平是你必须专注于性能的地方,实现最佳方式通常是为了获得经常一起使用的数据,尽可能在物理上尽可能地靠近(并且很少有相同的东西在一起行)。