- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想将父实体的子实体的某个属性的总和限制为该父实体的某个属性。我想在不使用触发器的情况下使用 PostgreSQL 来执行此操作。下面是一个例子;
假设我们有一个带有 volume 属性的箱子。我们想用更小的盒子填充它,这些盒子有自己的体积属性。 crate 中所有箱子的体积总和不能大于 crate 的体积。
我的想法是这样的:
CREATE TABLE crates (
crate_id int NOT NULL,
crate_volume int NOT NULL,
crate_volume_used int NOT NULL DEFAULT 0,
CONSTRAINT crates_pkey PRIMARY KEY (crate_id),
CONSTRAINT ukey_for_fkey_ref_from_boxes
UNIQUE (crate_id, crate_volume, crate_volume_used),
CONSTRAINT crate_volume_used_cannot_be_greater_than_crate_volume
CHECK (crate_volume_used <= crate_volume),
CONSTRAINT crate_volume_must_be_positive CHECK (crate_volume >= 0)
);
CREATE TABLE boxes (
box_id int NOT NULL,
box_volume int NOT NULL,
crate_id int NOT NULL,
crate_volume int NOT NULL,
crate_volume_used int NOT NULL,
id_of_previous_box int,
previous_sum_of_volumes_of_boxes int,
current_sum_of_volumes_of_boxes int NOT NULL,
id_of_next_box int,
CONSTRAINT boxes_pkey PRIMARY KEY (box_id),
CONSTRAINT box_volume_must_be_positive CHECK (box_volume >= 0),
CONSTRAINT crate_fkey FOREIGN KEY (crate_id, crate_volume, crate_volume_used)
REFERENCES crates (crate_id, crate_volume, crate_volume_used) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED,
CONSTRAINT previous_box_self_ref_fkey FOREIGN KEY (id_of_previous_box, previous_sum_of_volumes_of_boxes)
REFERENCES boxes (box_id, current_sum_of_volumes_of_boxes) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED,
CONSTRAINT ukey_for_previous_box_self_ref_fkey UNIQUE (box_id, current_sum_of_volumes_of_boxes),
CONSTRAINT previous_box_self_ref_fkey_validity UNIQUE (crate_id, id_of_previous_box),
CONSTRAINT next_box_self_ref_fkey FOREIGN KEY (id_of_next_box)
REFERENCES boxes (box_id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED,
CONSTRAINT next_box_self_ref_fkey_validity UNIQUE (crate_id, id_of_next_box),
CONSTRAINT self_ref_key_integrity CHECK (
(id_of_previous_box IS NULL AND previous_sum_of_volumes_of_boxes IS NULL) OR
(id_of_previous_box IS NOT NULL AND previous_sum_of_volumes_of_boxes IS NOT NULL)
),
CONSTRAINT sum_of_volumes_of_boxes_check1 CHECK (current_sum_of_volumes_of_boxes <= crate_volume),
CONSTRAINT sum_of_volumes_of_boxes_check2 CHECK (
(previous_sum_of_volumes_of_boxes IS NULL AND current_sum_of_volumes_of_boxes=box_volume) OR
(previous_sum_of_volumes_of_boxes IS NOT NULL AND current_sum_of_volumes_of_boxes=box_volume+previous_sum_of_volumes_of_boxes)
),
CONSTRAINT crate_volume_used_check CHECK (
(id_of_next_box IS NULL AND crate_volume_used=current_sum_of_volumes_of_boxes) OR
(id_of_next_box IS NOT NULL)
)
);
CREATE UNIQUE INDEX single_first_box ON boxes (crate_id) WHERE id_of_previous_box IS NULL;
CREATE UNIQUE INDEX single_last_box ON boxes (crate_id) WHERE id_of_next_box IS NULL;
我的问题是,这是否是一种执行此操作的方法,以及是否有更好的(更少混淆、更优化等)方法来执行此操作。还是我应该坚持使用触发器?
提前致谢。
最佳答案
My questions is if there is a better (less confusing, more optimized etc.) way of doing this.
是的,有:总之,使用触发器……
不,没关系,你不想使用一个。在这里使用触发器;没有如果,没有但是。
扩展我和其他人之前发表的评论:
您所做的相当于编写一个约束触发器来验证 sum(boxes.volume) <= crate.volume
.它只是以一种非常、非常 SCSS 的方式(通过检查约束、唯一键和外键伪装成聚合函数),然后在您的应用程序中进行相关计算。
避免使用真正的触发器的唯一成就将是在两个并发更新试图影响同一个 crate 时出现错误。所有这一切,都是以维护不必要的唯一索引和外键为代价的。
当然,您最终会解决部分或所有这些问题,并通过使外键可延迟、添加锁来进一步完善您的“实现”,yada yada。但最终,您所做的基本上相当于编写一个效率极低的聚合函数。
所以使用触发器。在箱子上使用 after 触发器维护箱子中的 current_volume 列,并在箱子上使用简单的 check() 约束强制执行检查。或者在框上添加约束触发器,以直接执行检查。
如果您需要更有说服力,只需考虑您正在创建的开销。真的。冷静、认真地审视一下:不是使用触发器在 crate 中维护 一个 volume 列(如果是的话),而是维护不少于 六个 服务的字段绝对没有超出您的约束的目的,以及与它们相关的许多无用的唯一索引和外键约束,以至于当我尝试枚举它们时我真的数不清了。然后检查对它们的约束。这些东西在存储和写入性能方面都加起来了。
关于postgresql - postgres - 对列总和的约束(无触发器),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20744564/
我基本上有三个表: hunt_c_usershunt_c_collected_eggshunt_c_achievements 我目前只使用 hunt_c_users 和 hunt_c_collecte
我已经计算了不同表中计数的总和。这会执行两次,每个 performanceID 一次。现在我想得到两个总和的总和。 下面是我目前做的两个总和的代码: SELECT SUM((COUNT (Bo
我有一个对 2 个值求和的脚本。我计划添加更多值(value),但首先我需要让它发挥作用。人们告诉我给他们 NUMBER 值,所以我这样做了,但现在它甚至没有给出输出。 base = 0; $("#F
我正在尝试计算在我们的数据库中跟踪的花费总额。每个订单文档包含一个字段“total_price” 我正在尝试使用以下代码: db.orders.aggregate({ $group: {
给定 Excel 2013(或更高版本)中的 2 个命名表: tbl发票 ID InvRef Total 1 I/123 45 2 I/234
希望你们一切都好。我来这里是因为我从今天早上开始就试图解决一个问题,我再也受不了了。 这就是上下文:我有一个 excel 工作簿,其中有不同的工作表,其中包含不同国家/地区的不同商业计划。我的目标是制
我有一份报告显示客户订购的产品及其价格: CompanyA Product 7 14.99 CompanyA Product 3 45.95 CompanyA Prod
我使用此python客户端: https://github.com/ryananguiano/python-redis-timeseries 如何汇总所有匹配? ts = TimeSeries(cli
希望创建一个总和和计数公式,该公式将自动调整以适应范围内插入的新行。 例如,如果我在单元格 D55 中有公式 =SUM(D17:D54)。每次我在该范围内插入新行时,我都需要更改公式的顶部范围来解释它
所以,我需要聚合日期相同的行。 到目前为止,我的代码返回以下内容: date value source 0 2018-04-08 15:52:26.1
我有数字输入 数量约为 30 我需要将它们全部汇总到一个字段 我拥有的在下面 查看:
您好,我正在尝试根据以下数据计算过去三个月中出现不止一次的不同帐户 ID 的数量;我想要 2 作为查询结果,因为 test1@gmail.com 和 test2@gmail.com 出现超过 1 次。
我有两个带有以下字段的表: ... orders.orderID orders.orderValue 和 payments.orderID payments.payVal 在 payments.pay
我想按 image_gallery 和 video_gallery 两列的 DESC 进行排序。 SELECT b.*, c.title as category, (S
实际上我的原始数据库为 SELECT sum(data1,data2) as database_value,sum(data3,data4) as database_not_value from t
我试图获取三个分数中每一个的值并将它们相加并显示在“总计:”中。我的问题是,我不知道如何做到这一点,以便每次其中一个分数值发生变化时,相应的总分值也会随之变化。 我可以在某处调用“onchange”来
如何获得按第一个值分组的元组列表中第二个和第三个值的总和? 即: list_of_tuples = [(1, 3, 1), (1, 2, 4), (2, 1, 0), (2, 2, 0)] expec
我正在尝试将我的列表中的整数转换为列表的总和和平均值,并说明任何低于冰点 F<32 的温度。每当我尝试获取总和或平均值时,我都会收到错误提示“+: 'int' 和 'str' 不支持的操作数类型”。我
在我的 ios 项目中,我使用了两个实体 (CoreData):具有一对多关系的 Person 和 Gifts 我知道如何计算给一个人的礼物总和: NSDecimalNumber *orderSum=
我有两个表(输入和类别): CREATE TABLE categories ( iId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, sNam
我是一名优秀的程序员,十分优秀!