Office中国论坛/Access中国论坛

标题: 请教数据表的规划 [打印本页]

作者: 简    时间: 2011-5-26 10:32
标题: 请教数据表的规划
我知道,为了避免数据的重复,实施参照完整性,在数据表里需要采用一对多,一对一等关系,我想了解两个问题:
1.有没有必要建立关系?有个朋友给我说,没必要建立关系之类的,因为在窗体输入数据时就可以判断和确定数据之间的关系。
2.像我这附件里的几个表,应该如何规划才合理呢。
这几个表是:tblgr(工人)tblgx(工序)
tblgxgr(工序下的工人,字段值是工序和工人的名称)
[attach]45687[/attach]

tblgxgr_id(工序下的工人,字段值是工序和工人的id)
[attach]45688[/attach]

那么,从数据库的后期设计比如窗体,查询,报表等及维护来看,工序下的工人表应该采用tblgxgr表好还是tblgxgr_id表好呢,为什么呢。

附件:  [attach]45689[/attach]


作者: roych    时间: 2011-5-26 11:14
1、尽管建立了关系可以级联删除,便于删除相关的所有记录,但这并不少非做不可的。像我们公司用的几个系统都没有建立。需要删除信息时怎么办呢?写一个宏,来执行多个删除查询就是了。这些见仁见智,看LZ具体情况吧。
2、像LZ这个,个人觉得tblgxgr-id没有存在的必要。一个tblgx和tblgxgr就够了,把后面这个绑定到窗体,而tblgx作为录入的组合框选择就行了。不知道LZ觉得怎么样?
作者: 简    时间: 2011-5-26 15:12
roych 发表于 2011-5-26 11:14
1、尽管建立了关系可以级联删除,便于删除相关的所有记录,但这并不少非做不可的。像我们公司用的几个系统都 ...

以前我在论坛上遇到一个朋友,他是不用关系,而且他不用查询,宏,至于查询和宏,他都是用代码来确定,但他也强调,表结构很关键,表结构做好了,后面的设计就做好一半了。

我也不知我是怎么的,老是在关系和用代码确定数据关系中游离不定,总想弄清什么名堂,但又说不清楚我到底想要知道什么。

tblgxgr-id表在该数据库中是显得多余,但我看见很多数据库里,往往选择的是类似tblgxgr-id结构的表,而不是类似tblgxgr结构的表。在该数据库里,我之所以考虑tblgr工人表,是想到工人的排序,比如用工号grid排序。


作者: pq318    时间: 2011-5-26 15:16
首先我觉得有个问题要清楚啊,首先不用关系的后果相信地球人都知道,还有你的编码技术强的话,为何不多用用代码呢,我还是喜欢程序之美
作者: roych    时间: 2011-5-26 16:08
建议LZ还是做下查询吧。毕竟这比写代码直观多了,而且修改起来也更方便。无论怎么说,软件总不会是一劳永逸,而是需要根据实际变化做一些调整的。
作者: aslxt    时间: 2011-5-26 21:02
我建议用关系,表结构规划和关系搞好以后,后面的工作简单得很多。
作者: szyewj    时间: 2011-5-27 00:09
一、内容决定形式;二、表的不可拆分性(避免数据的重复)。因此,一个tblgx和tblgxgr就够了,如图:

作者: szyewj    时间: 2011-5-27 00:12
额,图太小了

作者: szyewj    时间: 2011-5-27 00:15
汗啊,第一次发图,不好意思

作者: todaynew    时间: 2011-5-27 11:42
本帖最后由 todaynew 于 2011-5-27 11:54 编辑
简 发表于 2011-5-26 10:32
我知道,为了避免数据的重复,实施参照完整性,在数据表里需要采用一对多,一对一等关系,我想了解两个问题 ...


1、无关系不成方圆。但是否在关系视图中建立关系不是最重要的,也就是说除了在关系视图中建立关系外,还可以在查询视图中建立关系,还可以在主子窗体中建立关系,还可以利用筛选建立关系等等。这个都是建立关系的手段和方法,但是不能想象完全没有关系的若干数据表能有什么用处。通常在关系视图中建立表或查询之间的关系是最简单、最直观的,一般来说还是应该利用关系视图来建立表间的关系,定义表间关系的属性。

2、单独的工序与工人建立一个数据表是没什么实际意义的。工序与加工的产品有关系,工人也与加工的产品有关系,也就是说只有存在一个加工任务,工人与工序才能联系起来,所以工人与工序的联系是在有关描述加工的数据表中存在的。
   这种存在可以根据情况出现两种表达方式,最通常的一种表达方式是基于工人所从事的工序是多种,此类情形中,工人和工序的特征字段(也就是ID值或者姓名)需要进入加工表中。另外一种情形是工人的工序岗位完全确定不会变化,这种情形下,工序应该存在与工人表中,也就是说每个工人都只对应一个工序。那么在加工表中只需要工人的特征字段就可以了。

