我需要生成yyyyMMddxxxxxx格式的订单号,其中xxxxxx是午夜以来的订单数。
例如20120821000004是2012年8月21号的第四个订单。每秒最多可以创建5个订单,因此这是一个性能考虑因素。
一个显而易见的解决方案是执行类似于以下操作的操作,以查找要递增的最新订单:
SELECT MAX (id) FROM table_name WHERE id LIKE '2012-08-21%'但这很可能会遇到性能问题。
我已经探索过的另一个选项是创建一个序列,用于驱动number组件并使用插入触发器。这种方法的问题是,您需要一些安全的方法来在一天开始时将序列滚动到零,这可能会导致冲突/竞争条件,如果序列没有在午夜整点重置。
有没有什么技巧可以让我在Oracle中使用它,使其无懈可击,同时又具有良好的性能?
发布于 2012-08-21 09:34:08
如果您只打算在SQL中执行此操作,而不使用任何外部实用程序,我可能会保留两个表:
第一个表将用于生成单调递增的唯一ID值。第二个表将用于跟踪从第一个表到每日ID的每日偏移量。将在当天的第一个订单上插入一行,该行将是第一个表中的日期和最高ID。然后,可以通过从第一个表中提取的新ID减去第二个表中的ID偏移量来计算订单ID。
您可以考虑使用整数绝对订单ID在内部跟踪DB中的订单,并仅使用日期/偏移量数据来动态或作为交叉引用生成日期和每日订单编号等人类友好的信息。
发布于 2012-08-21 09:18:55
你可以为每一天生成一个新的序列。给它们起一个有意义的名字,比如'order_seq_20120821‘。
这不是什么java问题,客户端不能处理数据库并发。
发布于 2012-08-21 09:01:46
这并不是专门的Oracle解决方案,但我正在考虑有一个包含三列的order numbers表: date、xxxxxx (作为int)和order number。
将索引保存在(date,xxxxxxx)上。现在,按如下方式执行查询:
select max(id) from OrderNumbers where date = <date>这将使用索引,并应加快操作。
另一个想法是保留一个类似的表,但仅用于当前日期。在这个版本中,您将有一个序列/自动增量列自动生成xxxxxx。然后,您可以使用触发器来计算订单号,并取回最后插入的值以创建新的订单号。这可能是最快的方法,特别是在考虑锁定数据的问题时。
https://stackoverflow.com/questions/12046941
复制相似问题