电商系统设计之商品 (下)

电商大伙每天都在用,类似某猫,某狗等。 电商系统设计看似复杂又很简单,看似简单又很复杂 本章适合初级工程师及中级工程师细看,大佬请随意

前言

商品系统与订单系统(交易系统)是相铺相成的,当买家购买商品后将经历一个过程

商品系统->交易系统->订单系统->物流系统->售后系统

完成上述流程则是完成了一笔交易,经常网上购物的童鞋都懂这个。今天我们讲下从商品系统到交易系统和订单系统的存储过程及其设计上的应该注意的“坑”。

存储

前俩篇文章讲解的商品系统的SKU与SPU的设计过程

  • SPU(Standard Product Unit)标准化产品单元
  • SKU(Stock Keeping Unit)库存量单元

现在我们已经清楚商品系统数据表的设计并且清楚为什么要这样设计。

现在抛出了一个问题

用户购买的商品如何存储到订单/交易系统中?

关联问题

现在有这么一个场景

小明在某宝买了一部爱疯手机,颜色是红色,存储是32G,他选择使用某宝支付.

SKU

产品

颜色

存储

001

爱疯手机

红色

32G

002

爱疯手机

红色

256G

003

爱疯手机

黑色

32G

004

爱疯手机

黑色

256G

小明选择购买SKU=001的产品,正常情况下订单表应该与此SKU编码相关联来维持数据一致性。像这样

订单号

用户

SKU

SN110

小明

001

这种设计有个弊端,商品的名称及价格都不是固定,如果商户修改了商品的标题或者其他的属性,那小明当时买的爱疯手机是8000元,结果过了几年降价了商户修改了价格,结果小明的购买清单里也变成了修改后的价格,所以说这种仅仅关联的设计是不可取的(至少在电商系统中不可取)。

订单号

用户

SKU

商品标题

商品价格

商品封面图

商品其他属性

SN110

小明

001

爱疯手机

8000

aifeng.png

其他属性

像上表中设计,有人会问了 “那关联的意义何在呢?”

我的回答是 “保持数据关联” ,虽然商户有可能改变商品属性,但作为一名程序员,应该尽可能的记录用户所有的动作。

文末有订单表的数据结构

多商户电商

实际在电商系统设计上,个人感觉不应区分多商户的电商与单用户的电商(至少开发者不应区分他们),但前期设计上就应把多商户概念带入到系统内。哪怕只有一个官方专卖店呢?!

涉及到多商户就需要考虑用户统一下单问题了。

  • 订单是由购物车下单,多个商品来自多个商户
  • 如果进行拆单、分单
  • 如何进行下单通知等等多商户的问题

关于多商户的问题不是本章的重点,本次我先提出这几个疑问,感兴趣的同学可以提前思考下,后续文章会详细讲解

订单是由购物车下单,多个商品来自多个商户

如果下单是来自多个商户的商品,那么订单的数据库接口应该这样设计

订单表

订单号

用户

SN110

小明

订单详情表

订单号

SKU

用户

商户

SN110

001

小明

官方

SN110

002

小明

第三方

无论购买多少商品并且商品归属于多少个商户,我们都应把用户一次性购买的商品归属与一个订单,订单下再关联多个商品的详情。在售后操作上,也方便买家退换单个商品。

文末有详细数据结构设计

后台功能列表

这里提供下功能名称与URL为参考

菜单名称

URL

商品管理

/product

发布商品

/product/create

商品类目

/product/category

品牌管理

/product/brand

规格管理

/product/attribute

回收站

/product/recycle

订单列表

/order

后台的设计和操作套路我会单独拿一篇文章来介绍。这里只做一个大概的table。

数据表

order 订单表