3、以下的示例是基于第一种情形做的表结构设计:
[attach]45702[/attach]

[attach]45703[/attach]

4、在数据库表结构设计时,不应局部的看问题,更不应该割裂出一个局部来讨论全局性的问题。这样的话,永远说不清道不明。工序和工人是两个局部问题,如果没有一个加工任务的话,工序只存在于工艺设计员的设计方案中,工人也只是坐在车间喝茶聊天。这种情况下,工人和工序并不发生什么关系。只有生产任务下达了,工艺的加工图纸到了工人手中,材料齐备、设备启动,工人才会来到钳台或机器旁按照图纸进行他们的工作,工序和工人才发生了关系。这样去观察问题,就有了全局的和实际的视角,数据表的设计也就不是什么难事了。



作者: ycxchen    时间: 2011-5-27 12:17
工人的姓名、身份证号码等基本信息一般是不变的,但工序会变的,所以,我还是建议建立一对多关系,日后设立查询、窗体等方便,10楼版主已详细写了个例子,楼主要细心研究。
作者: 简    时间: 2011-5-27 15:19
谢谢楼上各位热心的朋友,让我懂得了不少东西。
作者: 简    时间: 2011-5-27 21:30
本帖最后由 简 于 2011-5-28 08:10 编辑

我想再请教一下,以todaynew老汉的表结构数据库为例,我想统计加工表中工序id为刨的个数,其程序代码该怎么写呢?

我原来写成me.txt0=DCount("*", "加工表", "[工序id]<> '刨'"),运行错误,我也知道原因是工序id值是长整型,而刨是字符型,类型不匹配。

