设为首页收藏本站Access中国

Office中国论坛/Access中国论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

12下一页
返回列表 发新帖
查看: 2158|回复: 17
打印 上一主题 下一主题

数据一致性与有效性的问题

[复制链接]
跳转到指定楼层
1#
发表于 2002-10-12 21:25:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
学数据库的人都知道,数据的一致性与有效性很重要,由于access没有触发器,要保证数据的一致性与有效性就成了一个问题,虽然可能通过定义表与表之间的关系和使用有效性规则解决一些问题,但是有些问题的解决则有些困难(至少对我而言是这样),例如:
有一个表,其中有一个字段是“科室” ,另一个字段是“姓名”,这两个都是必填的字段,而且都已经设置成“必填字段”,现在科室的值是“生产科”,姓名是“黄小二”,“黄小二”是“生产科”的员工,这没有问题,但是如果改变了这两值的其中的一个(例如“生产科”改成“销售科”),但另一个操作员忘了改变,这就变成“黄小二”是“销售科”的员工了,但“黄小二”并不是“销售科”的员工,“销售科”也没有“黄小二”这个人,这不是乱套了吗?这虽然是操作员录入时的错误,但怎样才能保证这样的错误不会发生呢?
还有,例如有一个表,有字段“购进价”与“销售价”,现在由于购进价提价了,操作员改变了“购进价”的值(变成10元),但忘了改变“销售价”的值(原为9元),这就变成“销售价”比“购进价”还小 ,这不就让公司赔本了吗?怎样才能保证这样的错误不发生呢?
再有,有一个表有字段为“已付款”和“付款日期”,如果“已付款”的值为“已付”,但“付款日期”将为必填,怎样才能保证“已付款”这“已付”时,但“付款日期”没有填的记录不能保存呢,而必须要求填写“付款日期”呢?
对于以上这些,我现在所能做到的只是提示操作员“记录不全”,但并不能阻止这样的记录的保存。请各位高手有何高见?
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 分享淘帖 订阅订阅
2#
发表于 2002-10-12 21:45:00 | 只看该作者
问题很好,但都不是ACCESS的错。
1.如设为两个表。"科室","员工"此不成问题
2.根据ERP系统来看这应该不是问题。如果售价应该变动则一定会记得改因为你要修改发票,不改打不出正确发票,打不出发票收不到钱(我所指的是西方作业方式:INVOICE,CREDIT NOTE,DEBIT NOTE)。本人建议不变动以前记录,而是象西方做法一样有变动会有另外模块处理来调整收入。如果售价不需变动亏是正确的。如果什么都不记得那只有下岗
3.不是问题,ACCESS能作到
3#
 楼主| 发表于 2002-10-13 04:11:00 | 只看该作者
看来我们得再详细地讨论这个问题,先讨论第一个问题吧(以一个医院管理系统为例,为简化,只列出一些相关的字段):
1、科室表:
ID   名称
1    内科
2    外科
3   妇科

2、职员表(其中“所在科室ID”与科室表的“ID”相连接,是一对多的关系,实施参照完整性):
ID  姓名           所在科室ID
1   黄小二       2
2   李明           1
3   张天           3

3、住院病人管理表(“住院科室ID”与“科室表”的ID连接,一对多关系;“主治医生ID”与“职员表”的ID相连接,一对多关系)
ID   病人姓名   住院科室ID   主治医生ID
1    陈月明       2                     1
2    何天           1                     2

4、现在用一个窗体输入“住院病人管理表”中的记录。与“住院科室ID”相关连的为“组合框”控件,它的值来自一个查询,这个查询查出所有的“科室”及科室的ID,结合列为2,列数为2;与“主治医生ID”相关连的控件也是“组合框”,其值来自一个查询,这个查询查出所在与“住院科室ID”相关的医生的姓名及ID,结合列为2,列数为2。在第一次录入值的时候是没有问题的,因为“主治医生ID”的值都是与“住院科室ID”相关的,不会出现住院科室为“内科”而主治医生却是“外科”的医生的问题。但是如果录入了一次这两个值之后,操作人员更改了“住院科室ID”的值,使其变成“外科”,但又忘了更改“主治医生ID”的值,这就产生了一条无效的记录。例如改变了第2条记录的“住院科室ID”的值,使其由“1”(内科)变成“2”(外科),但没有改变“主治医生ID”的值“2”(李明)〈程序不会也不能自动改变这个值,因为这个值是不确定性的;也不能将这个值清空,因为是必填字段,清空这个值将会出错,我现在所能做到的是给操作员一个提醒,提醒其注意更改“主治医生ID”的值,但不能完全避免这样的记录的保存。〉,即:

ID   病人姓名   住院科室ID   主治医生ID
1    陈月明       2                     1
2    何天           2                     2

显然,第2条记录是无效的,因为“2”(李明)并不是科室“2”(外科)的职员。当然,发生这样的因原是操作员的失误,而且发生的可能性也很小,但是,作为一位严谨的数据库开发者,考虑这样的问题也是职责所在,我们应尽可能地保证数据库中的数据是有效的。请问,如何才能更好的避免这样的无效数据的产生呢?解决的办法可能很简单,但是我不知道,请你们详细地告诉我好吗?
4#
发表于 2002-10-13 04:30:00 | 只看该作者
“但是如果录入了一次这两个值之后,操作人员更改了“住院科室ID”的值,使其变成“外科”,但又忘了更改“主治医生ID”的值”------------〉恕我直言,我的确看得不是太明白。有一点应该清楚再好的软件基本资料都是要人来输的。还有id如你所说操作人员可以更改,不明?----id应该是自动产生的
5#
 楼主| 发表于 2002-10-13 05:44:00 | 只看该作者
表的ID是自动生成,但连接的ID(例如“住院科室ID”、“主治医生ID)却是录入的,更确切地说,它们分在“科室表”与“职员表”中是自动生成,并且代表相应表中唯一的一条记录,但是它们在“住院病人管理表”中却是录入的,而且由于实施了参照完整性,只能录入
“科室表”与“职员表”中已自动生成了的ID值。明白吗?话说回头,你说得很对,数据是人录入的,不可避免地会产生错误,但把错误的发生率降到最低,则是做数据库的人的职责。
6#
 楼主| 发表于 2002-10-13 05:58:00 | 只看该作者
对于第二个问题,如果不作处理,并不是想象中的那么简单,因为销售的人并不是进货的人,而且对于一个联网的数据库来说,销售的人并不是一个,而且是多个,他们对货物的价格可能一无所知,货物是按照数据库中的“销售价”来售出的,发票也是按照这项数据来计算并打印的,打印发票的销售人员不可能知道所有货物价格的变动,从而也不知道货物的销售价和发票是否正确。如进货的人在录入数据的时候真的出错了,数据库又没有作相应的处理,那么后果将是难能想象的。还是以那个“医院管理系统”为例来详细讨论这个问题吧(为简化,只列相关的重要字段):

1、药品表
ID   品名  购进价  销售价
1   咳必清   5         8
2  病毒灵   0.5       0.7
……

2、药品购进明细(其中“药品ID”与“药品表”中的ID是一对多的关系,实施参照完整性)
ID   药品ID  进货价  进货日期
1   2            0.5             2002-8-1
2   3            7               2002-8-1
3   1            9               2002-8-1
……

3、药品售出明细(其中“药品ID”与“药品表”中的ID是一对多的关系,实施参照完整性;“销售价”通过查询“药品表”得到)
ID  药品ID  销售价  销售量 售出日期
1   2           0.7         5            2002-8-2
2   3           9           2           2002-8-2
3   1          8            3           2002-8-2

很显然,在2002-8-1日购进“1”(咳必清)的时候,药品提价了,这时应该修改“药品表”中的“购进价”,也要修改“销售价”,“购进价”可以写一段代码来自动修改,但销售价则不能,因为其是不确定性的(当然也可以设置一个利润比例来自动修改,但这样太疆化了),必须人工修改,但如果录入人员由于工作上的失误,忘了更新“销售价”,就会出现“上面药品售出明细”中显示的那样,“咳必清”已提价到9元,但销售人员仍按8元的价格售出“咳必清”,这将是医院重大的经济损失。
对于上面这个问题,我现在所能做到的是,(1)在“购进价”改变的时候提示操作员修改“销售价”;(2)在销售时如果发现有某种药品的的“销售价”比“购进价”还小或达不到某一个利润比例,则系统禁止这种药品的售出,但却不能完全禁止这样的无效数据的存在,如何才能做到完全禁止这样的无效的数据的保存呢?请高手指点迷津。