CREATE TABLE `order` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `order_no` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '订单编号',
  `order_sn` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '交易号',
  `member_id` int(11) NOT NULL COMMENT '客户编号',
  `supplier_id` int(11) DEFAULT '0' COMMENT '商户编码',
  `supplier_name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '商户名称',
  `order_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '订单状态 0未付款,1已付款,2已发货,3已签收,-1退货申请,-2退货中,-3已退货,-4取消交易 -5撤销申请',
  `after_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '用户售后状态 0 未发起售后 1 申请售后 -1 售后已取消 2 处理中 200 处理完毕',
  `product_count` int(11) NOT NULL DEFAULT '0' COMMENT '商品数量',
  `product_amount_total` decimal(12,4) NOT NULL COMMENT '商品总价',
  `order_amount_total` decimal(12,4) NOT NULL DEFAULT '0.0000' COMMENT '实际付款金额',
  `logistics_fee` decimal(12,4) NOT NULL COMMENT '运费金额',
  `address_id` int(11) NOT NULL COMMENT '收货地址编码',
  `pay_channel` tinyint(4) NOT NULL DEFAULT '0' COMMENT '支付渠道 0余额 1微信 2支付宝',
  `out_trade_no` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '订单支付单号',
  `escrow_trade_no` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '第三方支付流水号',
  `pay_time` int(11) NOT NULL DEFAULT '0' COMMENT '付款时间',
  `delivery_time` int(11) NOT NULL DEFAULT '0' COMMENT '发货时间',
  `order_settlement_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '订单结算状态 0未结算 1已结算',
  `order_settlement_time` int(11) NOT NULL DEFAULT '0' COMMENT '订单结算时间',
  `is_package` enum('0','1') COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '0' COMMENT '是否是套餐',
  `is_integral` enum('0','1') COLLATE utf8mb4_unicode_ci DEFAULT '0' COMMENT '是否是积分产品',
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  `deleted_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `order_order_sn_member_id_order_status_out_trade_no_index` (`order_sn`,`member_id`,`order_status`,`out_trade_no`(191))
) ENGINE=InnoDB AUTO_INCREMENT=114 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

order_detail 订单详情

CREATE TABLE `order_detail` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `order_id` int(11) NOT NULL COMMENT '订单编码',
  `product_id` int(11) NOT NULL COMMENT '商品编码',
  `product_name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '商品名称',
  `product_price` decimal(12,4) NOT NULL COMMENT '商品价格',
  `product_sku` int(11) NOT NULL COMMENT '商品SKU',
  `product_picture_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `product_mode_desc` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '商品型号信息',
  `product_mode_params` int(11) DEFAULT NULL COMMENT '商品型号参数',
  `discount_rate` tinyint(4) NOT NULL DEFAULT '0' COMMENT '折扣比例',
  `discount_amount` decimal(12,4) NOT NULL DEFAULT '0.0000' COMMENT '折扣比例',
  `number` int(11) NOT NULL DEFAULT '1' COMMENT '购买数量',
  `subtotal` decimal(12,4) NOT NULL COMMENT '小计金额',
  `is_product_exists` enum('0','1') COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '0' COMMENT '商品是否有效 1失效',
  `remark` text COLLATE utf8mb4_unicode_ci COMMENT '客户商品备注',
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `order_detail_order_id_index` (`order_id`)
) ENGINE=InnoDB AUTO_INCREMENT=118 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

order_logistics 订单物流

CREATE TABLE `order_logistics` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `order_id` int(11) NOT NULL COMMENT '订单编码',
  `express_no` varchar(125) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '发货快递单号',
  `consignee_realname` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '收货人姓名',
  `consignee_telphone` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '联系电话',
  `consignee_telphone2` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '备用联系电话',
  `consignee_address` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '收货地址',
  `consignee_zip` int(11) NOT NULL COMMENT '邮政编码',
  `logistics_type` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '物流方式',
  `logistics_fee` decimal(12,2) NOT NULL DEFAULT '0.00' COMMENT '物流发货运费',
  `order_logistics_status` int(11) NOT NULL DEFAULT '0' COMMENT '物流状态',
  `logistics_settlement_status` int(11) NOT NULL DEFAULT '0' COMMENT '物流结算状态',
  `logistics_result_last` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '物流最后状态描述',
  `logistics_result` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '物流描述',
  `logistics_create_time` int(11) NOT NULL DEFAULT '0' COMMENT '发货时间',
  `logistics_update_time` int(11) NOT NULL DEFAULT '0' COMMENT '物流更新时间',
  `logistics_settlement_time` int(11) NOT NULL DEFAULT '0' COMMENT '物流结算时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=114 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

order_returns 订单退换货

CREATE TABLE `order_returns` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `returns_no` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '退货编号 供客户查询',
  `order_id` int(11) NOT NULL COMMENT '订单编号',
  `express_no` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '物流单号',
  `consignee_realname` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '收货人姓名',
  `consignee_telphone` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '联系电话',
  `consignee_telphone2` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '备用联系电话',
  `consignee_address` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '收货地址',
  `consignee_zip` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '邮政编码',
  `logistics_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '物流方式',
  `logistics_fee` decimal(12,2) NOT NULL COMMENT '物流发货运费',
  `order_logistics_status` int(11) DEFAULT NULL COMMENT '物流状态',
  `logistics_settlement_status` int(11) DEFAULT NULL COMMENT '物流结算状态',
  `logistics_result_last` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '物流最后状态描述',
  `logistics_result` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '物流描述',
  `logistics_create_time` int(11) DEFAULT NULL COMMENT '发货时间',
  `logistics_update_time` int(11) DEFAULT NULL COMMENT '物流更新时间',
  `logistics_settlement_time` int(11) DEFAULT NULL COMMENT '物流结算时间',
  `returns_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '0全部退单 1部分退单',
  `handling_way` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'PUPAWAY:退货入库;REDELIVERY:重新发货;RECLAIM-REDELIVERY:不要求归还并重新发货; REFUND:退款; COMPENSATION:不退货并赔偿',
  `returns_amount` decimal(8,2) NOT NULL COMMENT '退款金额',
  `return_submit_time` int(11) NOT NULL COMMENT '退货申请时间',
  `handling_time` int(11) NOT NULL COMMENT '退货处理时间',
  `remark` text COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '退货原因',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

order_returns_apply 售后申请

退换货申请

CREATE TABLE `order_returns_apply` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `order_no` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '订单单号',
  `order_detail_id` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '子订单编码',
  `return_no` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '售后单号',
  `member_id` int(11) NOT NULL COMMENT '用户编码',
  `state` tinyint(4) NOT NULL COMMENT '类型 0 仅退款 1退货退款',
  `product_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '货物状态 0:已收到货 1:未收到货',
  `why` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '退换货原因',
  `status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '审核状态 -1 拒绝 0 未审核 1审核通过',
  `audit_time` int(11) NOT NULL DEFAULT '0' COMMENT '审核时间',
  `audit_why` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '审核原因',
  `note` text COLLATE utf8mb4_unicode_ci COMMENT '备注',
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

致谢

感谢你看完这篇文章,接下来会继续出一些电商相关的文章,例如交易系统的设计、订单系统的设计等等。感谢近期来关注我的童鞋们。作为一个程序员,我很荣幸能把我知道的分享给大家。

代码多变,初心不变

最后修改:2个月前 2018-07-16

© 著作权归作者所有

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java帮帮-微信公众号-技术文章全总结

Oracle应用实战七——多表查询+PL/SQL

1 多表查询 内连接 使用一张以上的表做查询就是多表查询 语法: SELECT {DISTINCT} *|列名.. FROM 表名 别名,表名1 别名 {WH...

83440
来自专栏沃趣科技

SQL优化案例-正确的使用索引(二)

下面sql 30秒执行出结果,查看sql谓词中有like,我们知道谓词中有这样的语句是不走索引的(为了保护客户的隐私,表名和部分列已经重命名)。

16160
来自专栏landv

一、K3 WISE 开发插件《K3 WISE常用数据表整理》

42870
来自专栏idba

修改字符集的注意那些事儿

最近有开发同学遇到emoji显示问题,表结构是utf8mb4字符集,但是不支持emoji表情字符。我们在解决字符集问题的时候也重新认识了修改字符集操作的...

9420
来自专栏杨建荣的学习笔记

merge语句导致的CPU使用率过高的优化(二) (r7笔记第9天)

之前分享过一篇关于merge语句导致的CPU使用率过高优化的案例。http://blog.itpub.net/23718752/viewspace-181947...

32840
来自专栏程序员宝库

电商系统设计之订单

用户交易将经历一段艰辛的历程,一般用户感觉不到,实际程序是经历了一段生死离别。具体付款流程如下:

52230
来自专栏数据和云

实战演练:通过伪列、虚拟列实现SQL优化

本文是技术同仁 蔡亮 在日常工作中通过试验,总结出的一些技巧方案,供大家参考学习。在此,感谢蔡亮的供稿分享,希望大家也可以后续将学习工作中遇到的问题,解决方法分...

15230
来自专栏程序员宝库

电商系统设计之商品 (上)

电商大伙每天都在用,类似某猫,某狗等。电商系统设计看似复杂又很简单,看似简单又很复杂。本章适合初级工程师及中级工程师细看,大佬请随意。

32140
来自专栏杨建荣的学习笔记

生产环境大型sql语句调优实战第一篇(二) (r2笔记32天)

继续昨天的部分,上一篇的链接为: http://blog.itpub.net/23718752/viewspace-1217012/ 对这条大sql的性能瓶颈进...

28360
来自专栏杨建荣的学习笔记

MySQL表连接优化的初步分析

每每一些很深刻的优化案例时,就会无比想念Oracle里的优化技巧,因为无论是从工具还是信息,都会丰富许多。

9020

扫码关注云+社区

领取腾讯云代金券