2021-05-06

基于新型邮政编码的快递管理系统

 

目录

基于新型邮政编码的快递管理系统

一、需求分析

1.1问题分析

1.2设计需求

二、概念结构设计

2.1 方案一

2.2 方案二

2.3 方案三

2.4方案论证

三、逻辑结构设计

3.1数据库表设计

四、创建数据库和表

4.1 SQL语句实现

4.2结果实现

五、数据测试

5.1 customer表

5.2 warehouse表

5.3 deliver表

5.4 entry 表

5.5 sendout表

5.6 package表

5.7 receiver表

5.8 sender表

六、SQL语句的实现

6.1数据定义

6.2 数据查询 

6.3 数据更新 

  6.4 创建视图 

   6.5 授权 

  6.6 创建索引

 七、存储过程和触发器

7.1 运用存储过程的查询语句 

7.2 运用触发器的SQL语句 

八、小结


一、需求分析

1.1问题分析

  业内专家表示,新型邮编建设完成后,除了 ID 信息技术的革新,还将减少快递人力成本、配送成本、车辆成本等,极大提升配送效率,甚至将推动快递业进入无人时代。随着快递行业的迅速发展,现在许多人都在享受网购这种足不出户的购物方式。但是伴随着快递量的突增,许多快递公司不堪重负,丢件以及送错件的事件数见不鲜,如何有效降低这种情况的发生率,以及提高快递服务业的服务水平,已成为一个亟待解决的问题。

  而新型邮政编码的出现,可以大大提服务,虽然目前新型邮编只是在概念当中,相信不久的未来,新型邮政编码会走进生活的每一个角落。

1.2设计需求

  本设计以寄件人为主体,即,寄件人为事件的发生者,收件人为被动接收者,默认寄件人有多个收件人,收件人可以有多个地址,一个订单可以有多个包裹。而且寄件人和收件人在系统中快递系统中注册的手机号码唯一且不重复。 快递过程的开始为:寄件人生产入库订单。

  对于包裹 ID,本实验默认为 6 位数字字符构成。

  对于快递员编号,本实验默认为 2 位数字字符构成。

  在个人“唯一 ID”中,本实验默认为 6 位数字字符构成:00 代表性别为男,01 代表性别为女,后面 4 位为统一编码。

  对于地址 ID,本题限制如下:共由 6 位数字字符构成,前两位代表省和直辖市,后面四位为区域码(默认根据新型邮政编码每个地址点已标好相应的区域码)。

表 1-1:省市代码示例

01

02

03

04

05

06

07

08

天津市

河北省

上海市

深圳市

北京市

河南省

辽宁省

江苏省 

如:011234,代表天津市的某个具体地址。

作为入库订单,包含唯一订单编号,收件快递员,仓库号,收件人和寄件人ID以及地址,同时也包含入库时间,以及对应包裹的数量和总运费。

作为出库订单,包含唯一编号,分配派件快递员以及其他与入库对应的信息。

作为寄件人,在新型邮政编码的体系下,有自己身份的唯一 ID,同时可以拥有多个收件人,即收货地址,包括收件人地址和收件人手机号码。

对于被寄送的包裹,在新型邮政编码的体系下,拥有自己唯一的 ID,可以避免包裹的混乱。同时包裹还拥有订单号、类别、运费等。

作为收件人,与快递员通过手机号码进行联系,签收自己的包裹。

作为快递员,对应快递公司的人员对入库订单的地区分配进行收件,在仓储中根据包裹地址进行分拣,同时确定包裹ID。

二、概念结构设计

2.1 方案一

2.1.1 ER图

2021-05-06_第1张图片

