我是怎么設計一個訂單號生成策略的(庫存系統)

我是怎么設計一個訂單號生成策略的(庫存系統)


一、背景

最近我在做一套自研的庫存管理系統,其中有一個看似簡單、實則很關鍵的功能:訂單號生成策略

訂單號不僅要全局唯一,還要有一定的可讀性業務含義,比如能一眼看出是入庫單還是出庫單、是哪個用戶、什么時間生成的。這樣在后續查日志、對賬、排查問題的時候才更方便。

市面上雖然有很多現成的 ID 生成方案,比如 UUID、Snowflake、Leaf 等等,但它們都有一個共同的問題:沒有業務語義

比如這個訂單號到底是入庫單還是出庫單?用戶是誰?哪天生成的?看不出來。

所以,我決定自己設計一個訂單號生成策略,結合 Redis、時間戳、業務標識和用戶信息,實現一個既唯一、又可讀、還易維護的方案。


二、我遇到的問題

在設計過程中,我遇到了幾個關鍵問題:

  1. 如何保證訂單號全局唯一?
  2. 怎么讓訂單號有業務含義?
  3. 如何支持分布式部署?
  4. Redis 生成自增ID會不會成為瓶頸?
  5. 如何避免 Redis Key 堆積?

帶著這些問題,我開始一步步設計我的訂單號生成邏輯。


三、我是怎么做的?

我最終設計了一個訂單號結構如下:

[業務碼][機器碼][用戶碼][日期][自增ID]

每個字段的含義如下:

字段長度示例說明
業務碼2位RK、CK入庫(RK)、出庫(CK)
機器碼2位01、02表示部署節點
用戶碼6位000123用戶ID后6位
日期8位20250719格式為YYYYMMDD
自增ID6位000001每天從1開始遞增

示例訂單號:

RK0100012320250719000001
  • RK:入庫訂單
  • 01:機器編號
  • 000123:用戶ID后6位
  • 20250719:訂單生成日期
  • 000001:當天該用戶該業務類型的第一個訂單

四、技術實現細節

1. 使用 Redis 生成自增ID

我用 Redis 的 INCR 命令來生成每天的自增ID,Key 的格式如下:

order:${businessType}:${date}:${userCode}

例如:

INCR order:RK:20250719:000123

這樣可以保證:

  • 同一用戶、同一天、同一業務類型的訂單號唯一
  • 每天自動重置計數,避免ID無限增長

2. Java 實現代碼

public class OrderNoGenerator {private RedisTemplate<String, String> redisTemplate;public OrderNoGenerator(RedisTemplate<String, String> redisTemplate) {this.redisTemplate = redisTemplate;}public String generateOrderNo(String businessType, int machineId, long userId) {// 1. 業務類型(2位)String bizCode = businessType;// 2. 機器ID(2位)String machineCode = String.format("%02d", machineId);// 3. 用戶ID(6位)String userCode = String.format("%06d", userId % 1000000); // 截取后6位// 4. 當前日期(8位)String dateCode = LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE);// 5. Redis 自增ID(6位)String redisKey = String.format("order:%s:%s:%s", bizCode, dateCode, userCode);Long incrId = redisTemplate.opsForValue().increment(redisKey);String incrCode = String.format("%06d", incrId);// 6. 組裝訂單號return bizCode + machineCode + userCode + dateCode + incrCode;}
}

3. Redis Key 管理與清理

為了避免 Redis Key 無限增長,我加了一個定時任務,每天凌晨清理前一天的 Key:

@Scheduled(cron = "0 0 0 * * ?")
public void clearYesterdayOrderKeys() {String yesterday = LocalDate.now().minusDays(1).format(DateTimeFormatter.BASIC_ISO_DATE);Set<String> keys = redisTemplate.keys("order:*:" + yesterday + ":*");if (keys != null && !keys.isEmpty()) {redisTemplate.delete(keys);}
}

五、難點與優化點

難點:

  1. 如何保證訂單號唯一性?
    答案是:Redis + 業務類型 + 時間 + 用戶ID組合,保障唯一。

  2. 如何避免 Redis 成為瓶頸?
    Redis 的 INCR 是原子操作,性能很好,但為了進一步優化,也可以采用“分段緩存”機制,比如一次取100個ID本地緩存使用。

  3. 如何讓訂單號具備可讀性?
    通過字段拼接,讓訂單號包含業務類型、用戶、時間等信息,方便日志追蹤。

優化建議:

  • 分段自增機制:減少 Redis 調用頻率
  • 用戶ID壓縮算法:如 CRC32 或 MurmurHash,生成更短的用戶碼
  • 日志與監控:記錄生成的訂單號,異常時自動報警
  • 多機部署支持:通過機器碼區分不同節點,避免沖突

六、實際效果如何?

這套訂單號生成策略在我們系統中上線后,運行穩定,效果不錯:

