4

我在谷歌上搜索了一个从今天早上开始就问自己的问题,但找不到任何关于它的信息或文章。

我想知道,在以下情况下,提高性能(仍然有一点):

上下文:我有两列:IDAddedAtAddedAt是创建行时的 Unix 时间戳)。

理论上,如果您插入一个新行,ID将是 +1 并且AddedAt将是当前时间。

现在,假设在当前情况下不可能同时插入两个,将其AddedAt用作 aPK并删除ID列会更好吗?AddedAt将只是一个唯一的列,PK并且UNIX Timestamp。所以在决赛中,我将只有一栏而不是两栏。

我看到的唯一不好的一面可能是将创建的密钥的大小,AddedAt因为现在的 unix 时间戳是 10 位数。

在这种情况下会更好吗?你怎么看 ?

编辑:使用时间戳+毫秒怎么样?

4

5 回答 5

4

时间戳以秒为单位。虽然您可能没有同时插入,但随着世界趋于加速,您可能会在一秒钟内获得多个插入。构建您的系统以使其正常运行——不要使用时间采样作为主键。

此外,由于语句复制有时时间戳在 dbs 之间不一致......基于行的复制缓解了这一点,但在使用它们时仍然是另一个值得关注的原因。

从一个好的约定的角度来看,如果主键不仅仅是我们一个普通的旧自动递增 id 字段,那么它应该对你以外的其他人有一些明确的意义。通常,人们期望键的数字或字符值,而不是诸如 blob、时间戳、日期时间等之类的东西……如果稍后将其用作另一个表中的外键,则尤其如此,使用时间戳作为外键可能会造成混淆给后来的开发者。当然,如果您有一个您知道是唯一的 varchar GUID 字段,请将其用作键。请记住,当用作外键时,如果您有一个巨大的字符串,您也会消耗相当多的内存。

于 2012-07-31T14:22:49.833 回答
2

假设您可以保证两个事件不会在相同的 1 秒间隔内发生,那么当然,您可以将时间戳字段用作 PK。

话虽如此,您为什么担心密钥大小?一个时间戳可能是 10 位,但它的内部存储要求只有4 个字节。相比之下,一个 int 也是 4 个字节,所以你不会丢失任何东西 - 除非你使用 bigints,在这种情况下它是 8 个字节。

另外,请注意时间戳字段会受到 y2038k 问题的影响。它们本质上是 unix 时间戳,可以为您自动格式化为人类可读的日期。如果您的应用程序将存在超过 26 年,那么您应该坚持使用 int/bigint,它具有“插入行的速度”的环绕范围,而不是固定的日期/时间。

于 2012-07-31T14:21:43.367 回答
1

主键不仅是一种技术性的东西,它还是某种事物的业务表示,它使行所表示的每个对象都是唯一的。

时间戳是对象的唯一字段,因为您不能(在您的情况下)同时插入两个对象,但它不是业务对象的主要定义(如果您有一个名为“时间戳”的业务对象,那么是的,插入的时间应该是主键)

ID 代表“我的客户有一个代表他的物理 ID”:过去,我们会在文件、账单...

永远不要忘记,计算机科学本身不是目标,而是实现目标的手段。

于 2012-07-31T14:29:03.777 回答
0

我会将该ID列作为主键,因为在某些情况下,unix 时间戳会给您一个您不期望的值。一个可能是非常快速地连续插入返回相同的时间戳,另一个是如果服务器管理员决定对服务器时间设置进行监控。

进行连接可能会更加明显,因为人们通常期望主键是某种唯一的 id,而不是时间戳。

于 2012-07-31T14:21:51.507 回答
0

当然可以,但是只有在添加新记录时,性能提升才会很小。此外,您将被迫在所有相关对象中为 foreign_keys 使用时间戳。

仅当您期望每秒有很多插入和大量记录(以节省 id 列及其索引的存储空间)时才值得考虑,但正如您所说的时间戳将是唯一的,因此每秒最多 1 条记录 :-)

于 2012-07-31T14:22:04.577 回答