好吧今天还得再发表一两篇文章。
数据库用的是Postgresql,使用的管理软件是pgAdmin。
几张表的构成如下。尽量简单点吧,反正仓库的流程本身也挺简单的。
office给出纸质order -> 仓库根据order把东西装车发给客户/客户自己开车过来,至少两人一组把东西给他搬车上 -> 出库完成
集装箱到货 -> 用叉车叉到仓库储存区 -> 对照office给出的入库单,清点数量,无误 -> 入库完成
OK,下面是建表的sql文档,以及部分测试数据。
建表文档:
📚 QuickStore Database Tables
- [QuickStore Database Schema Overview](#QuickStore Database Schema Overview "#quickstore-database-schema-overview")
- [users (系统用户)](#users (系统用户) "#users-%E7%B3%BB%E7%BB%9F%E7%94%A8%E6%88%B7")
- [products (商品信息)](#products (商品信息) "#products-%E5%95%86%E5%93%81%E4%BF%A1%E6%81%AF")
- [product_locations (商品位置信息)](#product_locations (商品位置信息) "#product_locations-%E5%95%86%E5%93%81%E4%BD%8D%E7%BD%AE%E4%BF%A1%E6%81%AF")
- [customers (客户信息)](#customers (客户信息) "#customers-%E5%AE%A2%E6%88%B7%E4%BF%A1%E6%81%AF")
- [inbounds (入库记录)](#inbounds (入库记录) "#inbounds-%E5%85%A5%E5%BA%93%E8%AE%B0%E5%BD%95")
- [inbound_items (入库商品)](#inbound_items (入库商品) "#inbound_items-%E5%85%A5%E5%BA%93%E5%95%86%E5%93%81")
- [orders (客户下的订单/出库记录)](#orders (客户下的订单/出库记录) "#orders-%E5%AE%A2%E6%88%B7%E4%B8%8B%E7%9A%84%E8%AE%A2%E5%8D%95%E5%87%BA%E5%BA%93%E8%AE%B0%E5%BD%95")
- [order_items (订单出库的商品明细)](#order_items (订单出库的商品明细) "#order_items-%E8%AE%A2%E5%8D%95%E5%87%BA%E5%BA%93%E7%9A%84%E5%95%86%E5%93%81%E6%98%8E%E7%BB%86")
- [order_operators (订单出库的协同人员)](#order_operators (订单出库的协同人员) "#order_operators-%E8%AE%A2%E5%8D%95%E5%87%BA%E5%BA%93%E7%9A%84%E5%8D%8F%E5%90%8C%E4%BA%BA%E5%91%98")
QuickStore Database Schema Overview
This document outlines the structure and meaning of all database tables used in the QuickStore WMS.
users (系统用户)
| 字段名 | 类型 | 描述 |
|---|---|---|
id |
SERIAL (PK) | 用户 ID,自增主键 |
username |
TEXT | 登录名(唯一) |
password_hash |
TEXT | 加密后的密码 |
full_name |
TEXT | 用户姓名 |
role |
TEXT | 角色:如 'admin'、'office'、'warehouse' |
created_at |
TIMESTAMP | 创建时间 |
products (商品信息)
| 字段名 | 类型 | 描述 |
|---|---|---|
id |
SERIAL (PK) | 产品 ID,自增主键 |
name |
TEXT | 产品名称(如 角铝、圆管 等) |
specification |
TEXT | 规格(如 20x20mm、2mm 厚) |
unit |
TEXT | 单位(如 米、条、根) |
price |
NUMERIC(10, 2) | 单价(如 12.50) |
created_at |
TIMESTAMP | 添加时间 |
product_locations (商品位置信息)
| 字段名 | 类型 | 描述 |
|---|---|---|
id |
SERIAL (PK) | 位置 ID |
product_id |
INTEGER (FK → products.id) | 所属商品 ID |
location_code |
TEXT | 货位编码(比如A1,C1,S1等) |
quantity |
INTEGER | 当前位置货物数量。当is_default为true时可以为0 |
is_default |
BOOLEAN | 是否为商品默认位置。可以有多个true |
updated_at |
TIMESTAMP | 最后修改时间 |
customers (客户信息)
| 字段名 | 类型 | 描述 |
|---|---|---|
id |
SERIAL (PK) | 客户 ID |
name |
TEXT | 客户名称(公司名或个人名) |
contact_number |
TEXT | 电话号码 |
email |
TEXT | 邮箱(可选) |
address |
TEXT | 地址 |
created_at |
TIMESTAMP | 添加时间 |
inbounds (入库记录)
| 字段名 | 类型 | 描述 |
|---|---|---|
id |
SERIAL (PK) | 入库记录 ID |
shipment_code |
TEXT | 货柜编号或批次号(可选) |
arrival_date |
DATE | 到货日期 |
inbound_date |
DATE | 入库日期 |
created_by |
INTEGER (FK → users.id) | 哪个用户录入的 |
remark |
TEXT | 备注(手动调整库存等) |
status |
TEXT | 状态(如:办公室:draft, 仓库:pending, completed等) |
created_at |
TIMESTAMP | 入库登记时间 |
inbound_items (入库商品)
| 字段名 | 类型 | 描述 |
|---|---|---|
id |
SERIAL (PK) | 入库商品 ID |
inbound_id |
INTEGER (FK → inbounds.id) | 入库记录 ID |
product_id |
INTEGER (FK → products.id) | 产品id |
quantity |
INTEGER | 入库数量 |
remark |
TEXT | 备注(手动调整库存等) |
created_at |
TIMESTAMP | 入库登记时间 |
orders (客户下的订单/出库记录)
| 字段名 | 类型 | 描述 |
|---|---|---|
id |
SERIAL (PK) | 订单 ID |
customer_id |
INTEGER (FK → customers.id) | 所属客户 |
order_date |
TIMESTAMP | 下单时间 |
created_by |
INTEGER (FK → users.id) | 哪位员工录入的 |
is_delivery |
BOOLEAN | 是否需要司机配送 |
remark |
TEXT | 备注(如客户退货等) |
status |
TEXT | 状态(如:pending, fulfilled, canceled) |
created_at |
TIMESTAMP | 本记录创建时间 |
order_items (订单出库的商品明细)
| 字段名 | 类型 | 描述 |
|---|---|---|
id |
SERIAL (PK) | 明细 ID |
order_id |
INTEGER (FK → orders.id) | 所属订单 |
product_id |
INTEGER (FK → products.id) | 产品 |
quantity |
INTEGER | 数量 |
unit_price |
NUMERIC(10, 2) | 下单时的单价(防止价格变动影响历史) |
created_at |
TIMESTAMP | 本记录创建时间 |
order_operators (订单出库的协同人员)
| 字段名 | 类型 | 描述 |
|---|---|---|
id |
SERIAL (PK) | 明细 ID |
order_id |
INTEGER (FK → orders.id) | 所属订单 |
user_id |
INTEGER (FK → users.id) | 出库的仓库人员是谁(因为一般是两人或两人以上完成一张订单) |
created_at |
TIMESTAMP | 本记录创建时间 |
各表之间的一对多关系:
| 主表 | 子表 | 关系类型 |
|---|---|---|
customers → orders |
1 → ∞ | |
inbounds → inbound_items |
1 → ∞ | |
orders → order_items |
1 → ∞ | |
orders → order_operators |
1 → ∞ | |
products → order_items |
1 → ∞ | |
products → product_locations |
1 → ∞ | |
inbounds → inbound_items |
1 → ∞ | |
products → inbound_items |
1 → ∞ | |
users → orders, inbounds |
1 → ∞ |
-- 数据库表的建表语句
sql
-- ==========================================
-- 1. users (系统用户表)
-- ==========================================
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username TEXT NOT NULL UNIQUE,
password_hash TEXT NOT NULL,
full_name TEXT NOT NULL,
role TEXT NOT NULL DEFAULT 'warehouse',
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
COMMENT ON TABLE users IS '系统用户表';
COMMENT ON COLUMN users.id IS '用户 ID,自增主键';
COMMENT ON COLUMN users.username IS '登录名(唯一)';
COMMENT ON COLUMN users.password_hash IS '加密后的密码';
COMMENT ON COLUMN users.full_name IS '用户姓名';
COMMENT ON COLUMN users.role IS '角色:如 admin、office、warehouse';
COMMENT ON COLUMN users.created_at IS '创建时间';
-- ==========================================
-- 2. products (商品信息表)
-- ==========================================
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
specification TEXT,
unit TEXT,
price NUMERIC(10, 2) NOT NULL DEFAULT 0.00,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
COMMENT ON TABLE products IS '商品信息表';
COMMENT ON COLUMN products.id IS '产品 ID,自增主键';
COMMENT ON COLUMN products.name IS '产品名称(如 角铝、圆管 等)';
COMMENT ON COLUMN products.specification IS '规格(如 20x20mm、2mm 厚)';
COMMENT ON COLUMN products.unit IS '单位(如 米、条、根)';
COMMENT ON COLUMN products.price IS '当前标准单价(如 12.50)';
COMMENT ON COLUMN products.created_at IS '添加时间';
-- ==========================================
-- 3. product_locations (商品库存分布与默认货位表)
-- ==========================================
CREATE TABLE product_locations (
id SERIAL PRIMARY KEY,
product_id INTEGER NOT NULL REFERENCES products(id) ON DELETE CASCADE,
location_code TEXT NOT NULL,
quantity INTEGER NOT NULL DEFAULT 0 CHECK (quantity >= 0),
is_default BOOLEAN NOT NULL DEFAULT FALSE,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- 联合唯一约束:同一个商品在同一个货位只能有一条记录
CONSTRAINT unique_product_location UNIQUE (product_id, location_code)
);
COMMENT ON TABLE product_locations IS '商品库存分布与默认货位表(支持一物多位与习惯性留白)';
COMMENT ON COLUMN product_locations.id IS '自增主键';
COMMENT ON COLUMN product_locations.product_id IS '关联的产品 ID';
COMMENT ON COLUMN product_locations.location_code IS '货位编码(如 A1, C1, S1)';
COMMENT ON COLUMN product_locations.quantity IS '该特定货位上的商品当前库存数量(默认货位允许为0)';
COMMENT ON COLUMN product_locations.is_default IS 'TRUE: 设为该商品的默认/常用位置(即使库存为0也不释放)';
COMMENT ON COLUMN product_locations.updated_at IS '最后一次位置库存变动时间';
-- ==========================================
-- 4. customers (客户信息表)
-- ==========================================
CREATE TABLE customers (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
contact_number TEXT,
email TEXT,
address TEXT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
COMMENT ON TABLE customers IS '客户信息表';
COMMENT ON COLUMN customers.id IS '客户 ID,自增主键';
COMMENT ON COLUMN customers.name IS '客户名称(公司名或个人名)';
COMMENT ON COLUMN customers.contact_number IS '电话号码';
COMMENT ON COLUMN customers.email IS '邮箱(可选)';
COMMENT ON COLUMN customers.address IS '地址';
COMMENT ON COLUMN customers.created_at IS '添加时间';
-- ==========================================
-- 5. inbounds (入库单主表)
-- ==========================================
CREATE TABLE inbounds (
id SERIAL PRIMARY KEY,
shipment_code TEXT,
arrival_date DATE,
inbound_date DATE,
created_by INTEGER REFERENCES users(id) ON DELETE SET NULL,
remark TEXT,
status TEXT NOT NULL DEFAULT 'draft',
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
COMMENT ON TABLE inbounds IS '入库记录主表';
COMMENT ON COLUMN inbounds.id IS '入库记录 ID,自增主键';
COMMENT ON COLUMN inbounds.shipment_code IS '货柜编号或批次号(可选)';
COMMENT ON COLUMN inbounds.arrival_date IS '集装箱到货日期';
COMMENT ON COLUMN inbounds.inbound_date IS '正式点完核对入库的日期';
COMMENT ON COLUMN inbounds.created_by IS '哪位员工录入的单据';
COMMENT ON COLUMN inbounds.remark IS '备注(手动调整库存原因等)';
COMMENT ON COLUMN inbounds.status IS '状态:draft(办公室草稿), pending(清点中), completed(已入库)';
COMMENT ON COLUMN inbounds.created_at IS '入库登记时间';
-- ==========================================
-- 6. inbound_items (入库商品明细表)
-- ==========================================
CREATE TABLE inbound_items (
id SERIAL PRIMARY KEY,
inbound_id INTEGER NOT NULL REFERENCES inbounds(id) ON DELETE CASCADE,
product_id INTEGER NOT NULL REFERENCES products(id),
quantity INTEGER NOT NULL CHECK (quantity > 0),
remark TEXT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
COMMENT ON TABLE inbound_items IS '入库商品明细表';
COMMENT ON COLUMN inbound_items.id IS '明细 ID,自增主键';
COMMENT ON COLUMN inbound_items.inbound_id IS '关联的入库主单 ID';
COMMENT ON COLUMN inbound_items.product_id IS '关联的产品 ID';
COMMENT ON COLUMN inbound_items.quantity IS '本次实际入库数量';
COMMENT ON COLUMN inbound_items.remark IS '单项备注';
COMMENT ON COLUMN inbound_items.created_at IS '本条记录创建时间';
-- ==========================================
-- 7. orders (客户订单/出库记录主表)
-- ==========================================
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
customer_id INTEGER REFERENCES customers(id) ON DELETE SET NULL,
order_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
created_by INTEGER REFERENCES users(id) ON DELETE SET NULL,
is_delivery BOOLEAN NOT NULL DEFAULT FALSE,
remark TEXT,
status TEXT NOT NULL DEFAULT 'pending',
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
COMMENT ON TABLE orders IS '客户下的订单/出库记录主表';
COMMENT ON COLUMN orders.id IS '订单 ID,自增主键';
COMMENT ON COLUMN orders.customer_id IS '所属客户 ID';
COMMENT ON COLUMN orders.order_date IS '客户下单时间';
COMMENT ON COLUMN orders.created_by IS '哪位办公室员工录入的';
COMMENT ON COLUMN orders.is_delivery IS 'TRUE: 司机开 UTE 配送 / FALSE: 客户自提';
COMMENT ON COLUMN orders.remark IS '备注(退换货说明、配送要求等)';
COMMENT ON COLUMN orders.status IS '订单状态:pending(待配货), fulfilled(已出库), canceled(已取消)';
COMMENT ON COLUMN orders.created_at IS '本记录创建时间';
-- ==========================================
-- 8. order_items (订单商品明细表)
-- ==========================================
CREATE TABLE order_items (
id SERIAL PRIMARY KEY,
order_id INTEGER NOT NULL REFERENCES orders(id) ON DELETE CASCADE,
product_id INTEGER NOT NULL REFERENCES products(id),
quantity INTEGER NOT NULL CHECK (quantity > 0),
unit_price NUMERIC(10, 2) NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
COMMENT ON TABLE order_items IS '订单中的商品明细表';
COMMENT ON COLUMN order_items.id IS '明细 ID,自增主键';
COMMENT ON COLUMN order_items.order_id IS '所属订单 ID';
COMMENT ON COLUMN order_items.product_id IS '关联的产品 ID';
COMMENT ON COLUMN order_items.quantity IS '购买数量';
COMMENT ON COLUMN order_items.unit_price IS '下单时的实际成交单价(防止商品调价影响历史对账)';
COMMENT ON COLUMN order_items.created_at IS '本记录创建时间';
-- ==========================================
-- 9. order_operators (订单出库协同人员中间表)
-- ==========================================
CREATE TABLE order_operators (
id SERIAL PRIMARY KEY,
order_id INTEGER NOT NULL REFERENCES orders(id) ON DELETE CASCADE,
user_id INTEGER NOT NULL REFERENCES users(id),
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
COMMENT ON TABLE order_operators IS '订单出库协同人员中间表';
COMMENT ON COLUMN order_operators.id IS '记录 ID,自增主键';
COMMENT ON COLUMN order_operators.order_id IS '所属订单 ID';
COMMENT ON COLUMN order_operators.user_id IS '参与出库的仓库人员 ID';
COMMENT ON COLUMN order_operators.created_at IS '协同出库确认时间';
测试数据:
sql
-- 1. 插入初始化用户 (密码暂用明文替代,后续开发需改用 Bcrypt/Argon2 密码哈希)
INSERT INTO users (username, password_hash, full_name, role) VALUES
('admin_tony', 'hashed_password_123', 'Tony (老板)', 'admin'),
('office_lucy', 'hashed_password_456', 'Lucy (文员)', 'office'),
('wh_jack', 'hashed_password_789', 'Jack (仓库小哥)', 'warehouse'),
('wh_sam', 'hashed_password_abc', 'Sam (仓库小哥)', 'warehouse');
-- 2. 插入部分铝材产品
INSERT INTO products (name, specification, unit, price) VALUES
('等边角铝', '20x20mm, 2mm厚, 6米长', '根', 15.50),
('方管', '50x50mm, 3mm厚, 6米长', '根', 32.00),
('槽铝', '40x20mm, 2mm厚, 6米长', '根', 22.00);
-- 3. 初始化货位数字化:为这些产品绑定默认货位 (初始数量为0,落实习惯性留白)
INSERT INTO product_locations (product_id, location_code, quantity, is_default) VALUES
(1, 'A1', 0, TRUE), -- 角铝默认放A1
(1, 'S1', 0, TRUE), -- 角铝大宗囤货放S1
(2, 'B3', 0, TRUE), -- 方管默认放B3
(3, 'A-FLOOR', 0, TRUE); -- 槽铝默认堆在地板区A
-- 4. 插入几个本地建筑商客户
INSERT INTO customers (name, contact_number, email, address) VALUES
('ABC Alum Windows Pty Ltd', '0412345678', 'info@abcwindows.com.au', '123 Springvale Rd, Glen Waverley VIC 3150'),
('Melbourne Building Supplies', '0398765432', 'order@melbbuild.com.au', '45 Dandenong Rd, Dandenong VIC 3175');
可以写在简历上的东西:
好吧这是AI帮我生成的,但是到时候写简历也可以参考下:
sql
QuickStore Warehouse Management System (Personal Project)
- Built a full-stack Warehouse Management System using React, Spring Boot, PostgreSQL and JWT authentication.
- Designed and implemented a PostgreSQL database schema consisting of 9 relational tables supporting inventory management, inbound shipments, customer orders and warehouse operations.
- Developed normalized database relationships using primary keys, foreign keys, constraints and cascading rules to ensure data integrity.
- Implemented inventory location management supporting multi-location stock allocation and warehouse tracking.
- Created RESTful APIs for user authentication, product management, customer management and warehouse workflows.
sql
Translated real-world warehouse business requirements into a normalized PostgreSQL relational database schema consisting of 9 interconnected tables.