繁体   English   中英

数据库设计通告参考/潜在的不一致

[英]Database design circular reference / potential inconsistency

我无法想出摆脱这种潜在矛盾的方法:

考虑以下四个实体:

     CUSTOMERS  >----------------   LOCATIONS
      id                             id
      name                           name
      loc_id           
                                       |
       |                               |
       |                               |
       |                               |
       /\                              /\

      ORDERS   >------------------   PRODUCTS           
       c_id                           id
       p_id                           name
                                      loc_id

每个客户都有一个位置(id:“ 3”,名称:“ US”)

每个客户定购许多产品,每个产品可以由许多客户购买(这些交易存储在ORDERS表中)

每种产品仅适用于具有相同位置的客户(“美国”客户可以使用“美国”产品)

问题:

我希望做一个产品只提供给客户 “US”,所以我插入一个产品 ,loc_id‘3’(美国)。

当我插入一个loc_id 客户问题出现“2”(EU)和创造同样产品订单 我结束了在一个位置 客户 下令在不同的位置提供产品 有什么办法可以避免这种情况?

当我插入具有loc_id“ 2”(EU)的客户并为该产品创建订单时,就会出现问题。 我最终在一个LOCATION中找到一位客户,并在另一个LOCATION中订购了产品。 有什么办法可以避免这种情况?

有两种添加此限制的方法。 在您的架构或模型中

在模式中,您可能会在订单表上使用触发器,以确保客户位置和产品位置相同。

在该模型中,您将向订单模型添加逻辑,以在创建订单之前验证客户位置和产品位置是否相同。 而且,您要确保所有创建订单的内容都使用该模型,而不要随意进行SQL查询。 您还希望出于其他维护原因。

放在哪里? 模型还是架构? 我的答案是模型。 这是我的想法

模式用于数据完整性。 模型用于业务规则。

结论:“业务规则”包括大多数数据验证。

“客户和订单必须具有相同的位置”是一项业务规则 这是企业定义的限制,可以随时更改。

相反,诸如“每个产品都必须具有有效的位置”或“您不能删除具有订单的产品”之类的数据完整性问题。 如果products.loc_idnull或指向不存在的一行位置,则会发生不良情况。 这就是诸如not null以及referencescascade目的。

业务规则始终在变化,因此您需要一种快速且易于更改的解决方案。

模式是昂贵的,并且有更改的风险。 任何更改都可能影响使用数据库的所有内容。 触发器不透明且复杂。 SQL在执行验证方面也受到限制。 检查是否相等是一回事,但是它可以检查URL是否有效吗? 那不是一个脏话吗? 由于存在这样的限制,您将面临巨大压力,需要在架构和模型之间划分验证和业务规则,这会带来干扰和混乱。

相反,该模型易于更改和测试。 它可以快速响应业务规则的异想天开。 编程语言更适合所有数据验证,并且许多模型库都带有丰富的验证功能。 有些甚至可以自动将这些转换为架构约束。

业务规则和数据验证变得复杂

另外,就数据而言,业务规则是任意的外部限制。 如果将其放在模式中,则与数据交互的所有内容都必须具有此限制: 无例外 这意味着您放入架构中的任何业务规则都必须处理所有可能性。

业务规则一开始往往很简单,但随着时间的流逝变得越来越复杂。 触发器和约束不是为复杂而设计的。 将您的业务规则放在架构中有一种趋势,就是仅仅因为不能轻易地将规则表达为触发器而限制了您的业务范围。

相反,用编程语言编写的模型可以很好地处理复杂性。 也许美国和加拿大需要分组? 还是欧盟国家? 也许有些客户为国际运输支付了额外的费用? 用任何体面的编程语言编写的模型都可以处理所有这些额外的复杂性。

如果不是所有内容都使用该模型怎么办? 存储过程。

如今,我们倾向于编写模型并使用工具,然后为我们编写架构。 预计与数据库的所有交互都将通过模型进行。 但这并非总是如此。 如果数据验证在模型中,那么使用数据库而不是模型的事情又如何呢?

我的第一个答案是:考虑不这样做。 如果异构系统需要访问数据,请考虑将微服务用作数据库上的抽象层。 然后,其他需要使用数据的系统通过定义良好的API与之交互。 这样可以避免每个人都随意地访问数据库,而不用知道谁在处理数据。

如果您不能做到这一点,请考虑将混合方法与存储过程结合使用。 将存储过程编写为模型的一部分。 他们处理与数据库的交互并完成所有CRUD工作。 在您的情况下,您将编写一个new_order存储过程,该过程执行模型将执行的所有验证。 这样,与数据库进行交互的任何人都将使用存储过程,而不是编写自己的查询。

许多数据库甚至允许使用其他语言编写的存储过程,从而为您提供了全方位的灵活性。 不幸的是MySQL没有。 如果您刚刚开始进步,请考虑切换到功能更强大的数据库,例如PostgreSQL。

结论

您正在谈论的数据验证是一种业务规则。 业务规则一直在变化,并且它们往往变得比触发器和约束所能处理的更为复杂。 它们属于易于更改和功能强大的验证工具的模型。

并且一定要有一个模型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM