从数据库中指定关系可以获得什么?

时间:2017-04-11 14:33:31

标签: ms-access database-design ms-access-2010

我正在MS Access 2010中构建一个项目。我以前在Oracle中有过经验。我正在阅读关于MS Access并继续看到对表关系的引用。它似乎是一种方便的方式来帮助普通人进行数据输入和验证以及查询构建,但我只在SQL模式下编写查询,并为具有自己的验证规则的表单的用户强制执行数据输入。

是否真的有必要强制执行关系?它似乎并没有让我获得任何高级水平的东西,并且实际上可能会给我或其他最终从我接管维护的人带来问题。我之前从未使用它们,而且我现在还没有真正看到它的好处。任何人都可以对此有所了解吗?

5 个答案:

答案 0 :(得分:3)

您说您以前有Oracle的经验。您是否从未在Oracle中定义外键约束?如果您这样做,那么当您在Access中定义关系时,这就是您正在做的事情。您可以使用它来强制引用完整性(如果子记录仍然存在,则不允许您删除父记录),或者,如果使用cascade delete选项,则在删除父记录时自动删除子记录。它是一个有用的备份,可以覆盖编码错误,如果您没有定义关系(FK),您可能会忘记可能会成为孤儿的子记录。

答案 1 :(得分:2)

从一个只查询数据的人那里,关系就不那么重要了。但是从应用程序的角度来看,如果不是非常重要的话,它们会非常有用。

例如,您可能有一个客户的表,然后说一个订单表。业务规则是除非您首先拥有客户,否则无法创建订单。因此,如果您自由编写一些SQL来添加没有客户的订单,那么您的更新/插入查询将不起作用。如果您需要删除客户,那么该客户的所有订单都可以/将自动删除,而无需编写复杂的删除SQL语句。例如,您可能希望删除所有超过5年或10年的客户(因此他们处于非活动状态)。当您删除这些客户时,您希望所有订单也被删除。 (如果您必须删除每个客户的子记录,这是一个非常难以编写的查询。强制关系,然后所有子记录将自动删除(强制级联删除))。

从报告的角度来看,这也很重要。如果您编写查询以显示本月的所有客户及其结算总额,那么您将得到一个总结果。但是,如果您决定不想显示/包含客户,您可能只需点击订单表并获得总额。问题是没有RI,那么你可能(偶然或甚至只是一些用户启动订单表格)输入了订单信息(总金额),但没有客户。

现在发生的事情是当你运行两个不同的报告/ quire时,你发现总数是不同的!在一个复杂的应用程序中,两个报告不同的“原因”可能需要数天,或者甚至一周内有大量数据来弄清楚为什么两份月度销售报告彼此不一致。如果您强制执行业务规则,即没有订单可以输入系统,除非他们有客户,那么您可以消除报告中的此类错误。您可以“说”您是SQL的完美用户,但是有大量代码,大量数据输入表单,您如何确保订单永远不会在没有客户的情况下输入。数据输入期间的用户可能忘记以该订单形式输入客户。即使您按照订单形式编写代码以确保必须选择客户,也许您在编写某些SQL时偶然会在没有客户的情况下将订单记录插入系统。但是,您的每月客户总报告查询“假定”您有一个客户记录,您在订单中加入了总数据。

但是,某些报告必须仅在订单数据上运行(每月摘要总数不需要包括客户)。问题现在是系统中的某个地方,您有一个订单记录,其中包含没有客户的总数据。结果是不同的报告和销售总额的现状不同意。这是一场彻头彻尾的噩梦。

因此,可能会出现应用程序代码中的一些错误或错误,并导致现在应该是具有“孤立”记录的关系数据。也许您的业务规则允许在没有分配客户的情况下输入订单,但是您的月度销售报告必须显示该事实,或者任何点击订单表并且不包括客户的查询都必须“检查”那些可能性查询没有客户记录退出。

