3. 数据模型设计:货架数据结构定义、状态枚举与模拟数据生成
好,咱们进入第三个环节。说实话,很多初学者一上来就急着写界面、画图表,结果做到一半发现数据对不上、状态乱套了。我个人的习惯是——先把数据模型想清楚,再动手写代码。这就像盖房子,地基没打好,后面全是坑。
这一章,我们就来定义货架的数据结构,明确状态枚举,再生成一批模拟数据。嗯,内容不多,但很关键。
3.1 货架数据结构:到底要存哪些信息?
先问一个问题:一个货架,在系统里应该长什么样?
你想想看,我们做的是「货架状态可视化」,那至少得知道:
- 这个货架在哪?(位置信息)
- 它现在是什么状态?(满/空/缺货)
- 它放的是什么商品?(品类)
- 它最多能放多少?现在有多少?(容量数据)
我在项目中遇到过一种情况:有人把货架编号和商品名称硬编码在一起,结果换商品时整个数据结构都得改。所以,我建议把货架本身的信息和商品信息分开,但又通过关联字段连起来。
下面是我常用的一个数据结构定义,用 Python 的字典来表示:
shelf = {
"id": "A-01-01", # 货架编号:区域-排-层
"zone": "A", # 所属区域
"row": 1, # 第几排
"level": 1, # 第几层
"category": "饮料", # 商品品类
"capacity": 50, # 最大容量(件)
"current_stock": 30, # 当前库存(件)
"status": "normal", # 状态枚举值
"last_updated": "2025-01-15 14:30:00" # 最后更新时间
}
你看,这个结构很清晰。每个字段都有明确的含义。其中 status 字段就是我们接下来要重点讲的状态枚举。
id 设计成有意义的编码,比如 "A-01-01" 一眼就能看出是 A 区第 1 排第 1 层。这在排查问题时特别方便。
3.2 状态枚举:满、空、缺货,怎么定义?
货架的状态,说白了就三种:
- 满(full):库存量接近或等于容量,不需要补货。
- 空(empty):库存量为 0,必须立即补货。
- 缺货(low):库存量低于某个阈值,需要关注。
但这里有个细节——「缺货」的阈值怎么定?
我曾经在一个项目中,直接把阈值写死成 10%。结果有个货架容量是 1000,10% 就是 100 件,其实还够卖两天,但系统疯狂报警。后来我改成按「安全库存天数」来算,才解决了问题。
不过咱们这个课程是入门级的,先简化处理。我建议用容量百分比来定义:
| 状态 | 枚举值 | 判断条件 | 说明 |
|---|---|---|---|
| 满 | full |
current_stock >= capacity * 0.8 | 库存充足,无需补货 |
| 缺货 | low |
current_stock <= capacity * 0.2 | 库存偏低,建议补货 |
| 空 | empty |
current_stock == 0 | 完全没货,必须补货 |
嗯,这里要注意:full 和 low 之间其实还有一个「正常」状态。但为了简化,我们只定义这三种极端情况。中间状态可以统一归为 normal。
empty 和 low 混在一起,结果导致缺货预警和紧急补货的流程冲突。记住,empty 是红色警报,low 是黄色预警,级别完全不同。
3.3 模拟数据生成:让数据「活」起来
好了,数据结构定义好了,状态枚举也清楚了。接下来我们要生成一批模拟数据,用来测试我们的可视化界面。
为什么要模拟数据?因为真实数据往往涉及隐私或权限问题,而且你不可能为了开发一个仪表盘,真的去仓库里摆满货架再一个个数。所以,自己造数据是最快的。
我写了一个简单的 Python 脚本来生成模拟数据。核心思路是:
- 定义几个区域(A、B、C)
- 每个区域有若干排和层
- 随机分配品类和库存量
- 根据库存量计算状态
来看代码:
import random
from datetime import datetime
def generate_shelf_data():
zones = ['A', 'B', 'C']
categories = ['饮料', '零食', '日用品', '粮油', '调味品']
shelves = []
shelf_id = 1
for zone in zones:
for row in range(1, 4): # 每区3排
for level in range(1, 5): # 每排4层
capacity = random.choice([30, 50, 80, 100])
current_stock = random.randint(0, capacity)
# 根据库存量判断状态
if current_stock == 0:
status = "empty"
elif current_stock <= capacity * 0.2:
status = "low"
elif current_stock >= capacity * 0.8:
status = "full"
else:
status = "normal"
shelf = {
"id": f"{zone}-{row:02d}-{level:02d}",
"zone": zone,
"row": row,
"level": level,
"category": random.choice(categories),
"capacity": capacity,
"current_stock": current_stock,
"status": status,
"last_updated": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
}
shelves.append(shelf)
shelf_id += 1
return shelves
# 生成数据
data = generate_shelf_data()
print(f"共生成 {len(data)} 个货架数据")
print(data[:3]) # 打印前3个看看效果
运行这个脚本,你会得到类似这样的输出:
共生成 36 个货架数据
[
{'id': 'A-01-01', 'zone': 'A', 'row': 1, 'level': 1, 'category': '饮料', 'capacity': 50, 'current_stock': 42, 'status': 'full', 'last_updated': '2025-01-15 14:30:00'},
{'id': 'A-01-02', 'zone': 'A', 'row': 1, 'level': 2, 'category': '零食', 'capacity': 80, 'current_stock': 5, 'status': 'low', 'last_updated': '2025-01-15 14:30:00'},
{'id': 'A-01-03', 'zone': 'A', 'row': 1, 'level': 3, 'category': '日用品', 'capacity': 100, 'current_stock': 0, 'status': 'empty', 'last_updated': '2025-01-15 14:30:00'}
]
你看,三个货架分别展示了 full、low、empty 三种状态。这就是我们后面做可视化要用到的数据基础。
3.4 本章小结
这一章我们做了三件事:
- 定义了货架的数据结构——包含编号、区域、容量、库存等关键字段。
- 明确了状态枚举——满(full)、空(empty)、缺货(low),并给出了判断条件。
- 生成了模拟数据——用 Python 脚本批量生成 36 个货架数据,覆盖了所有状态。
有了这些数据,下一章我们就可以开始搭建可视化仪表盘了。说实话,数据模型设计这一步虽然看起来枯燥,但它是整个项目的基石。你想想看,如果数据结构没设计好,后面改起来有多痛苦?
好,这一章就到这里。下一章我们开始画图,让数据「看得见」。