Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database design 数据库设计-如何使用数据库确认完整的数据输入和验证_Database Design - Fatal编程技术网

Database design 数据库设计-如何使用数据库确认完整的数据输入和验证

Database design 数据库设计-如何使用数据库确认完整的数据输入和验证,database-design,Database Design,我有一个应用程序表和一个资源表。由于许多资源可以在单个应用程序上工作,并且许多应用程序可以由单个资源工作,因此我创建了第三个表: 应用程序资源: -ID(int) -应用程序ID(int) -资源ID(int) -PctOfTime(浮动) 在数据库本身中,我是否可以确保所有资源的PctOfTime总和达到100%?在SQL中没有声明性的方法来实现这一点 您可以使用触发器(每当插入、更新或删除ApplicationResources表中的行时都会运行的存储过程)来完成此操作。如果触发器会导致条件

我有一个应用程序表和一个资源表。由于许多资源可以在单个应用程序上工作,并且许多应用程序可以由单个资源工作,因此我创建了第三个表:

应用程序资源
-ID(int)
-应用程序ID(int)
-资源ID(int)
-PctOfTime(浮动)


在数据库本身中,我是否可以确保所有资源的PctOfTime总和达到100%?

在SQL中没有声明性的方法来实现这一点

您可以使用触发器(每当插入、更新或删除ApplicationResources表中的行时都会运行的存储过程)来完成此操作。如果触发器会导致条件为false,则可以测试条件并拒绝更改

问题是,您可能需要允许该表暂时无效。例如,如果您删除资源的记录,则在添加或更新一个或多个记录以恢复到100%之前,该条件将不会为真。为了使其正常工作,您需要将触发器延迟到事务结束并能够执行该操作在不同的数据库中不同的位置

如果您希望任何资源的分配都不能超过100%(并且允许未充分利用的资源),那么您的问题更容易解决。

您使用Oracle吗

如果您使用Oracle,则可以使用快速刷新物化视图以声明方式验证数据,您必须为此物化视图添加检查约束。这意味着验证将在提交时完成

Edit1

oo没有回答我一个非常简单的问题,这让我有点难过,所以我不知道他/她是否使用Oracle,但无论如何:

让我们创建一个带有物化视图日志的表,一个带有group by on resourceid的物化视图,以及一个检查约束,以检查每个resourceid的PctOfTime之和是否等于100

create table applicationresources 
(
id number(10) not null primary key,
applicationid number(10) not null,
resourceid number(10) not null,
pctoftime  number(3)  not null
);

create materialized view log on applicationresources 
with rowid (id,applicationid,resourceid,pctoftime) including new values;

create materialized view pctoftimecheck
refresh fast on commit
as
select sum(pctoftime) sum_time,resourceid
from   applicationresources
group by resourceid
/

alter table pctoftimecheck add constraint c1 check(sum_time=100);
现在有两个例子:

例1(将成功):

示例2(提交时将失败,因为sum=101)


有关更多信息,请参阅:

这可以通过触发器完成,但问题是当总数不等于100%时,如何处理。如果我将一个值从50%更改为60%(并且我已经有另一个记录用于其他50%),是否要调整其他记录降到100或拒绝更新。还有初始插入记录的问题。第一个记录是60%,但根据您的规则,我必须以100%的比例输入,直到我输入另一个记录。最后,如果所有记录的总和不等于100%,该怎么办。是否要在所有记录之间分割差异,分割dif未更改记录之间的差异是保留更改的值,还是拒绝使总数不相加的更改


这是一个必须仔细考虑和设计的触发器。

为什么要添加ID。为什么不在PK中使用ApplicationId和ResourceId?>@RichardOD:我经常这样做。这使前端编程更容易-用户可以“指向”对于一个记录,代码可以使用单个值来识别它。@oo:计算可以在触发器中完成,也可以通过存储过程中的逻辑完成。如果值始终为100%,我看不出存储该值的意义。@OMG Ponies:如果一个资源在多个应用程序上工作,它们可能在一个应用程序上占40%,在另一个应用程序上占60%,但没有什么是适用的g像这样的总数是100%最好作为一个评论-我不会,但其他人喜欢记下这些不知情的答案。哈哈,好吧,我不怕!顺便问一下,我的答案中到底有什么是不知情的?
insert into applicationresources values (1, 1, 1, 50);

insert into applicationresources values (2, 2, 1, 50);

commit;
insert into applicationresources values (3, 1, 2, 50);

insert into applicationresources values (4, 2, 2, 50);

insert into applicationresources values (5, 3, 2, 1);

commit;

SQL> Error: ORA-02290: CHECK-constraint (DSEDD.C1) violated.