Database design 数据库模型规范化-数据完整性

Database design 数据库模型规范化-数据完整性,database-design,erd,data-integrity,Database Design,Erd,Data Integrity,这是我的问题,我有两个基本的实体 一阶和 2-递送类型(基本上是查找表1-电子邮件、2-下载、3-USPS邮件) 假设一位客户下了订单并选择了3-USPS邮件交付类型 “我的订单”表存储要加入交货类型的id 3。基本的东西 但是,当管理员错误地将UPS邮件的递送类型更新为Fedex邮件时,会发生什么情况呢 订单将反映错误的交付类型。 我的问题是,我们应该防止人们在下订单后更新交付类型,还是应该取消我的订单的规范化,并在此时存储文档类型的快照这方面的最佳做法是什么 我发现,大多数情况下,例如在订单

这是我的问题,我有两个基本的实体

一阶和 2-递送类型(基本上是查找表1-电子邮件、2-下载、3-USPS邮件)

假设一位客户下了订单并选择了3-USPS邮件交付类型

“我的订单”表存储要加入交货类型的id 3。基本的东西

但是,当管理员错误地将UPS邮件的递送类型更新为Fedex邮件时,会发生什么情况呢

订单将反映错误的交付类型。 我的问题是,我们应该防止人们在下订单后更新交付类型,还是应该取消我的订单的规范化,并在此时存储文档类型的快照这方面的最佳做法是什么

我发现,大多数情况下,例如在订单产品场景中,更新产品名称并不是什么大问题,但当新值影响订单时,需要执行什么程序


谢谢

这将完全取决于您在那里自动化的业务流程。如果他们不能这样做,并且没有商业理由这样做,那么应该阻止他们这样做。如果他们需要这样做,那么系统需要能够处理它。这是一种你需要从一开始就建模的东西,以避免进入你无法走出的洞

因此,除此之外,没有确切的答案。您的数据需要与订单当前发生的情况相匹配,这是肯定的

但是,当管理员错误地将UPS邮件的递送类型更新为Fedex邮件时,会发生什么情况呢

别让这种事发生。特权是数据库设计的一部分,下面使用PostgreSQL进行说明。原则适用于所有客户机/服务器SQL dbms

create table delivery_types (
  delivery_type_num integer not null primary key,
  delivery_type_name varchar(15) not null unique
);

insert into delivery_types values
(1, 'Email'), (2, 'Download'), (3, 'USPS Mail');

create table orders (
  order_num integer primary key,
  other_columns char(1) not null default 'x',
  delivery_type_num integer not null references delivery_types
    on delete no action on update no action
);

revoke insert, update, delete, truncate on delivery_types from public;
grant select on delivery_types to public;
通过从“public”角色撤消这些特权,只有所有者和数据库超级用户才能更新该表。“orders”中的外键引用将阻止所有者和数据库超级用户删除行或更新其他表引用的行的id号

稍微不同的方法使用自然关键点。这不是非规范化。两个表“交付类型”都在6NF中

create table delivery_types (
  delivery_type varchar(15) primary key
);

insert into delivery_types values
('Email'), ('Download'), ('USPS Mail');

create table orders (
  order_num integer primary key,
  other_columns char(1) not null default 'x',
  delivery_type varchar(15) not null references delivery_types
    on delete no action on update no action
);

revoke insert, update, delete, truncate on delivery_types from public;
grant select on delivery_types to public;

insert into orders values 
(1, 'x', 'Email'), (2, 'x', 'Download'), (3, 'x', 'USPS Mail');

特权的工作原理与以前一样——“public”角色的成员可以从交付类型中进行选择,但不能更改内容。但是现在,即使是数据库超级用户也不能删除或更新传递类型中的行。外键引用阻止了它。

这是有道理的,是的,我们的业务规则是明确的:如果他们在下订单后试图更改任何值,这意味着两件事1)他们试图欺骗2)这是一个诚实的错误,他们正在试图纠正。第二种情况并不常见,就像在iphone上市后试图更改其名称一样。谢谢你的快速回复,没问题。如果他们不应该做某件事,就让它不可能做。因为如果他们能,他们会的D(那种东西留下的一些旧伤疤…)