简介这是一份面向数据库课程设计、系统分析与软件工程等场景的电子商店系统数据库设计文档适合计算机、信息管理等专业的本科生、高职学生以及需要完成类似选题的开发者参考。内容围绕系统需求分析、数据字典、E-R图与数据流程图展开并覆盖概念结构设计、逻辑结构设计、物理结构设计、完整性约束、索引设置和用户权限设计等完整流程能直观展示如何从业务需求逐步转换为可落地的关系模式。文档以文字说明配合图表形式呈现清晰刻画用户、商品、订单等核心实体及其联系可用于课程报告撰写、答辩演示也可作为后续完成购物车、支付结算等模块开发的建模依据。资源包内仅有1个doc文件大小约1.09MB使用Office或WPS即可打开编辑查阅和修改都很方便。目前已有694人学习下载整体结构完整、步骤分明是一份可以直接参考的数据库设计范例。1. 电子商店系统数据库设计这份文档能解决你课程设计里最头疼的三件事写数据库课程设计最怕的不是写代码而是画E-R图、画数据流程图、写数据字典这三件事。画到一半发现实体关系理不清数据流对不上号规范化解不开表最后只能重画。这份电子商店系统数据库分析设计文档恰好把整个流程做全了从系统需求分析、38个数据项的数据字典、36条数据流清单到分E-R图和总E-R图再到逻辑结构设计里的关系模式、规范化、完整性约束最后还落了物理结构的索引与权限设计。适合正在做数据库课程设计、毕业设计或者急着交一套完整设计文档但没时间从零整理的人。2. 先从需求分析下手五个功能模块、数据字典与数据流程图怎么复用2.1 五个功能子系统怎么划分注册、购买、支付、物流、后台这份文档把电子商店系统切成了五个子系统这个切法不是随便分的每个子系统都对应一批独立的数据存储后文的数据流程图就是按这四个方向注册、购买、支付、物流分别展开的。先理解这个边界再去看后面那张总E-R图会清晰很多。用户注册系统负责用户注册和身份验证要求录入用户ID、密码、姓名、身份证、手机号、邮箱、生日等实名信息。购买系统包含商品信息查询、商品推荐、购物车三个功能推荐还细分了幻灯片推荐、列表推荐、销售排行推荐三种形态。支付系统用户个人信息中心加网上支付走第三方认证中心代管资金订单确认后才能付款。物流系统前期对接顺丰、申通、圆通等现有快递公司后期再自建物流平台。后台管理系统管理员身份验证、商品管理、订单管理、员工管理员工还按职能分了不同权限级别。这里有一个对数据库设计很关键的点功能模块划分决定了数据存储的边界。比如购买系统里“商品推荐”需要按销量排序那商品表里就一定得有销售量这个字段后文数据字典里DI22销售量就是这么来的。如果你自己从头做设计建议先按功能模块整理一份数据需求清单再进入概念结构设计不然画E-R图的时候很容易漏实体。2.2 数据字典38个数据项的分类与取值约定文档的数据字典是按编号组织的从DI01到DI38一共38个数据项覆盖了订单、会员、商品、管理员、物流五大类信息。类型设计上有几个值得注意的做法订单号DI01是“数字串类型”也就是用纯数字字符串而不是数值类型密码DI06也是数字串而单价DI15、总金额DI04、物流费用DI38都是整数类型。这个选择在课程设计里比较常见因为它简化了实现但如果按生产标准看金额用DECIMAL会更稳这一点后面说物理设计时再展开。编号范围数据项示例归属实体类型特点DI01-DI04订单号、订单状态、下单时间、总金额订单订单号唯一时间用日期型DI05-DI14登录名、密码、生日、姓名、性别、Email、邮编、电话、手机、地区会员/收货地址登录名唯一联系方式分类独立DI15-DI17单价、数量、积分购物车/订单明细整型为主DI18-DI20管理员ID、管理类别、工作任务管理员管理员ID唯一DI21-DI33ISBN、销售量、库存量、颜色、名称、类别、用途、保质期、价格、生产日期、适用人群、厂商、尺寸商品ISBN唯一类型覆盖字符/日期/整型DI34-DI38店铺网址、主营商品、物流公司、业务范围、物流费用店铺/物流公司网址字符型费用整型数据结构部分整理了8个会员信息、订单信息、收货地址、购物车、管理员、商品信息、店铺信息、物流公司。每个数据结构都列出了属性这些属性就是后面概念结构设计里实体属性的直接来源。我一般拿到这种数据字典第一件事是把它拍平成一张字段对照表字段名、类型、是否唯一、归属实体列成四列后面建表时可以少很多来回翻页的时间。2.3 数据流程图与36条数据流的边界四条主链路文档里画了四张数据流程图用户注册模块、网上购买模块、网上支付模块、物流模块。配合数据字典里DF1到DF36一共36条数据流整个系统的主链路可以归纳成四条读这份文档时按链路去追比一条条背要高效。注册链路是DF1到DF8从登录网页信息开始经过填写注册信息、验证信息、成为会员、激活会员账号、完善个人信息最后完整用户信息交给系统管理员。这条链路上数据存储有DB1系统提示信息、DB2完整用户信息注意注册信息的验证是循环的不合格信息会退回重填。购买链路是DF9到DF21买家登录商店首页后检索商品商品链接信息从DB3商品链接数据库取出满意就放入购物车DB5确认所购商品后填写订单并提交合格订单DB6买家订单信息流向卖家。这里有一条分支不合格订单DF20会退回确认所购商品这个回流在画图时很容易漏。支付链路DF22到DF30账号登录信息走账号认证通过后进网银身份验证验证通过发送交易信息到第三方服务机构错误提示和未通过验证的信息分别回流到买家和网银。注意这里有两个回流分支画图时如果不加判断框数据流就对不上。物流链路DF31到DF36卖家通知派送中心安排运输任务、派送货物、代理点交付已签收发货单回流通知卖家退货流程从代理点办理退货运往卖家。这条链路上DB9订单库是关键它把订单和发货单关联起来了。读这份文档的数据流清单最容易翻车的地方是来源和去处对不上。比如DF19“合格订单”的来源是“填写订单并提交”去处是“买家合格订单”粗看会以为数据流进了存储实际上它去的是下一个处理过程。我自己的习惯是照着DF编号在草稿纸上画一条单向箭头链每画一条就划掉一条最后数一遍划掉的数量和文档里的36条对不对得齐这个动作能帮你把绝大部分断链问题暴露出来。3. 概念结构设计十一组实体联系与E-R图转换关系模式的方法3.1 11个实体集和11组联系先理清楚再画图文档在概念结构设计阶段标识了11个实体集会员、商品、管理员、商品大类、商品细分类、购物车、收货地址、订单、物流公司、已选购商品、发货单外加一个店铺文档的属性集里还有店铺实体集列表里没单列但属性是有的。每个实体都列出了完整属性集比如会员登录名、密码、姓名、性别、生日、Email商品则长达16个属性从ISBN到适用人群都有。真正有价值的是那11组联系这是整个E-R图的核心骨架。文档对每一组联系都做了基数描述我整理成了一张表后面转关系模式时直接查表操作联系参与实体基数转换策略使用会员-购物车文档标1:N文字另有出入见避坑章外码并入N端拥有会员-收货地址N:M拆中间表包含订单-发货单1:1外码并入任一端拥有收货地址-订单1:N外码加在N端订单管理管理员-订单N:M拆中间表属于商品大类-商品细分类N:M拆中间表属于商品-商品细分类N:M拆中间表拥有订单-已订购商品1:N外码加在N端包含商品-已订购商品文档标1:1实际应为N:1见避坑章已在订单明细中体现管理物流公司-发货单1:N外码加在N端属于店铺-管理员1:N外码加在N端这张表建议直接抄进自己的设计文档里因为后面关系模式转换的每一个决定都能在这里找到依据。特别是N:M那几组如果漏掉任何一个中间表建库时外码会乱套。3.2 N:M联系为什么必须拆中间表三个典型例子文档里有三组典型的N:M联系每组都对应一个中间表。第一组是会员和收货地址一个家庭里多个会员可以共用一个收货地址一个会员也可以登记多个地址所以是N:M拆出来的中间表至少要有会员登录名、地址ID两个字段。第二组是管理员和订单一个管理员可以管理多份订单一份订单也可能被多个管理员处理中间表里除了两个外码通常还会带一个“处理时间”之类的属性。第三组是商品和商品细分类一个商品可以属于多个细分类一个细分类也可以包含多个商品这组在文档里被反复强调。这里有一个E-R图转关系模式的通用规则做过几次设计的人都应该背下来1:N联系把“1”那一端的主码放到“N”端实体表里做外码N:M联系必须新建一张中间表两个外码联合做主码1:1联系任选一端把另一端主码放进来做外码推荐放在访问频率低的那一侧。文档里订单和发货单就是1:1发货单号被放进了订单表这个方向是对的因为订单是主业务表查询订单时带出发货单号更方便。3.3 从分E-R图到总E-R图的集成两步消冲突文档在2.2节里写了E-R图合成过程采用分E-R图集成总E-R图的方式分两步走。第一步是合并局部E-R图把会员-购物车、会员-收货地址、管理员-订单、商品大类-细分类、物流公司-发货单、商品-已选购商品、已选购商品-订单这些小图先各自合并第二步是处理合并时的冲突这是最花时间的环节。冲突通常有三类命名冲突、属性冲突、结构冲突。命名冲突比如“商品ID”和“商品条形码ISBN”设计文档里商品ID是逻辑主键ISBN是业务唯一键合并时如果都叫“编号”就会乱属性冲突比如文档里订单的总金额是整数类型但商品单价也是整数这两者的精度语义不同合到一个视图里要统一结构冲突最典型的是商品分类文档里设计了商品大类、商品细分类两级结构而有的局部E-R图可能只画了一级合并时就要补齐。现在很多工具可以辅助做这件事比如MySQL Workbench可以从表结构反向导出E-R图Navicat也有类似功能。但工具只能帮你画图帮你做不了冲突消解的判断。如果你最近在写课程设计我的建议是先手绘一遍分E-R图再用工具出总图这样对每个联系的基数比印象会深很多。4. 逻辑结构设计关系模式映射、规范化拆分与完整性约束落地4.1 从E-R图到初始关系模式12张表的映射起点文档3.1节给出了初始关系模式这是E-R图直接翻译过来的结果。按照3.2节那张联系表的转换策略可以得到一组关系模式我按实体和联系逐一列在这里会员登录名、密码、姓名、性别、生日、Email登录名做主码管理员管理员ID、密码、姓名、类别、工作任务商品商品ID、商品名、生产日期、厂商、保质期、ISBN、颜色、尺寸、价格、已售出数量、库存数量、用途、缩略图链接、图片、类别、适用人群订单订单编号、下单时间、可执行操作、发货单号、管理员ID、收货地址、订单状态、物流状态、订购ID、总金额购物车会员登录名、商品链接收货地址收件地址、收件人姓名、邮编、手机、电话已订购商品订购ID、订单ID、ISBN物流公司公司名称、业务范围、物流费用发货单发货单号、寄件人姓名、寄件人地址、店铺名称、收件人姓名、收件人地址、收件人联系方式、商品价格、物流公司名称店铺店铺网址、主营商品商品大类大类ID、大类名称商品细分类细分ID、细分类名、大类ID。这份初始模式可以直接看出问题订单表里混了收货地址、管理员ID、发货单号、订购ID四个本应独立的信息仓储味道很重。接下来的规范化就是要把这些混合拆分干净。下面用一段建表SQL演示会员、商品、订单、订单明细四张核心表在规范化之后的形态这四张表就是前面E-R图和关系模式映射的直接落地CREATE TABLE member ( member_id INT AUTO_INCREMENT PRIMARY KEY COMMENT 会员ID自增主码, login_name VARCHAR(50) NOT NULL UNIQUE COMMENT 登录名业务唯一键, password_hash VARCHAR(255) NOT NULL COMMENT 密码哈希不存明文, real_name VARCHAR(50) COMMENT 姓名, gender CHAR(1) COMMENT 性别M/F, birthday DATE COMMENT 生日, email VARCHAR(100) COMMENT 邮箱用于找回密码, created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 注册时间 ) ENGINEInnoDB COMMENT会员信息表; CREATE TABLE product ( product_id INT AUTO_INCREMENT PRIMARY KEY COMMENT 商品ID自增主码, isbn VARCHAR(20) UNIQUE COMMENT ISBN/条形码唯一键, product_name VARCHAR(100) NOT NULL COMMENT 商品名称, category_id INT COMMENT 归属细分类ID外码指向商品细分类, price DECIMAL(10,2) NOT NULL CHECK (price 0) COMMENT 售价必须大于0, stock INT NOT NULL DEFAULT 0 CHECK (stock 0) COMMENT 库存量不允许负数, sale_count INT DEFAULT 0 COMMENT 已售数量用于销售排行, manufacturer VARCHAR(100) COMMENT 生产厂商, production_date DATE COMMENT 生产日期, shelf_life INT COMMENT 保质期单位天 ) ENGINEInnoDB COMMENT商品信息表; CREATE TABLE orders ( order_id INT AUTO_INCREMENT PRIMARY KEY COMMENT 订单ID, order_no VARCHAR(20) NOT NULL UNIQUE COMMENT 外部订单号业务唯一, member_id INT NOT NULL COMMENT 下单会员ID外码, address_id INT NOT NULL COMMENT 收货地址ID外码, status TINYINT NOT NULL DEFAULT 0 COMMENT 订单状态0待付款 1已付款 2已发货 3已完成 4已取消, total_amount DECIMAL(10,2) NOT NULL CHECK (total_amount 0) COMMENT 订单总金额, created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 下单时间, CONSTRAINT fk_orders_member FOREIGN KEY (member_id) REFERENCES member(member_id), CONSTRAINT fk_orders_address FOREIGN KEY (address_id) REFERENCES shipping_address(address_id) ) ENGINEInnoDB COMMENT订单主表; CREATE TABLE order_item ( item_id INT AUTO_INCREMENT PRIMARY KEY COMMENT 明细ID, order_id INT NOT NULL COMMENT 所属订单ID外码, product_id INT NOT NULL COMMENT 商品ID外码, quantity INT NOT NULL CHECK (quantity 0) COMMENT 购买数量, unit_price DECIMAL(10,2) NOT NULL COMMENT 下单时快照单价防止商品改价后订单金额对不上, CONSTRAINT fk_item_order FOREIGN KEY (order_id) REFERENCES orders(order_id), CONSTRAINT fk_item_product FOREIGN KEY (product_id) REFERENCES product(product_id) ) ENGINEInnoDB COMMENT订单明细表;这段SQL里有几个参数是照着前面数据字典语义设计的订单状态用TINYINT而不是字符串因为程序里枚举判断比字符串比较快状态流转也更清晰unit_price单独存快照价而不是关联商品表的实时价这是订单系统最常见的处理方式否则商家一改价历史订单的金额就失真了。每个字段都加了COMMENT这在课程设计文档里是加分项说明你对自己设计的每个字段都有明确语义。4.2 规范化检查订单表的传递依赖是怎么拆掉的规范化是逻辑结构设计的核心章节。文档3.2节关于数据模型的规范化核心就是把初始关系模式逐级推到3NF。推演的关键在订单表初始模式的订单订单编号、下单时间、可执行操作、发货单号、管理员ID、收货地址、订单状态、物流状态、订购ID、总金额存在多个问题。先看1NF要求字段不可再分。初始模式里“收货地址”是一个复合概念收件人、街道、邮编、电话混在同一个字段里不符合1NF所以要拆成独立的收货地址表收件地址、收件人姓名、邮编、手机、电话。再看2NF要求非主属性完全依赖主码订单表的主码是订单编号但“订购ID”这个字段其实属于订单明细和订单编号是部分依赖关系要拆出去形成已订购商品表。最后是3NF要求没有传递依赖订单表里“可执行操作”这个字段实际上由“订单状态”决定——待付款时可执行操作是付款已发货时可执行操作是确认收货这就是典型的传递依赖正确做法是把可执行操作从订单表里删掉由程序根据status字段动态生成。这轮拆完订单表只剩订单编号、下单时间、发货单号、管理员ID、收货地址ID、订单状态、物流状态、总金额全部直接依赖订单编号。其他表同理会员表、商品表相对规整主要问题在多对多联系产生的中间表。规范化的代价是查询要关联更多表但换来的是一致性和可维护性课程设计层面更看重后者这个取舍要心里有数。4.3 主码、外码、完整性约束三种约束的落地写法文档3.3节专门讲了关系主码、完整性和其他约束条件的设计。完整性约束分三类落地到SQL时分别对应不同的写法。实体完整性靠主码实现建表时PRIMARY KEY自动保证主码非空且唯一参照完整性靠外码实现FOREIGN KEY约束可以定义在子表上也可以加上ON DELETE CASCADE做级联删除用户定义完整性靠CHECK约束和NOT NULL实现。ALTER TABLE orders ADD CONSTRAINT chk_orders_status CHECK (status IN (0,1,2,3,4)), ADD CONSTRAINT chk_orders_amount CHECK (total_amount 0); ALTER TABLE product ADD CONSTRAINT chk_product_price CHECK (price 0), ADD CONSTRAINT chk_product_stock CHECK (stock 0);CHECK约束这个参数要特别注意如果用的是MySQL 8.0.16以下版本CHECK约束只解析不执行建了等于白建真正的校验得靠应用层写。生产级做法是把价格、库存这类强约束放在数据库层和业务层双重校验数据库层兜底业务层给用户友好提示。5. 物理结构设计与避坑排查索引、权限设置和五个常见翻车点5.1 数据库选型与索引设置不要迷信“越多越快”物理结构设计章节文档给了三个选型MySQL、SQL Server、Oracle。对课程设计来说MySQL足够了完全免费、InnoDB支持事务、网上案例多。选型定了之后索引设置是物理设计里最实操的部分文档里提到商品推荐按销量排行、商品按分类查询、订单按用户管理这几条业务路径都应该有对应索引。常见的索引设计思路就是WHERE子句里的条件列、ORDER BY的排序列、JOIN的关联列这三类列优先考虑加索引。CREATE INDEX idx_order_member ON orders(member_id); CREATE INDEX idx_order_created ON orders(created_at); CREATE INDEX idx_product_category ON product(category_id); CREATE INDEX idx_product_sale ON product(sale_count DESC);这里面idx_product_sale用的是降序索引因为销售排行是“销量从多到少”如果业务上高频跑这个查询降序索引能省一次反向排序。但索引不是越多越好这一点经常有人栽跟头每个索引在INSERT和UPDATE时都要同步维护索引多了写性能会明显下降。课程设计阶段每张表一到三个索引足够了从高频查询反推不要为了“看起来专业”给每个字段都建索引。5.2 安全性设计三层权限控制怎么落文档里安全性和用户权限设计提到管理员身份验证、不同身份级别只能做相关操作。落到实际可以拆成三层应用层登录认证、数据库层账号权限、敏感字段加密。数据库层的权限控制用MySQL的账号和授权机制实现课程设计做到这一层已经超出大多数同学的水平了。CREATE USER shop_applocalhost IDENTIFIED BY StrongPass123; GRANT SELECT, INSERT, UPDATE, DELETE ON shop.* TO shop_applocalhost; CREATE USER shop_adminlocalhost IDENTIFIED BY AdminPass456; GRANT ALL PRIVILEGES ON shop.* TO shop_adminlocalhost;这样拆的好处是应用被注入或者账号泄露时攻击者拿到的只是一个受限账号没法直接DROP表。文档里后台管理系统把管理员和员工按职能分权限对应到数据库层面就是多个低权限业务账号加一个高权限管理账号每个账号只授予完成本职工作所需的最小权限集合。密码字段也别存明文用哈希加盐存储这是数据库设计的基本素养。5.3 避坑排查这五个翻车点我基本都踩过做数据库设计文档踩坑是必然的这份文档本身也不是完美无缺。下面五条都是常见问题把现象、原因、解决写清楚你做到这些就能少走弯路。坑一E-R图里的联系基数比和文字描述打架。现象文档里写“会员和购物车之间一个会员只有一个购物车而购物车可以被多个会员使用”但标注的关系却是1:N文字描述和基数比不一致。 原因需求分析阶段对业务理解不彻底购物车到底是“会话级”还是“持久化实体”没想清楚。 解决做设计文档时先把每个联系的基数比写成一句话业务规则规则和标注冲突时以业务规则为准。购物车通常按会员ID唯一归属设计一个会员一个购物车更合理按1:1处理。坑二N:M联系漏拆中间表。现象按文档关系模式建库发现商品和商品细分类之间没法直接关联外码不知道该放哪边。 原因建表时直接照抄实体表没把N:M联系转换成独立中间表。 解决对照联系表检查每一组N:M中间表必须建。文档里会员-收货地址、管理员-订单、商品大类-细分类、商品-细分类这四组都是N:M一张中间表都不能少。坑三数据流清单和图对不上。现象数据流程图改了版本数据字典里的数据流清单没同步更新文档前后矛盾。 原因数据流是按子系统分开画的清单却是全局编号改某一处时很容易漏掉另一处。 解决每改一条数据流立刻同步更新编号、来源、去处三列并在图上用荧光笔标记改动链路验收前花十分钟逐条核对。坑四规范化拆表之后查询性能崩了。现象订单、订单明细、商品、地址拆成四张表后列表页查询要JOIN五张表响应时间明显变慢。 原因规范化解决的是一致性问题但过度规范化会让查询路径变长课程设计里数据量小不明显生产环境会放大。 解决规范化做到3NF即可不要在课程设计里炫技拆到BCNF或4NF。如果某个查询高频且JOIN复杂可以建一个冗余的汇总表或加物化视图。坑五索引建太多写入卡顿。现象每张表建了六七个索引录入商品信息时明显变慢。 原因忽略索引维护成本把“索引能加速查询”理解成了“索引越多越好”。 解决参考5.1的规则只针对高频查询的过滤列和排序列建索引每张表不超过三个。写完索引后实际跑一下EXPLAIN看是否真的被用到别让索引变成摆设。6. 把文档变成能跑的库三步一致性验证技巧设计文档写得再漂亮最后都要落到一张张能建出来的表上。我拿到任何一份数据库设计文档包括这份电子商店系统都会强制走一遍“数表、数外码、数中间表”的三步验证这三步能拦住绝大多数文档和实际建库对不上的问题。第一步把文档里的关系模式清单和E-R图实体逐一比对数一遍最终应建的表数量。第二步列出所有外码用SQL反向查information_schema核对实际外码数量和设计数量是否一致。第三步数N:M中间表凡是在E-R图里标了N:M的联系强行检查是否都有对应的中间表缺一张都不行。下面这条查询就是第二步的落地写法SELECT TABLE_NAME, COLUMN_NAME, CONSTRAINT_NAME, REFERENCED_TABLE_NAME FROM information_schema.KEY_COLUMN_USAGE WHERE CONSTRAINT_SCHEMA shop AND REFERENCED_TABLE_NAME IS NOT NULL ORDER BY TABLE_NAME;这条SQL从元数据层把库里的全部外码捞出来和设计文档的外码清单逐条对。如果查出来的结果比设计少大概率是建表时漏了FOREIGN KEY如果比设计多可能是多余的冗余外码会影响后续维护。第三步的中间表检查没有捷径就是把E-R图上的N:M联系列成清单一张一张手工核对。这套验证方法是我在一次课程设计答辩上翻车之后总结出来的。当时我的设计文档里画了会员-收货地址的N:M联系建库却只建了两张表老师一眼就看出来外码缺失那一次被批得很狼狈。从那以后我不管做课程设计还是做正经项目交付前都强制走一遍“数表、数外码、数中间表”三步验证十分钟就能把文档和库的一致性确认到位。这套流程也适合你手头正在写的任何一份数据库设计文档希望帮到你。本文还有配套的精品资源点击获取