对于第三个问题,还请版主指点一下,详细说说如何用ACCESS禁止这样的问题的出现。谢谢。



[此贴子已经被作者于2002-10-12 21:49:13编辑过]




[此贴子已经被作者于2002-10-12 21:58:19编辑过]

7#
发表于 2002-10-13 06:35:00 | 只看该作者
我认为你顶多改名称为什么还要改ID呢.
还是先解决容易的吧.第3个问题.你在设计表时设定"付款日期"为必填即可.
其它问题还是传例子解决吧.
8#
发表于 2002-10-13 07:16:00 | 只看该作者
上述问题与Access没有触发器无关。
数据结构很重要。
例如:引用[在第一次录入值的时候是没有问题的,因为“主治医生ID”的值都是与“住院科室ID”相关的,不会出现住院科室为“内科”而主治医生却是“外科”的医生的问题。但是如果录入了一次这两个值之后,操作人员更改了“住院科室ID”的值,使其变成“外科”,但又忘了更改“主治医生ID”的值,这就产生了一条无效的记录。]
      通常,一个id对应的主要字段是不能(不允许修改)修改。对于某个人,某个事务,它的id是唯一的。如果科室变了名称,就新增加一个科室,然后把数据关联到相应的科室。
原有的科室及其id保留。只是可以停用,在目前的输入界面中不显示。如果原有的科室id在其他表中没有关联记录,可以在整理数据结构时去掉。id资源多着呢,不需要这么节省。

数据都有一个实效性。
例如:[咳必清”已提价到9元,但销售人员仍按8元的价格售出“咳必清”,这将是医院重大的经济损失]
在售出表中,销售价格是要保存的(不允许通过查询药品表得到)。对应每一笔销售,同一种药品都用它当时售出的价格。不然,药品调价后,售出表中的售出价格会有问题。

9#
 楼主| 发表于 2002-10-13 08:08:00 | 只看该作者
对呀,就是说是药品调价后要改销售价,不改就会出错,问题是:怎样防止调价了,但是操作员没有正确地改“销售价”。十分正确,数据是有时效性的,换句话说,我所说的正好就是怎样才保证数据有很好的“时效性”。单价是要查药品表得到了,不可能让销售人员去背药品的当前销售价,然后手工输入,现在所说的问题就是要保证他们查到的是很有“时效性”的正确的调价后的价格。
对于ID问题,可能你们还不太明白,一个病人,他要住院,他可能住“外科”,也可能住“内科”,还有可能要转科(这就是改科室的实例),例如“何天”这个病人,他得了“肺炎”,他住在“内科”(也就是说他的“住院科室ID”的值是“1”,“1”是“内科”的ID,它代表“内科”,明白吗?),现在他“肺炎”经检查原来是一个肿瘤引起的,要做“外科”手术切除, 那么他就要转科了,也就是说他的“住院科室ID”的值将改为“2”,“2”是“外科”的ID,“2”就代表“外科”,明白吗?但“住院科室ID”改成“2”之后,操作员没有改“主治医生ID”的值(当然这是操作员的错,一般不会出现这样的错误,但不能排除,例如操作员失恋了,心不在焉,偏偏就忘了),它的值仍是“2”,“2”是“李明”这个医生的ID,“2”就代表“李明”这位医生,从“职员表”可以看出,他是“内科”的医生,这就变成“何天”在“外科”住院,他的主治医生却是一个“内科”的医生,这不乱套了吗??

对于第三个问题,“付款日期”是不能改为必填的,因为在商品售出的时候,对方可能还没有付款(允许说信用的客户延期付款),如果付款日期为必填,则不能保存这条记录。对方还没有付款,付款日期填什么?没法填,但如果它又是必填的,所以记录就不能保存了。过了一些日子,对方付款了,这时付款日期就一定要填的了,但它又不是必填字段,不填也可以,这就有可能出现对方付了款,但付款日期却没有填,当然出现这种情况的可能性也很小,但录入员头晕眼花,也不是没有可能,怎么办???
10#
 楼主| 发表于 2002-10-13 08:14:00 | 只看该作者
怎样上传例子?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|站长邮箱|小黑屋|手机版|Office中国/Access中国 ( 粤ICP备10043721号-1 )  

GMT+8, 2024-12-2 21:56 , Processed in 0.118985 second(s), 34 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表