如何用关系模型为层次关系建模

nudter401 2008-01-13 11:33:23
一个企业的产品可分为三个等级:器件->模块->设备
比如某设备A下面有模块1,模块2,模块3,这三个模块又各由器件a,器件b组成
每个器件都是由某型号电阻、电容之类的物料组合生产出来

企业组织生产设备A一套,采购原料时候需要根据设备A的结构图,得到他所需的全部物料
事物是层次模型,但用关系模型建模 ,如何建表?

高人请指点

PS:设备A结构图就是指A下面有模块1,模块2,模块3,这三个模块又各由器件a,器件b组成
...全文
118 点赞 收藏 16
写回复
16 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
sp4 2008-01-16
已阅
回复
JiangHongTao 2008-01-16
下面的应该正确了
--一、建立三个表
--1、项目表(原材料、元器件、模块、设备等通称为项目)
--项目表(项目编号,项目名称)
create table item(id int,name varchar(10) primary key(id))
--2、配置表(除了原材料,其它的项目的配置全部记录在本表中)
--配置表(项目编号,子项目编号,需要数量)
create table con(id int,subid int,s int primary key(id,subid))
--3、库存表(包括材料、元器件、模块、设备等的库存)
--库存表(项目编号,库存数量)
create table sto(id int,s int primary key(id))
--二、获取生产某设备需要采购的原材料。
--1、定义变量,@item 为需要生产的项目,@s 为需要生产的数量,@t1,@t2为临时表
declare @t1 table(subid int,c int,s int)
declare @t2 table(subid int,c int,s int)
declare @item int,@s int
set @item = 1
set @s = 10
--2、获取数量
--获得最初的需要数量和库存数量,注意,在最初的需要数量中可能有些材料没有列出来,因为包含在更上级的项目中,不过没关系,后面会加进去。
insert @t1 select subid,a.s*@ss ,isnull(b.s,0) from con left join sto b on a.id = @item and a.subid = b.id
--检查是否包含不是最底层的项目,如果存在SUBID在con表中作为ID存在,则表明该subid还可以拆分,需要继续循环。
while exists (select * from @t1 x where exists(select * from con id = x.subid))
begin
--向下拆分一级,分为两个部分。
insert @t2
--将两个部分获得的数据进行进行SUBID汇总合并,因为可能不同项目拆分后会包含相同的下级项目,因此需要合并汇总。
select subid,sum(c),sum(s) from
--获取已经是最底层的项目,不需要参与参分,作为一个部分参与合并。
(select subid,c,s from @t1 where subid not in(select id from con)
union
--另一个部分全部为需要拆分的项目,通过CON表进行拆分,注意,拆分的时候顺便把需要数量和可存数量同步向下级计算数量。
select b.subid,a.c * b.s c,a.s * b.s s from @t1 a,con b where a.subid = b.id) c
--合并分组。
group by subid
--这句比价关键,就是上面说的,获取拆分后产生的新项目的库存,已有项目的库存在前面已经获取,就不能获取了。
update @t2 set s = a.s + b.s from @t2 a,sto b where a.subid = b.id and a.subid not in(select subid from @t1)
--循环赋值,清空@t1表,将结果赋给@t1,以便下一次循环。
delete @t1
insert @t1 select * from @t2
delete @t2
end
--3、显示需要采购的项目和数量,说明一下,整个设计思路是将配置表(con)的数量需要全部转换成最底层项目需要的数量,同时将对应的库存也转换成最底层项目的数量,这样相减就能得到需要采购的数量了。
select b.id,b.name,c - s from @t1 a,item b where a.subid = b.id and c-s> 0
回复
JiangHongTao 2008-01-16
还是有一个错误,忘了清空@t2表了。
放在赋值给@t1表的后面。
回复
JiangHongTao 2008-01-16
--获得最初的需要数量和库存数量,注意,在最初的需要数量中可能有些材料没有列出来,因为包含在更上级的项目中,不过没关系,后面会加进去。
insert @t1 select subid,a.s*@ss ,isnull(b.s,0) from con left join sto b on a.id = @item and a.subid = b.id
--检查是否包含不是最底层的项目,如果存在SUBID在con表中作为ID存在,则表明该subid还可以拆分,需要继续循环。
while exists (select * from @t1 x where exists(select * from con id = x.subid))
begin
--向下拆分一级,分为两个部分。
insert @t2
--将两个部分获得的数据进行进行SUBID汇总合并,因为可能不同项目拆分后会包含相同的下级项目,因此需要合并汇总。
select subid,sum(c),sum(s) from
--获取已经是最底层的项目,不需要参与参分,作为一个部分参与合并。
(select subid,c,s from @t1 where subid not in(select id from con)
union
--另一个部分全部为需要拆分的项目,通过CON表进行拆分,注意,拆分的时候顺便把需要数量和可存数量同步向下级计算数量。
select b.subid,a.c * b.s c,a.s * b.s s from @t1 a,con b where a.subid = b.id) c
--合并分组。
group by subid
--这句比价关键,就是上面说的,获取拆分后产生的新项目的库存,已有项目的库存在前面已经获取,就不能获取了。
update @t2 set s = a.s + b.s from @t2 a,sto b where a.subid = b.id and a.subid not in(select subid from @t1)
--循环赋值,清空@t1表,将结果赋给@t1,以便下一次循环。
delete @t1
insert @t1 select * from @t2
end
--3、显示需要采购的项目和数量,说明一下,整个设计思路是将配置表(con)的数量需要全部转换成最底层项目需要的数量,同时将对应的库存也转换成最底层项目的数量,这样相减就能得到需要采购的数量了。
select b.id,b.name,c - s from @t1 a,item b where a.subid = b.id and c-s>0