那么,像这种情况,代码该怎么写呢?难道应该是:
me.txt0=DCount("*", "加工表", "[工序id]=1”)

根据工序id的字段值,我不一定能晓得刨对应1,车对应2,磨对应3呀……

还有,既然工序id值是长整型,为什么字段值能保存成字符型如刨,钳等呢。

在加工表中,我需要通过工序(或工人)进行大量的筛选查找,建立查询,报表等,这时在加工表中,我应该将工序(或工人)设计成工序id(工人id)好呢,还是工序名称(或工人姓名)好呢?

作者: todaynew    时间: 2011-5-28 19:52
本帖最后由 todaynew 于 2011-5-28 20:18 编辑
简 发表于 2011-5-27 21:30
我想再请教一下,以todaynew老汉的表结构数据库为例,我想统计加工表中工序id为刨的个数,其程序代码该怎么 ...


呵呵,鬼打架的,你也不能一口气搞这么多问题呀。

1、统计问题应该如下解法:
Dcount("*","加工表","工序id=" & Dlookup("工序id","工序表","工序='刨'"))

2、组合框或列表框的绑定值和其显示的字段可以不一样,通常我们都是将记录的ID作为绑定值,但又不想显示出id(因为id枯燥无味可理解性很差)。于是乎我们就将id的列宽度设置为0,而将要显示的字段列宽度设置为一定的长度。这个设置在表、查询的查阅中设置,如果是窗体的组合框或列表框控件,则在数据属性和格式属性中设置。
这个问题要这样去理解,你的组合框或列表款给你显示的值并不一定是保存的值,而绑定的值(也许你看不见它)才是你保存的值。

3、一个表的ID是标识一条记录唯一性的字段,也是若干张数据表之间建立关系的字段。所以通常外键要使用主表中的ID,这个观点与后期的数据查询和其他方面的使用方便与否没什么大的关系,或者说这一方法已经为数据的后期使用奠定了基础。比如说你希望查询出某个工序的数据,而加工表中又只有ID没有工艺名称,那么你可以以加工表为基础将工艺表和工人表拖入到查询设计视图中,将工艺名称和工人姓名字段拖入到查询中以此建立一个名曰“加工查询”的查询,并以这个查询作为子窗体的数据源就可以了。

[attach]45717[/attach]

[attach]45716[/attach]


作者: 简    时间: 2011-5-28 23:07
todaynew 发表于 2011-5-28 19:52
呵呵,鬼打架的,你也不能一口气搞这么多问题呀。

1、统计问题应该如下解法:

回todaynew老汉:

看了你的回复,我大概晓得应该如何处理了,但我心中还有个疙瘩没有解开。以你的表结构为例,我以往在没有考虑表结构时,在加工表里我就会如下图设置:
[attach]45719[/attach]

然后在子窗体里,对工序我设置如下:
[attach]45718[/attach]

我觉得这样的设置一目了解,不需要拐弯抹角,当然,关系也就不起作用了。
看了一些实例后,发现对于类似情况,它们在表结构上都没有像我这样设置和设计,而是通过关系,通过一对多,一对一之类的来处理。我就觉得挺奇怪,因为我没有发现我以前那样的设计有什么不妥,而且那样的设计也没有出现什么数据的重复性,相反我还认为我以前那样设计在程序代码上处理更方便,就比如统计在加工表里统计工序为刨的个数,如果用我以前的设计方法,即用工序字段,其代码就是:DCount("*", "加工表", "[工序]<> ''"),如果用工序id字段,代码Dcount("*","加工表","工序id=" & Dlookup("工序id","工序表","工序=''")),这还反而麻烦呢。

作者: 简    时间: 2011-5-28 23:49
还有:

我看前面有两个朋友认为,只需要tblgx表(工序表)和tblgxgr表(工序下的工人)两个表即可,为什么他们会有这样考虑呢。如果工人较多,近百个,是不是还是单独建立工人表要好些呢。

另外todaynew老汉说,工人与工序的联系是在有关描述加工的数据表中存在的。这种存在可以根据情况出现两种表达方式……所以老汉建立工序表,工人表,以及让工序和工人发生联系的加工表。

我建立tblgxgr表的目的,一是生产的实际情况,有工人从事两个工序,比如说张三工人在刨和铣两个工序里操作。二是为了提高输入效率,三是在筛选工人时缩小选择范围,四是为了统计的需要。比如说,我要输入工人彭五的名字,打字慢的同事不想输入的话,可能就在组合框里挨个挨个找,如果知道彭五所属的工序是磨的话,就可以先在工序组合框里选择磨,然后在工人组合框里就自动筛选出磨工序下有哪些工人,这样就可以快速选择出彭五工人来。为了统计的需要,打个比方说,我需要了解这个月刨工序接受了多少加工任务,产量是多少等,即按工序来进行统计。

这样分析来,tblgxgr表还有没有必要单独建立呢。

作者: todaynew    时间: 2011-5-29 10:12
本帖最后由 todaynew 于 2011-5-29 13:42 编辑
简 发表于 2011-5-28 23:49
还有:

我看前面有两个朋友认为,只需要tblgx表(工序表)和tblgxgr表(工序下的工人)两个表即可,为什么他 ...


你还没有理解数据库设计的基本原理,呵呵。对于你的这几个问题,需要用倒叙来加以说明了。先从最后的问题来说吧。

  1、所谓工人表其实不应该是工人表,而应该是员工表。一个管理系统通常需要涉及到人,为什么呢?因为人是生产力的第一要素,没有人什么事情都办不成。就一个企业来看,人员所从事的工作是多方面的,有从事管理的管理干部、销售人员、财务人员、劳资人员等等,有从事技术工作的设计人员、检验人员等,还有从事一线生产人员的工人等等。人员有其共性,比如他们都有姓名、性别、年龄、岗位、隶属的部门等等,员工表所起的作用就是独立的保存这些有共性的信息。
  也就是说,我们通常应该把具有相同属性的一类对象用一张数据表来保存数据,企业管理的要素无法是人财物,以及人财物相互作用的各种过程各种结果。这些东西经过合理的分类,都可以形成相对独立而又有联系的对象,数据库的设计就是将这些对象数据化的分配到各个数据表中,并通过关系这样一些手段,来描述他们之间的联系。
  数据表大体上可以分为两类,一类是诸如员工表、部门表、产品表、材料表、工艺表、检验项目表等等,他们的特点是与时间的联系不紧密,也就是相对于时间的变化很小,这些数据表我们称之为基础资料。还有一类数据表是与时间紧密联系的(可能时间是隐形的),比如订单表、销售表、入库表、加工表等等,这些数据表我们可称之为动态数据。
  一般来讲,动态数据的数据表中都会存在基础资料数据表的ID,比如课程表中存在班级ID、学科ID和教师ID,加工表中存在工序ID、员工ID、材料ID。保存基础资料表中的ID,而不是保存基础资料表中的部分字段或全部字段,就是为了减少数据冗余。由于数据表的ID唯一性的定义了一条记录,所以保存数据表的ID也就是保存了该条记录。
  数据表的ID是强调数据表中记录的唯一性,但并不是说数据表的其他字段不能替代这个功能,比如说工艺表的工艺名称,员工表的姓名(只要企业内没有重名的职工),所以在某些情形下,数据表是可以不必单建ID字段的。但是通常我们都愿意单独建立ID字段,这又是为什么呢?这是因为对每个数据表单独建立ID可以统一ID的数据类型和编码规则,这样就对后期的编程按照统一的规则进行数据处理提供了方便。
  简言之,一个管理系统中一定需要建立一个人员表(可以叫做学生表、教师表、员工表、用户表等等),也一定需要设一个人员ID字段。

  2、简化操作特别是简化录入操作的问题,与数据表结构设计有关系但不是影响数据表设计的根本原因,也就是说在数据表设计阶段可以暂不考虑录入问题的简化,只需考虑一般的设计规范。筛选人员的方法有多种手段,比如可以用姓氏筛选,还可以用拼音助记码筛选,还可以用部门组合框加人员组合框联级筛选等等,工序的筛选和统计也是一样。这些操作都与数据表设计没什么太大关系,只是后期的处理技巧而已。

  3、DCount("*", "加工表", "[工序]= '刨'")的简单与Dcount("*","加工表","工序id=" & Dlookup("工序id","工序表","工序='刨'"))的麻烦,实际上是一个战略和战术的问题。红军长征时四渡赤水,连续走了几个大的迂回,当时部分指战员包括林彪、彭德怀等军团司令员都不理解,认为不应该走弓背而应该走弓弦。但最后的实践证明,毛泽东在运动中调动敌人消灭敌人摆脱敌人的战略是正确的。也就是局部的麻烦,不代表全局的麻烦,牺牲局部才可能带来全局的胜利。这就是我前面反复强调的全局性的观念、全局性的视角、全局性的思维。加工表中我们不用一个文本型的汉字字段作为ID,而以一个自动编号的数字型的字段作为ID,在统计时可能有些麻烦,但在做筛选、运算、排序等等方面都极大的简化了。花费了一个语句的麻烦,带来了几个语句,数十种处理的简化,你说是麻烦还是简单呢?
  在数据库设计时,要有进得去出得来的本领。所谓进得去,是指能关注到细微末梢的各种情况各类情形;所谓出得来,是指能忽略细节,站在全局的高度看问题。只有这样才能不畏浮云遮望眼,只缘身在最高层,否则就是一叶障目不见泰山了。

  4、最后再强调两点。第一点是数据库的设计一定要以表结构设计为基础,这个问题通常被初学者所忽视,我经常看见版友上传的问题实例中,表结构不合理的占绝大多数。不合理的表结构会带来一系列的麻烦,而合理的表结构可使程序极大的简化。第二点是初学者一定要使用关系视图来建立表间关系,Access中的这个工具非常好,它图示化的直观描述了数据关系,对于判断表结构是否合理有重要作用。我个人的体会是,如果关系视图中的连线交错的特别复杂,一定是表结构设计出现了问题,在这种情况下我会对表结构进行调整,使表间关系简洁明了。

作者: ycxchen    时间: 2011-5-29 14:56
老汉真是顶级老师,说理很详细,难得!
作者: 简    时间: 2011-5-29 16:11
todaynew 发表于 2011-5-29 10:12
你还没有理解数据库设计的基本原理,呵呵。对于你的这几个问题,需要用倒叙来加以说明了。先从最后的问 ...

谢谢老汉,让你费心了,能不能将就我的例子进行修改,让我再好好学习与消化呢。
作者: todaynew    时间: 2011-5-29 16:24
简 发表于 2011-5-29 16:11
谢谢老汉,让你费心了,能不能将就我的例子进行修改,让我再好好学习与消化呢。

14楼的例子应该能说明问题了。
作者: 简    时间: 2011-5-30 09:22
todaynew 发表于 2011-5-29 16:24
14楼的例子应该能说明问题了。

老汉,我还有些疑惑没有解决。

以你的表结构为例,当我在工序id里选择刨时,我希望工人id组合框里显示张三和王二,而不是所有工人。换句话说,张三和王二都是属于刨工序的。这种情况表结构和关系如何设计呢?

还有,如果张三既属于刨工序,又属于钳工序,九九既属于铣工序,又属于磨工序,这种情况下,表结构和关系又如何处理呢?

[attach]45728[/attach]

作者: 简    时间: 2011-5-30 11:24
我在主窗体里输入数据时发现一个问题,就是工序id和工人id的数据必须输入,否则就会弹出错误提示,但在实际操作中,却有可能因种种原因出现数据没有全部输完,然后点击保存的情况,然后等数据核对清楚,或者有时间时再继续将数据补充完整。
这种情况又如何解决呢,能否躲开呢?
作者: todaynew    时间: 2011-5-30 12:02
本帖最后由 todaynew 于 2011-5-30 12:18 编辑
简 发表于 2011-5-30 09:22
老汉,我还有些疑惑没有解决。

以你的表结构为例,当我在工序id里选择刨时,我希望工人id组合框里显示 ...


呵呵,怎么还不明白。筛选和表结构没什么关系。
1、前面的示例不是已经可以完成筛选功能:
[attach]45729[/attach]

2、这个示例就是基于工人可能从事多工种设计的,表结构不需做什么修改,你可以在这个示例中测试一个工人多工种的情况。

3、对于工序ID和工人ID不能同时输入的处理方法有多种,常用的有这样两种方法。第一种方法是,在关系视图中编辑关系属性,将“实施参照完整性”的勾选去掉。第二种方法是,在工人表中的工人字段加一个【待确定】的记录(如果工艺开始录入时也存在不确定的情况可以比照处理),录入数据不能确定时就选这条记录。当能确定工人后,再对该条记录进行更改。我一般喜欢采用第二种方法,《下里巴人》一文中有这样的处理,可以参见一下。

4、你目前所提到的所有问题,都不对表结构设计产生实质性的影响。所以还是那句话,先从数据分类的合理性出发建立表结构,不必操心后期的处理,后期处理可依据数据表结构有丰富多彩的手段。


作者: 简    时间: 2011-5-30 13:06
todaynew 发表于 2011-5-30 12:02
呵呵,怎么还不明白。筛选和表结构没什么关系。
1、前面的示例不是已经可以完成筛选功能:

我想你可能没完全明白我的意思。
我这个筛选不用于模糊查询,我希望是在输入数据时,比如在你的子窗体里输入数据时,当我在工序id里选择刨时,我希望工人id组合框里显示张三和王二,而不是所有工人。
作者: todaynew    时间: 2011-5-30 14:27
简 发表于 2011-5-30 13:06
我想你可能没完全明白我的意思。
我这个筛选不用于模糊查询,我希望是在输入数据时,比如在你的子窗体里 ...

那很简单嘛。先做一些数据到加工表中,工人ID与工序ID就建立了关系,然后用加工表为基础来联机筛选就可以了。
作者: todaynew    时间: 2011-5-30 18:22
本帖最后由 todaynew 于 2011-5-30 19:22 编辑
简 发表于 2011-5-30 13:06
我想你可能没完全明白我的意思。
我这个筛选不用于模糊查询,我希望是在输入数据时,比如在你的子窗体里 ...

1、联级筛选可利用加工表的数据进行,实例中已处理。

2、关于复制粘贴的问题,可以采用选定记录后追加部分字段的数据的方法来解决。如果不想另外设计按钮,可以采用自定义窗体快捷菜单的方式来解决。具体方法是写两个函数,一个函数叫做复制其功能是记住选定记录的ID值(记住的方法可以采用一个全局变量,点击快捷菜单的复制按钮时,将ID值赋值给这个变量),另一个函数叫做粘贴(粘贴函数实际就是一个追加查询代码),然后将这个两个函数给快捷菜单的复制和粘贴按钮作为其操作功能。实例中做了一个类似的例子。

3、关于工人ID在录入时可能不完全确定的情况下,用一个【待确定】进行替代的例子在实例中进行了处理。


[attach]45734[/attach]

[attach]45735[/attach]

作者: 简    时间: 2011-5-30 21:31
todaynew 发表于 2011-5-30 18:22
1、联级筛选可利用加工表的数据进行,实例中已处理。

2、关于复制粘贴的问题,可以采用选定记录后追加 ...

联级筛选可利用加工表的数据进行——我看了实例,用的是联合查询,晕啊,我就想不通,为啥不单独建立tblgxgr表来建立工序工人之间的关系呢,用tblgxgr表来确定工序下的所属工人不更好吗,因为联合查询联合的是加工表和工人表,根据加工表中工序和工人的对应关系来建立的筛选,但这个筛选关系我觉得似乎不能适应未来的变化,比如张三调离了刨工序,李四辞职没在这个工厂工作了,这个时候加工表中刨工序里就没有张三,而车工序里也没有李四。

还有“待确定”的问题,我想问,为了应付实际中的问题,除了工人ID需要待确定外,是不是像工序ID,产品ID,还有类似一对多,一对一关系中一方的ID都需要待确定为好呢?
作者: cwang2005    时间: 2014-11-2 09:58
学习了,感谢版主的教导。




欢迎光临 Office中国论坛/Access中国论坛 (http://www.office-cn.net/) Powered by Discuz! X3.3