2.1.2 关系模式

  • 用户(个人ID,姓名,手机号码,地址ID
  • 快递员(快递员编号,快递员姓名,快递公司)
  • 包裹(包裹ID,订单编号,包裹分类,运输费用)
  • 入库订单(订单编号,仓库编号,收件人ID,收件人地址,寄件人ID,寄件人地址,订单总额,入库日期,入库数量)
  • 出库订单(订单编号,仓库编号,快递员ID,收件人ID,收件人地址,寄件人ID,寄件人地址,订单总额,出库日期,出库数量)
  • 仓库(仓库编号,仓库名称,仓库总量,快递公司)

2.2 方案二

2.2.1 ER

2021-05-06_第2张图片

2.2.2 关系模式

  • 用户(个人ID,姓名,手机号码,地址ID
  • 快递员(快递员编号,快递员姓名,快递公司)
  • 包裹(包裹ID,订单编号,包裹分类,运输费用)
  • 出入库订单(订单编号,仓库编号,收件人ID,收件人地址,寄件人ID,寄件人地址,订单总额,日期,数量,类型)
  • 仓库(仓库编号,仓库名称,仓库总量,快递公司)

2.3 方案三

2.3.1 ER图

2021-05-06_第3张图片

2.3.2 关系模式

  • 用户(个人ID,姓名,手机号码,地址ID
  • 寄件人(寄件人 ID,姓名,手机号码,地址 ID
  • 收件人(收件人 ID,姓名,手机号码,地址 ID,寄件人 ID)
  • 快递员(快递员编号,快递员姓名,快递公司)
  • 包裹(包裹ID,订单编号,包裹分类,运输费用)
  • 入库订单(订单编号,仓库编号,收件人ID,收件人地址,寄件人ID,寄件人地址,订单总额,入库日期,入库数量)
  • 出库订单(订单编号,仓库编号,快递员ID,收件人ID,收件人地址,寄件人ID,寄件人地址,订单总额,出库日期,出库数量)
  • 仓库(仓库编号,仓库名称,仓库总量,快递公司)

2.4方案论证

对于方案一,我们考虑6个关系模式:用户、快递员、包裹、入库订单、出库订单以及仓库。该方案关系模式比较简单,但是没有直观的收件人、寄件人信息,考虑实际情况中,订单数和总用户的庞大数量,从入库订单和用户关系中查询收件、寄件信息是非常麻烦的。

对于方案二,我们考虑了5个关系模式,相较方案一,关系模式进一步简化,将出入库订单合成一个关系模式,“类别”属性为0是出库,1是入库。虽然关系模式简化了,但是后面进行仓库数量,订单金额的核算时,无法用到插入删除触发器。并且想分开查看入库和出库订单时,不如两个表便捷,虽然关系模式减少了,但是操纵变得复杂。

对于方案三,主要设计了8个关系模式:用户、寄件人、收件人、快递员、包裹、入库订单、出库订单以及仓库。用户为所有以身份证注册该系统的用户信息,一个订单可能对于多个包裹。寄件人首先填写入库订单,系统由入库订单自动导出寄件人表,根据寄件人地区实现仓库快递收件,包裹入库,仓库总量更新,包裹出库,自动导出出库订单,根据收件人地区自动分配快递员派送。

该方案相比方案一和方案二,收件寄件关系模式相比直接从入库订单查询收件寄件信息,更加精准、清晰的呈现个人信息;入库出库关系模式可以实现自动收件和派件,也可以依次自动更新仓库数量。缺点就是关系模式比较多,可能产生冗余。但总的来说,操作起来更加方便,描述的关系更加准确。

因此,我们选择方案三。

三、逻辑结构设计

3.1数据库表设计

       

表3- 1:用户(customer)表

序号

字段中文名

字段英文名

类型、宽度、精度

约束

备注

1

个人ID

cid

char(6)

联合主键

 

2

用户姓名

cname

varchar(20)

not null

 

3

手机号码

cphone

char(11)

not null

 

4

地址ID

aid

char(6)

联合主键

 

表3- 2:寄件人(sender)表

序号

字段中文名

字段英文名

类型、宽度、精度

约束

备注

1

寄件人ID

sid

char(6)

联合主键

 

2

寄件人姓名

sname

varchar(20)

not null

 

3

手机号码

sphone

char(11)

not null

 

4

地址ID

said

char(6)

联合主键

 

表3- 3:收件人(receiver)表

序号

字段中文名

字段英文名

类型、宽度、精度

约束

备注

1

收件人ID

rid

char(6)

联合主键

 

2

收件人姓名

rname

varchar(20)

not null

 

3

手机号码

rphone

char(11)

not null

 

4

地址ID

raid

char(6)

联合主键

 

5

寄件人ID

sid

char(6)

not null

 

 表3- 4:包裹(package)表

序号

字段中文名

字段英文名

类型、宽度、精度

约束

备注

1

包裹ID

pid

char(6)

主键

 

2

订单编号

eid

char(6)

not null

外键,来自入库订单表

3

包裹分类

pcate

char(10)

not null

 

4

运输费用

charge

numeric(8,2)

not null

 

表3- 5:快递员(deliver)表

序号

字段中文名

字段英文名

类型、宽度、精度

约束

备注

1

快递员编号

did

char(2)

主键

 

2

快递员姓名

dname

varchar(20)

not null

 

3

快递公司

dcom

varchar(30)

not null

 

表3- 6:入库订单(entry)表

序号

字段中文名

字段英文名

类型、宽度、精度

约束

备注

1

订单编号

eid

char(6)

主键

 

2

仓库编号

wid

char(6)

not null

外键,来自仓库表

3

快递员编号

did

char(2)

not null

外键,来自快递员表

4

收件人ID

rid

char(6)

not null

 

5

收件人地址

aid

char(6)

not null

 

6

寄件人ID

sid

char(6)

not null

 

7

寄件人地址

said

char(6)

not null

 

8

订单总额

total

numeric(8,2)

not null

 

9

入库日期

edate

datetime

not null

 

10

入库数量

enum

int

not null

 

表3- 7:出库订单(sendout)表

序号

字段中文名

字段英文名

类型、宽度、精度

约束

备注

1

订单编号

eid

char(6)

主键

 

2

仓库编号

wid

char(6)

not null

外键,来自仓库表

3

快递员编号

did

char(2)

not null

外键,来自快递员表

4

收件人ID

rid

char(6)

not null

 

5

收件人地址

aid

char(6)

not null

 

6

寄件人ID

sid

char(6)

not null

 

7

寄件人地址

said

char(6)

not null

 

8

订单总额

total

numeric(8,2)

not null

外键,来自入库信息表

9

出库日期

sdate

datetime

not null

 

10

出库数量

snum

int

not null

 

   表3- 8:仓库(warehouse)表

序号

字段中文名

字段英文名

类型、宽度、精度

约束

备注

1

仓库编号

wid

char(2)

主键

 

2

仓库名称

wname

varchar(20)

not null

 

3

仓库总量

wnum

int

not null

 

4

快递公司

wcom

varchar(30)

not null

 


四、创建数据库和表

4.1 SQL语句实现

4.1.1 customer表

create table customer(/*用户表*/
cid char(6) not null,
cname varchar(20) not null,
cphone char(11) not null,
aid char(6) not null,
primary key(cid,aid),
)

4.1.2 warehouse表

create table warehouse(/*仓库表*/

wid char(2) primary key,

wname varchar(20),

wnum int not null,

wcom varchar(30) not null,

)

4.1.3 deliver表 

create table deliver(/*快递员表*/
did char(2) primary key,
dname varchar(20),
dcom varchar(30) not null,
)

4.1.4 entry表

create table entry(/*入库订单表*/
eid char(6) primary key,
wid char(2) references warehouse(wid),
did char(2) references deliver(did),
rid char(6) not null,
raid char(6) not null,
sid char(6) not null,
said char(6) not null,
total numeric(8,2) not null,
edate datetime not null,
enum int not null,
)

4.1.5 sentout表

create table sendout(/*出库订单表*/
eid char(6) primary key,
wid char(2) references warehouse(wid),
did char(2) references deliver(did),
rid char(6) not null,
raid char(6) not null,
sid char(6) not null,
said char(6) not null,
total numeric(8,2) not null,
sdate datetime not null,
snum int not null,
)

4.1.6 package表

create table package(/*包裹表*/
pid char(6) primary key,
eid char(6) references entry(eid),
pcate char(10) not null,
charge numeric(8,2) not null,
)

4.1.7 receiver表

create table receiver(/*收件人表*/
rid char(6) not null,
rname char(20) not null,
rphone char(11) not null,
raid char(6) not null,
sid char(6) not null,
primary key(rid,raid),
)

4.1.8 sender表

create table sender(/*寄件人表*/
sid char(6) not null,
sname char(20) not null,
sphone char(11) not null,
said char(6) not null,
primary key(sid,said),
)

4.2结果实现

2021-05-06_第4张图片2021-05-06_第5张图片

五、数据测试

5.1 customer表

2021-05-06_第6张图片

5.2 warehouse表

2021-05-06_第7张图片

5.3 deliver表

2021-05-06_第8张图片

5.4 entry 表

2021-05-06_第9张图片

5.5 sendout表

2021-05-06_第10张图片

5.6 package表

2021-05-06_第11张图片

5.7 receiver表

2021-05-06_第12张图片

5.8 sender表

2021-05-06_第13张图片

六、SQL语句的实现

6.1数据定义

6.1.1 基本表的定义、删除和修改

create table sender(/*寄件人表*/

sid char(6) not null,

sname char(20) not null,

sphone char(11) not null,

said char(6) not null,

primary key(sid,said),

)

drop table receiver;/*删除表receiver*/

alter table sender add Sgender char(2);/*在sender表中加入属性列性别Sgender*/;

6.1.2 索引的建立和删除 

create unique index pindex on package(pid);/*创建package表中Pid的唯一索引*/

drop index Pindex on package;/*删除索引*/

6.2 数据查询 

6.2.1 from、where 子句 

select sid,said,sphone /*查询寄件人姓名为“蔡璐璐”的个人信息*/ 

from sender 

where sname='蔡璐璐'; 

6.2.2 group by、having 子句 

1)

select sid,count(rid) /*查询寄件人对应的的收件人的数目*/ 

from receiver 

group by sid 

having count(sid)>=1;

2)

select  pcate,count(pid)/*查询不同类别的包裹数量*/

from package

group by pcate

6.2.3 order by 子句 

select D.dname,P.pid/*查询快递员对应的运送包裹编码,按照包裹ID升序排列*/ 

from package P,deliver D,entry E

where P.eid=E.eid and E.did=D.did

order by P.eid;

6.3 数据更新 

6.3.1 插入数据

/*向 deliver 中插入编号为 25,姓名为何炅的顺丰快递员信息”*/

insert into deliver(Dno,Dname) values(25,'何炅');

  6.3.2 修改数据

update sender/*修改寄件人张霍霍的电话号码*/ 

set sphone=14789634567

where sname='张霍霍';

  6.3.3 删除数据

delete from deliver where Dname='何炅';/*删除 deliver 表中快递员何炅的信息*/

  6.3.4用户定义完整性

alter table warehouse/*为仓库表的数量属性增加约束条件,要求wnum不得超过*/

add constraint a1 check(wnum between 0 and 10000);

  6.4 创建视图 

6.4.1 创建寄件人快递信息视图

create view 蔡璐璐的快递信息一览表(eid,dname,rid,rname,raid) 

as 

select E.eid,D.dname,R.rid,R.rname,R.raid 

from receiver R,entry E,deliver D 

where R.sname='蔡璐璐' and 

R.rid=E.rid and 

R.raid=E.raid and 

E.did=D.did

with check option;

6.4.2 创建包裹信息视图

create view 包裹配送信息表(Pid,Dname) 

as 

select P.pid,D.dname 

from package P,deliver D ,entry E

where P.eid=E.eid and E.did=D.did;

   6.5 授权 

6.5.1创建角色并授权

create login 梦洁洁 with password='123456'

create user 梦洁洁 for login 梦洁洁 with default_schema=dbo

grant create role to 梦洁洁

  6.5.2把对sender表的查询权限授给用户user1

create role user1;/*把对sender表的查询权限授给用户user1*/

grant select on sender to user1

  6.6 创建索引

create unique index ssaid on sender(sid asc,said desc);

create unique index rraid on receiver(rid asc,raid desc);

create unique index caid on customer(cid,aid);

create unique index ddid on deliver(did);

create unique index eeid on entry(eid);

create unique index seid on sendout(eid);

 七、存储过程和触发器

7.1 运用存储过程的查询语句 

7.1.1 查询寄件人寄出的包裹的信息

-- =============================================

-- Author: <张雨佳>

-- Create date: <2020年11月15日>

-- Description: <查询寄件人寄出的包裹的信息>

-- =============================================

CREATE PROCEDURE pack_infm @sname varchar(20) 

as 

declare @pid char(6),@rid char(6),@rname varchar(20) 

BEGIN 

-- SET NOCOUNT ON added to prevent extra result sets from

-- interfering with SELECT statements.

if @sname is null 

begin 

print'该寄件人姓名不存在!请核实信息!' 

end 

end 

SET NOCOUNT ON; 

-- Insert statements for procedure here

SELECT @pid=P.pid,@rid=E.rid,@rname=R.rphone 

from sender S,package P,entry E,receiver R 

where S.sid=E.sid and P.eid=E.eid and R.rid=E.rid and

S.sname=@sname

print @sname 

print'的寄件信息为:' 

print @pid 

print @rid 

print @rname 

GO 

(1) 查询蔡璐璐的寄件信息:

USE [基于新型邮政编码的快递管理系统] 

GO 

DECLARE @return_value int 

EXEC @return_value = [dbo].[pack_infm] 

@sname = '蔡璐璐' 

SELECT'Return Value' = @return_value 

GO 

  (2) 查询成毅毅的寄件信息:

USE [基于新型邮政编码的快递管理系统] 

GO 

DECLARE @return_value int 

EXEC @return_value = [dbo].[pack_infm] 

@sname = '成毅毅' 

SELECT'Return Value' = @return_value 

GO 

7.2 运用触发器的SQL语句 

7.2.1 实现快递包裹按寄件人区域自动收件

-- =============================================

-- Author: <张雨佳>

-- Create date: <2020年11月15日>

-- Description: <快递自动收件>

-- =============================================

USE 基于新型邮政编码的快递管理系统 

GO 

/*将收件人地址在天津市的(ID前两位为)包裹交由编号为的快递员派送*/ 

CREATE TRIGGER updateDno ON entry

FOR insert 

AS

BEGIN 

declare @raid char(6),@dno char(2) 

declare aid_cursor cursor for select said from inserted 

open aid_cursor 

fetch next from aid_cursor into @said 

while @@FETCH_STATUS=0

begin 

select @said=said from entry 

if(@said='01%') 

update entry set did=01

else if(@said='02%') 

update entry set did=02

else if(@said='03%') 

update entry set did=03

else if(@said='04%') 

update entry set did=04

end 

if(@said='05%') 

update entry set did=05

else if(@said='06%') 

update entry set did=06

else if(@said='07%') 

update entry set did=07

else if(@said='08%') 

update entry set did=08

end 

END 

close aid_cursor 

deallocate aid_cursor 

GO 

7.2.2实现快递包裹按收件人区域自动派件

-- =============================================

-- Author: <张雨佳>

-- Create date: <2020年11月15日>

-- Description: <快递自动派件>

-- =============================================

CREATE TRIGGER updateDno ON sendout

FOR insert 

AS

BEGIN 

declare @raid char(6),@dno char(2) 

declare aid_cursor cursor for select raid from inserted 

open aid_cursor 

fetch next from aid_cursor into @raid 

while @@FETCH_STATUS=0

begin 

select @raid=raid from sendout

if(@raid='01%') 

update sendout set did=01

else if(@raid='02%') 

update sendout set did=02

else if(@raid='03%') 

update sendout set did=03

else if(@raid='04%') 

update sendout set did=04

end 

if(@raid='05%') 

update sendout set did=05

else if(@raid='06%') 

update sendout set did=06

else if(@raid='07%') 

update sendout set did=07

else if(@raid='08%') 

update sendout set did=08

end 

END 

close aid_cursor 

deallocate aid_cursor 

GO 

7.2.3存储过程和触发器实现仓库自动更新库存

--首先建立一个存储过程依据出库表和入库表的数据,更新库存表中的库存数量

CREATE PROCEDURE StorageUpdate AS

BEGIN

DECLARE cur_Product CURSOR  FOR

SELECT pid FROM warehouse

DECLARE @ID varchar(10)

DECLARE @Amount_In Int

DECLARE @Amount_Out Int

OPEN cur_Product    

FETCH NEXT FROM cur_Product INTO @ID

WHILE @@fetch_status = 0

BEGIN

    BEGIN

  UPDATE warehouse SET wnum=@Amount_In-@Amount_Out,

WHERE pid=@ID

END

FETCH NEXT FROM cur_Product INTO @ID

END

CLOSE cur_Product

DEALLOCATE cur_Product

END

--添加入库记录时,insert触发器

CREATE TRIGGER Entry_Insert

ON Entry

FOR INSERT 

AS 

UPDATE warehouse SET 

warehouse.wnum=warehouse.wnum+inserted.wnum,

FROM warehouse,inserted

WHERE warehouse.wid=inserted.wid

--删除入库记录时,delete触发器

CREATE TRIGGER Entry_delete

ON Entry

FOR DELETE

AS 

UPDATE warehouse SET 

warehouse.wnum=warehouse.wnum-Deleted.wnum,

FROM warehouse,Deleted

WHERE warehouse.wid=Deleted.wid

--更新入库记录时,用update触发器

CREATE TRIGGER Entry_Update

ON Entry

FOR UPDATE 

AS 

BEGIN

  UPDATE warehouse SET 

warehouse.wnum=warehouse.wnum-Deleted.wnum,

FROM warehouse,Deleted

WHERE warehouse.wid=Deleted.wid

UPDATE warehouse SET 

warehouse.wnum=warehouse.wnum-Deleted.wnum,

FROM warehouse,Deleted

WHERE warehouse.wid=Deleted.wid

END 

八、小结

通过本次数据库系统设计,我掌握了数据库设计的过程和方法,掌握了基本表、视图的创建,以及查询、插入、更新、删除等基本语句的使用,能够根据实际问题,自我设计存储过程和触发器,实现数据的自动管理。对于新型邮编有了更加深度的认识,尽管有些设计的关系模式并不能完美应用到现实生活中,但是通过自主设计的过程,我的个人能力有了很大的提升,这是基于理论课的一次完全自我设计的实践,在设计的过程虽然有困难,但是更多的是设计、查询、思考的乐趣。

 

你可能感兴趣的:(sql,数据库,mysql)