上面的方案有两个约定:
一个约定是采购的都是最底层项目,如果中间项目可以采购,则该方案存在问题。
另一个约定是不存在项目的循环配置,比如项目A需要配置B,项目B需要配置C,项目C需要配置A,所有在做项目配置表的程序的时候必须进行循环配置检查,如果出现循环配置,则不允许产生该配置。
至于生成项目配置图,我们可以看到这样的表结构本身就是一个树形结构,CSDN有很多关于树形结构的显示,在此就不描述了。

回复
-狙击手- 2008-01-15
关注
回复
nudter401 2008-01-15
JiangHongTao ,辛苦了,
我开始也类似建了表,这是具有可扩展性的设计,因为以后可能扩展到更高层次的封装,比如说系统级,
但这种建表方式进行齐套查询时最麻烦,其中复杂的逻辑把我搞晕了

你的那个while循环能不能给点注释?

多谢!
回复
JiangHongTao 2008-01-15
--还是错了,换成下面的语句
insert @t2 select subid,sum(c),sum(s) from (
select subid,c,s from @t1 where subid not in(select id from con) union
select b.subid,a.c * b.s c,a.s * b.s s from @t1 a,con b where a.subid = b.id) c
group by subid
回复
JiangHongTao 2008-01-15
insert @t2 select b.subid,a.c * isnull(b.s,1),a.s * isnull(b.s,1) from @t1 a left join con b on a.subid = b.id group by b.subid
--换成
insert @t2 select b.subid,sum(a.c * isnull(b.s,1)),sum(a.s * isnull(b.s,1)) from @t1 a left join con b on a.subid = b.id group by b.subid
回复
JiangHongTao 2008-01-15
前面的有些错误,修改如下:
--一、建立三个表
--1、项目表(原材料、元器件、模块、设备等通称为项目)
--项目表(项目编号,项目名称)
create table item(id int,name varchar(10) primary key(id))
--2、配置表(除了原材料,其它的项目的配置全部记录在本表中)
--配置表(项目编号,子项目编号,需要数量)
create table con(id int,subid int,s int primary key(id,subid))
--3、库存表(包括材料、元器件、模块、设备等的库存)
--库存表(项目编号,库存数量)
create table sto(id int,s int primary key(id))
--二、获取生产某设备需要采购的原材料。
--1、定义变量,@item 为需要生产的项目,@s 为需要生产的数量,@t1,@t2为临时表
declare @t1 table(subid int,c int,s int)
declare @t2 table(subid int,c int,s int)
declare @item int,@s int
set @item = 1
set @s = 10
--2、获取数量
insert @t1 select subid,a.s*@ss ,isnull(b.s,0) from con left join sto b on a.id = @item and a.subid = b.id
while exists (select * from @t1 x where exists(select * from con id = x.subid))
begin
insert @t2 select b.subid,a.c * isnull(b.s,1),a.s * isnull(b.s,1) from @t1 a left join con b on a.subid = b.id group by b.subid
update @t2 set s = a.s + b.s from @t2 a,sto b where a.subid = b.id and a.subid not in(select subid from @t1)
delete @t1
insert @t1 select * from @t2
end
--3、显示需要采购的项目和数量
select b.id,b.name,c - s from @t1 a,item b where a.subid = b.id and c-s>0
回复
JiangHongTao 2008-01-15
--一、建立三个表
--1、项目表(原材料、元器件、模块、设备等通称为项目)
--项目表(项目编号,项目名称)
create table item(id int,name varchar(10) primary key(id))
--2、配置表(除了原材料,其它的项目的配置全部记录在本表中)
--配置表(项目编号,子项目编号,需要数量)
create table con(id int,subid int,s int primary key(id,subid))
--3、库存表(包括材料、元器件、模块、设备等的库存)
--库存表(项目编号,库存数量)
create table sto(id int,s int primary key(id))
--二、获取生产某设备需要采购的原材料。
--1、定义变量,@item 为需要生产的项目,@s 为需要生产的数量,@t1,@t2为临时表
declare @t1 table(id int,subid int,s int)
declare @t2 table(id int)
declare @item int,@s int
set @item = 1
set @s = 10
--2、获取数量
insert @t1 select id,subid,s*@ss from con where id = @item
insert @t2 select @item
while exists (select * from @t1 x where not exists(select * from @t2 id = x.subid))
begin
insert @t2 select subid from @t1 where id in(select id from @t2)
update @t1 set s = a.s - isnull(b.s,0) from @t1 a left join sto b
on a.subid = b.id and a.subid in(select id from @t2)
delete @t1 where s = 0 or subid in(select id from @t2)
end
--3、显示需要采购的项目和数量
select subid,s from @t1
回复
nudter401 2008-01-15
首先谢谢各位
re1楼电阻、电容是基本物料,要维护其型号数量等库存信息
re2楼,加,但不多:)

