在 PostgreSQL 中为供应商生成连续且不同的订单号

问题描述 投票:0回答:1

我正在分布式系统中开发一个电子商务应用程序,其中多个服务器与 PostgreSQL 数据库交互。我需要为每个供应商实现一个订单号计数器,以确保每个供应商都有自己唯一的增量订单号。

每个供应商都有不同的订单号序列,例如供应商 1 的订单编号为 1、2、3...,供应商 2 的订单编号也为 1、2、3...。这些订单号与数据库 ID 无关并为每个供应商按顺序生成。

我考虑过使用序列和触发器,但我真的不知道这是否是正确的方法。我也听说过乐观锁并且可以提供帮助,但我不熟悉实现,我担心锁定数据库会导致一些性能问题或者需要创建乐观锁故障处理程序。 这就是 SQL 数据的样子:

CREATE TABLE vendors (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL);

CREATE TABLE orders (
id SERIAL PRIMARY KEY,
order_number INT NOT NULL,
vendor_id INT REFERENCES vendors(id));

那么有没有办法做到这一点?

postgresql concurrency distributed-computing optimistic-locking
1个回答
0
投票
每个供应商的

有效序号

为此,您需要一个

view

:如果您尝试仅通过插入时建立的默认值(自动数据库端或手动客户端)来保护编号的一致性,那么单个删除、更新或非默认插入可能会破坏这种一致性:

    A
  • delete
     在供应商的订单顺序中引入了间隙 - 您说这对您来说不是问题,但仍然是可以避免的。
  • 某人可以
  • update
    订单,将其重新分配给另一个供应商或在同一供应商内明确更改其编号。在这两种情况下,
    order_number
    都会与另一个未来或现有的自动编号订单发生冲突。
  • 可以明确地
  • insert
    编号无效、无序的顺序。根据您设置默认值的方式,
    OVERRIDING SYSTEM VALUE
    子句
    甚至可能没有必要。
视图可以使用

row_number()

窗口函数
计算截至查询时间的当前有效顺序,按 vendor_id
:
分区

CREATE TABLE orders ( id SERIAL PRIMARY KEY, vendor_id INT REFERENCES vendors(id), some_other_column TEXT); CREATE TABLE v_orders AS SELECT *,row_number()over(partition by vendor_id order by id) AS order_number FROM orders;


每个供应商

顺序标识符

如果这些只是您希望每个供应商连续且唯一的标识符,那么这与保持最新的缓存组计数非常相似(

示例)。标准方法在这里没有帮助:

  • id serial
    
    
  • id int generated by default as identity stored
    
    
  • id int default nextval()
    
    
它们都使用与

id

 列相关的单个通用序列。解决方法是使用一个接受 
vendor_id
 作为“种子”的函数,并为每个不同的种子维护单独的序列,并基于此返回足够的 
nextval()
。或者,维护一个单独的表来保存每个供应商的最新 ID。

© www.soinside.com 2019 - 2024. All rights reserved.