我正在使用Postgres中的虚拟私有数据库模式开发应用程序。
因此,每个用户都会获得他的id,并且该用户的所有行都将持有此id以与其他用户分离。该id还应成为主键的一部分。此外,每行必须具有在用户范围内唯一的id。这个id将成为主键的另一部分。 如果我们需要跨多个服务器扩展此功能,还可以附加第三列到标识生成此id的碎片的pk中。
我的问题是如何创建每个用户唯一的id。我提出了一些选项,但不确定所有影响。对我来说,最有前途的两个解决方案是:
为每个用户创建一个序列:
可以使用触发器自动完成每次创建用户时的操作。这肯定是事务安全的,而且在性能方面应该也相当不错。 我担心的是,这要处理大量用户(100k +),我不知道Postgres如何处理100k+序列。我试图找出序列的实现方式,但没有成功。
在用户表中使用计数器:
将所有用户保存在一个表中,并保留一个字段,其中包含为该用户提供的最新id。 当用户开始事务时,我可以锁定用户表中的行,并使用用户表中的最新id作为起始值创建一个临时序列。然后可以使用该序列为新条目提供id。 在退出事务之前,必须将当前值写回用户表,并释放锁定。如果同一用户的另一个事务尝试并发插入行,则会停止,直到第一个事务释放对用户表的锁定。 这样,我就不需要成千上万个序列,而且我认为不同用户之间的并发访问不会经常发生(应用程序具有OLTP特性-因此不会有长时间的事务),即使发生这种情况,它也只会停留约一秒钟,不会造成任何伤害。
我的另一个问题是,是否应该只使用2列(或者如果shard_id加入游戏,则使用三列),并将它们组合成复合主键,还是将它们放在一列中。我认为将它们放在单独的列中处理会更容易,但性能如何?假设两个值都是32位整数-在索引中是否有2个int列或1个bigint列更好?
谢谢所有答案, Alex