另其他各楼,这个层次关系不是很简单的,设备可能直接引用器件,也可能直接包含基本物料
而且器件、模块、设备一旦生产完毕,作为一个整体,也编上物料编码和基本物料一同加入物料列表

组织采购时,我这套软件首先要做的就是查出一个设备下面的各个模块、器件已经生产多少了,购买原材料时,那些用于生产对应模块、器件的原材料就相应的去除已生产部分,防止重复购买
模型还是蛮复杂的
回复
liangCK 2008-01-13
帮顶有分吗?
回复
-狙击手- 2008-01-13
电阻、电容之类

---

这些要进表管理吗
回复
中国风 2008-01-13
器件-> 模块-> 设备

--------
分解之后的关系:
器件->模块
模块-> 设备
器件->设备

设备:
ID
Name
模块:
ID
Name
Class--引用设备

器件:
ID
Name
Type--引用模块
----------------
以上命名随手敲的


回复
dobear_0922 2008-01-13
一个企业的产品可分为三个等级:器件-> 模块-> 设备

-----------------
如果只有固定的三个等级,每一个等级建一个表就行了,
回复
JL99000 2008-01-13
也没什么好的方法,可以这样:

设备表:t_equipment 字段:ID_i int, ModelID_i int, EquipName_ch varchar(100)
模块表:t_model 字段: ID_i int, MachineID_i int, ModelName_ch varchar(100)
器件表: t_machine 字段: ID_i int, ObjectID_i int, MachineName_ch varchar(100)
物料表:t_object 字段: ID_i int, ObjectName_ch varchar(100)

这是一种,也可以换个顺序:

设备表:t_equipment 字段:ID_i int, EquipName_ch varchar(100)
模块表:t_model 字段: ID_i int, EquipID_i int, ModelName_ch varchar(100)
器件表: t_machine 字段: ID_i int, ObjectID_i int, ModelID_i int, MachineName_ch varchar(100)
物料表:t_object 字段: ID_i int, ObjectName_ch varchar(100)
回复
相关推荐
发帖
疑难问题
创建于2007-09-28

2.1w+

社区成员

MS-SQL Server 疑难问题
申请成为版主
帖子事件
创建了帖子
2008-01-13 11:33
社区公告
暂无公告