  • 訂單號唯一性得到保障,未出現重復
  • 日志追蹤、對賬、排查問題都變得容易
  • Redis 性能良好,未出現瓶頸
  • 支持多節點部署,適配分布式環境

七、總結

通過結合 Redis 自增ID、業務標識、時間戳和用戶信息,我實現了一個適合庫存系統的訂單號生成策略,具有以下優勢:

優勢說明
唯一性強Redis + 時間 + 用戶 + 業務組合保障
可讀性高能看出訂單類型、用戶、時間等信息
結構清晰易于日志追蹤和調試
分布式支持機器碼支持多節點部署
易于維護支持定時清理、日志記錄、異常監控

如果你也在開發類似的庫存系統、訂單系統或支付系統,不妨參考這套方案。希望這篇文章能對你有所幫助!


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/89783.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/89783.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/89783.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

問津集 #1:Rethinking The Compaction Policies in LSM-trees

文章目錄引言正文結束語引言 陪女朋友出門&#xff0c;我大概有兩個小時左右的空閑時間&#xff0c;遂帶上電腦&#xff0c;翻了下論文列表&#xff0c;選擇了這篇文章做一個簡讀。 因為這一年負責時序系統的存儲引擎和計算引擎演進&#xff0c;而Compaction又是串聯讀寫的核心…

數據產品結構:從數據接入到可視化的完整架構指南

在數據驅動決策的時代&#xff0c;一套高效的數據產品結構是企業挖掘數據價值的基礎。無論是巨頭企業自建的完整體系&#xff0c;還是中小企業依賴的第三方工具&#xff0c;其核心邏輯都是實現 “數據從產生到呈現” 的全鏈路管理。本文將拆解數據產品的五層架構&#xff0c;對…

python學智能算法(二十三)|SVM-幾何距離

引言 前序學習文章中&#xff0c;已經探究了電荷超平面的距離計算方法&#xff0c;相關文章為點與超平面的距離。 在這片文章中&#xff0c;我們了解到計算距離的公式&#xff1a; Fmin?i1...myi(w?xib)F\min_{i1...m}y_{i}(w\cdot x_{i}b)Fi1...mmin?yi?(w?xi?b) 計算…

[每日隨題11] 貪心 - 數學 - 區間DP

整體概述 難度&#xff1a;1000 →\rightarrow→ 1400 →\rightarrow→ 1600 P3918 [國家集訓隊] 特技飛行 標簽&#xff1a;貪心 前置知識&#xff1a;無 難度&#xff1a;橙 1000 題目描述&#xff1a; 輸入格式&#xff1a; 輸出格式&#xff1a; 樣例輸入&#xff1a;…

Elasticsearch 9.x 搜索執行流程(源碼解讀)

1. 搜索執行流程概述 Elasticsearch的搜索執行是一個分布式過程,涉及協調節點和數據節點之間的多階段交互 #mermaid-svg-QGh2GjrUKcs5jzQp {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-QGh2GjrUKcs5jzQp .error…

暑期訓練8

E. G-C-D, Unlucky!題目要求判斷是否存在一個長度為 n 的數組 a&#xff0c;使得p[i] 是 a[0..i] 的前綴 GCDs[i] 是 a[i..n-1] 的后綴 GCD思路前綴 GCD 非遞增后綴 GCD 非遞減首尾 GCD 一致橋梁條件成立對于每個位置 i&#xff0c;gcd(p[i], s[i1]) 必須等于整個數組的 GCD&am…

深入解析Hadoop HDFS高可用性:原理、故障切換與元數據同步

Hadoop HDFS高可用性(HA)概述在分布式存儲領域&#xff0c;Hadoop分布式文件系統(HDFS)作為Hadoop生態系統的核心存儲組件&#xff0c;其高可用性(HA)設計一直是架構師們關注的焦點。傳統HDFS架構中&#xff0c;NameNode作為單一主節點管理整個文件系統的元數據&#xff0c;這種…

Freertos源碼分析:任務創建/刪除

任務創建/刪除流程1.簡介FreeRTOS 中任務創建通過 xTaskCreate() 或 xTaskCreateStatic() 實現。動態創建&#xff08;xTaskCreate&#xff09;會自動分配任務棧和TCB&#xff08;任務控制塊&#xff09;&#xff0c;靜態創建&#xff08;xTaskCreateStatic&#xff09;需用戶預…

warning: _close is not implemented and will always fail

相關問題&#xff1a; 一、undefined reference to _exit undefined reference to ‘end‘ warning: _close is not implemented and will always fail 一、環境&#xff1a; ubuntu24.04實體機、 arm-none-eabi-gcc gcc version 13.2.1 20231009 (15:13.2.rel1-2) 二…

MyBatis之緩存機制詳解

MyBatis之緩存機制詳解一、MyBatis緩存的基本概念1.1 緩存的核心價值1.2 MyBatis的兩級緩存體系二、一級緩存&#xff08;SqlSession級別緩存&#xff09;2.1 工作原理2.2 實戰案例&#xff1a;一級緩存演示2.2.1 基礎用法&#xff08;默認開啟&#xff09;2.2.2 一級緩存失效場…

云服務器搭建自己的FRP服務。為什么客戶端的項目需要用Docker啟動,服務端才能夠訪問到?

簡單回答&#xff1a;在云服務器搭建FRP服務時&#xff0c;客戶端項目用Docker啟動并非必需&#xff0c;而是因為Docker的特性簡化了配置&#xff1a; Docker通過端口映射&#xff08;如-p 本地端口:容器端口&#xff09;能固定項目對外暴露的端口&#xff0c;減少本地端口沖突…

6 STM32單片機的智能家居安防系統設計(STM32代碼+手機APP設計+PCB設計+Proteus仿真)

系列文章目錄 文章目錄 系列文章目錄前言1 資料獲取與演示視頻1.1 資料介紹1.2 資料獲取1.3 演示視頻 2 系統框架3 硬件3.1 主控制器3.2 顯示屏3.3 WIFI模塊3.4 DHT11溫濕度傳感器3.5 煙霧/燃氣傳感器模塊&#xff1a;MQ-23.6 火焰傳感器3.7 門磁模塊MC-38 4 設計PCB4.1 安裝下…

DevOps落地的終極實踐:8大關鍵路徑揭秘!

本文來自騰訊藍鯨智云社區用戶: CanWay當前&#xff0c;DevOps因其能夠降低IT運營成本、提高軟件質量并加快上市時間的能力而在全球范圍內引起廣泛關注。它打破了傳統軟件開發與運營的界限&#xff0c;消除了新功能發布延遲和軟件質量下降的障礙。DevOps通過實施持續集成、持續…

react - 根據路由生成菜單

后端返回菜單的格式menuList:[{index: true,name: "",component: "../views/Home",meta: { title: "首頁", requiresAuth: true,roles:[user]},},{path: "/admin",name: "admin",meta: { title: "管理頁", roles:…

Window延遲更新10000天配置方案

1.點擊"開始"菜單&#xff0c;搜索"注冊表編輯器"&#xff0c;點擊"打開"。2.找到"\HKEY LOCAL MACHINE\SOFTWARE\Microsoft\WindowsUpdate\Ux\Settings"路徑。3.右面空白處右鍵新建一個32位值&#xff0c;命名為FlightSettingsMaxPau…

【OD機試】人民幣轉換

題目描述 將阿拉伯數字金額轉換為中文大寫金額格式,需遵循以下規則: 1、 前綴要求:中文大寫金額前必須標明“人民幣”字樣。 2、 用字規范:使用壹、貳、叁、肆、伍、陸、柒、捌、玖、拾、佰、仟、萬、億、元、角、分、零、整等字樣。 3、 “整”字規則: 金額到“元”為止…

在ajax中什么時候需要將返回值類型做轉換

$.ajax({url: TMSPROC0050/deleteData?accidentIds accidentIds.join(,),type: DELETE,dataType: json,success: function(result) {$(#accidentGrid).datagrid(reload);$.messager.show({title: 成功,msg: result.message})},error: function(result) {$.messager.alert({ti…

Helm常用命令大全(2025最新版)

文章目錄Helm常用命令大全&#xff08;2025最新版&#xff09;一、基礎命令與環境配置版本與幫助信息安裝與升級HelmLinux系統安裝版本升級注意事項二、倉庫管理命令倉庫基礎操作OCI倉庫支持&#xff08;v3.8新特性&#xff09;三、Chart操作命令Chart創建與打包Chart搜索與下載…

gitlab+jenkins

文章目錄架構gitlab和jenkins安裝jenkins配置gitlab配置jenkins與gitlab聯動參考架構 gitlab和jenkins安裝 部署docker 部署jenkins 啟動jenkins 用戶&#xff1a;admin&#xff0c;對應的密碼如下 點擊安裝自定義推薦的插件 安裝gitlab插件 jenkins配置 配置pipline…

Redis字符串操作指南:從入門到實戰應用

Redis作為一款高性能的鍵值存儲數據庫&#xff0c;其字符串&#xff08;String&#xff09;類型是最基礎也最常用的數據類型。它不僅能存儲簡單的文本信息&#xff0c;還能應對數字計算、二進制數據等多種場景&#xff0c;靈活且高效。接下來&#xff0c;我們就全方位剖析Redis…