在postgres中拥有多个序列有什么不对吗?

时间:2014-05-27 12:37:04

标签: postgresql primary-key sequence sharding composite-primary-key

我正在使用postgres中的虚拟专用数据库模式开发一个应用程序。

因此每个用户都获得了他的id,该用户的所有行都将保持此id与其他用户分开。此id也应该是主键的一部分。此外,每一行都必须具有在用户范围内唯一的id。该id将是主键的另一部分。 如果我们必须在多个服务器上进行扩展,我们还可以在pk中附加第三列,以标识此id生成的分片。

我现在的问题是如何创建每个用户唯一的ID。我提出了一些选项,我不确定所有的含义。对我来说最有希望的两个解决方案是:

为每个用户创建一个序列:

每次创建用户时,都可以使用触发器自动完成此操作。这肯定是交易安全的,我认为它在性能方面应该是相当不错的。 我担心的是,这必须适用于很多用户(100k +),我不知道postgres将如何处理100k +序列。我试图找出如何实现序列,但没有运气。

用户表中的

计数器:

将所有用户保留在一个表中,其中的字段包含为此用户指定的最新ID。 当用户启动事务时,我可以锁定用户表中的行,并使用用户表中的最新id作为起始值创建临时序列。然后,此序列可用于为新条目提供ID。 在退出事务之前,必须将当前值写回用户表并且必须释放锁。 如果来自同一用户的另一个事务尝试同时插入行,它将停止,直到第一个事务释放其对用户表的锁定。 这样我就不需要成千上万的序列了,我认为不会经常从一个用户进行并发访问(应用程序有oltp字符 - 因此不会有持久的事务),即使发生了这种情况,也只会停止大约一秒钟,没有伤害任何东西。

我的问题的第二部分是我应该只使用2列(如果shard_id加入游戏,可能是3列)并使它们成为复合pk,或者我应该将它们放在一列中。我认为处理将更容易在单独的列中使用它们但性能如何?让我们假设两个值都是32位整数 - 在索引或1个bigint列中有2个int列更好吗?

所有答案都是, 亚历

1 个答案:

答案 0 :(得分:4)

我不认为序列可以扩展到你想要的水平(100k序列)。序列实现为其中只有一行的关系。

每个序列都将出现在系统目录(pg_class)中,该目录还包含所有表,视图等。拥有100k行肯定会大大降低系统速度。保存与这些序列关系相关的所有数据结构所需的内存量也很大。

如果与临时序列结合使用,您的第二个想法可能更实用,可能更具可扩展性。

对于你的第二个问题,我认为复合键不会比单个列键差,所以我会选择与你的功能需求匹配的任何东西。