以上只是简单地抓住了GAZILLION问题的表面。因此,虽然您可能只是在数据上创建简单的quires,但问题是数据在系统中是否正确相关?关于垃圾输入=垃圾输出的古老说法在这里是真的。

当你的SQL quires使用MULTIPLE表拉取数据的那天结束时,你必须对该数据及其关系完整性(RI)做出假设。因此,当您将该查询写入显示客户及其订单总计时,您可以选择并放入customers表,然后在orders表中进行关系连接。但是,如果订单不存在客户记录,那么您的查询将不会生成正确的值。更糟糕的是,点击订单表的报告现在会产生不同的结果。

如果您强制执行RI,那么无论如何,如果没有FIRST创建客户记录,您将无法意外或强制输入订单。如果您不强制执行此类规则,那么您的数据将产生不正确的结果。

典型的复杂应用程序将有40或70个相关表。并且这些表中的每一个都将根据您的业务假设集合假设“假设”父记录(或子记录)是否已经做出假设。

您可能拥有旅游预订系统。客户可能会打电话,存入押金但尚未预订特定的旅行。如果您允许此设置,那么您对本月客户的查询以及他们预订的游览将必须考虑到这一点。然而,业务规则可能是系统中放下钱的任何客户也必须被预订到一个旅游(因此您查询获取该信息将考虑此规则)。

如果您始终做的每个查询都不是要包含来自多个表的数据,那么您可能无法从强制执行关系数据中获益。但是,当您开始使用多个表捆绑查询时,您必须知道在编写查询之前对该数据所做的假设。那么,您是否允许客户在没有预订旅游的情况下在系统中存款?此规则将决定您必须如何编写该查询。如果强制执行RI,那么您可以查询客户“预订”,并且您知道它将附加到旅游活动中。同样如果任何预订+存款不需要预订 - 但您必须知道有关该数据的假设。

因此,基于对数据的假设是创建查询以根据这些假设提取数据的唯一实用方法。如果你强制执行RI,那么你至少知道数据必须是相关的,并根据这些假设进行设置。

一天结束?任何创建数据库的人都可以在不强制执行RI的情况下为业务应用程序和规则建模,而是建造一艘没有方向舵且没有罗盘的船。

从每个表导出数据是一个非常问题。但是,如果该数据混乱且具有孤立记录,那么您最终只会将不正确的数据模型导出到另一个数据库,并且所有问题都会存在。

答案 2 :(得分:1)

如果您纯粹在SQL模式下构建查询,那么定义关系可能对您没有任何影响。唯一可能有用的是,如果你构建了一些东西,然后几个月没有再看它,你就可以在概念上快速重新认识这些关系。

对于使用访问查询构建器的任何人,定义关系可以让您快速将表添加到查询中,而Access会自动为查询JOIN构建正确的(GIGO)关系。同样,如果您使用SQL编写,您可能已经这样做了,因此在查询构建中对您没什么帮助。

底线 - 它更像是一个简化查询过程的图形工具,至少在您尝试将表导出到“真正的”RDBMS之前,就像其他人已经提到的那样。

答案 3 :(得分:0)

如果不是您要求使用案例,那么您不必使用它。一个用例,这可能是“#34; required"在基于订单的情景中。

假设您有一个创建和跟踪订单的数据库。每个订单可以有多个与同一订单相关联的行。但是出于规范化的目的,大多数人会将这些分成两个单独的表。 OrderHead和OrderDetail。您可能希望在此强制执行参照完整性,以确保OrderDetail中永远不会有子记录链接回父订单。

我确信你可以在没有它的情况下阻止这样的事情,但它主要是强制执行它。

答案 4 :(得分:0)

关系有助于保持数据完整性,我同意您的观点,即如果用户从访问表单输入,则由于完整性导致的错误概率较小。但是将来如果用户从MS Access转移到纯RDBMS,这种关系肯定会有所帮助。

虽然关系的目标不是在以后的时间点进行迁移,但对于您的情况而言,这是我能想到的一个正当理由。

除此之外,对于具有自己的表单关系的MS Access,可能不会添加特定值。