制度设计:是否规范部门
System design: whether to normalize the departments or not
我在一个项目中与两位顾问合作。问题是我们已经到了他们无法达成协议的地步,并且每个人都提供了不同的方法。
问题是我们有一家商店有四个部门,我们想找到在同一个数据库中处理所有部门的最佳方法。
每个部门销售不同的产品:汽车、船只、摩托艇和摩托车。
当在每个部门插入或更新数据时,会有一些触发器被触发,因此不同的工作流程将开始,当添加新车时,需要检查某些要求以及汽车的详细信息这与船完全不同。此外,关于数据,没有太多共同的字段,我想说到目前为止只有品牌、颜色、型号和年份,其他所有内容都是针对每个部门的,因为不同的产品以及它们如何使用它们。
一位顾问说:
为所有部门创建一个table并使用一列来标识该行属于哪个部门,这样您将只有一个触发器,然后在触发器内调用每个记录类型所需的 function/mehod。
原因:你只有一个table(超过200个字段)和一个触发器,更容易维护。此外,如果您需要报告,您只需查询一个 table 并根据记录类型进行过滤。如果您需要报告所有项目,则不需要多个连接。
顾问二说:
为每个部门创建一个 table 并为每个 table 创建一个触发器。
原因:您将有更小的 tables(每个大约 50 个字段)并且更灵活,并且您将它们全部分开。如果你想报告,你需要加入 tables,因为你想包含来自不同地方的数据。
我看到了将所有内容都放在一个地方的好处,但如果我想扩展或更改任何内容,我感觉我会随着数据的增长而创建一个野兽 table。
另一方面,将它分开看起来更吸引人,但需要为每个不同的东西设置所有内容 table。
您认为最好的方法是什么?
你可能应该听听二号顾问的意见。
事实是,所有设计都是权衡取舍。您需要评估每种方法的优缺点,并且需要考虑每种设计所带来的风险。
- 当你的设计成长时会发生什么? (部门 5,每种产品类型的更多详细信息,...)
- 当系统扩展到更高的交易量时会发生什么?
- 当您的业务规则发生变化时会发生什么?
我已经这样做了很长时间,我看到一些钟摆在谈到什么是 "in fashion" 数据库和软件最佳实践时来回摆动。
我想说现在流行的观点是 关注点分离 天生就是好的。这意味着您应该将每个部门的程序逻辑(触发代码)分开。这是有道理的,因为您的逻辑会因一种产品类型而异,因为它们大多具有不同的列。
第二点也很重要,因为您在交易系统基础上的利益应始终从第三范式开始(或更高,如有必要)。有时你可以不用它就可以逃脱,但是四种不同类型的对象具有 40 个或更多不同的属性,每个对象听起来不像是将所有东西都塞进一个 table 的好选择。例如,您如何跟踪哪些列属于哪种类型的产品?每种产品类型的单独 table 保持这种清晰和简单 - 重要的是 - 易于您的支持程序员理解。
与一位顾问所说的相反,如果一个触发器是一大碗意大利面条,或者甚至是四个整洁、编写良好的子例程与一个switch
类型语句。
现在,程序员喜欢简短的、原子的、单一用途的函数(触发器,在你的例子中)。
如果有足够多的公共数据和公共业务逻辑,做四次看起来很尴尬,那么也许你有一个很好的超类型/子类型设计的候选。
我说一个
这些都是产品,不管是自行车还是汽车。您可以通过 RecordTypes 和页面布局来控制字段和对象,这将使您免于拥有 4 个对象,这意味着可能有 8 个新的 类(如果它遵循我的模式,它可能高达 20+)+ 所有跨这些新对象的工作流规则和验证规则,将很难维护具有 4 个对象但都是同一事物的结构。跟踪产品。
如果您决定添加新产品(例如飞机),那么向该对象添加飞机将非常容易,并且如果需要,代码可以从那里获取。您肯定需要记录类型来管理每个产品。如果顾问正确构建触发器代码,则触发器代码不应该成为问题,这意味着触发器永远不应具有任何业务逻辑,因此只要遵循所有代码,所有代码都将是可维护的
我会和一个一起去。
我假设您有大量产品并且此列表将来会增加。所有这些最后都是产品。他们会有一些共同的领域和共同的逻辑。
如果您将 Process Builder 与 Invocable 类 而不是触发器一起使用,您可以在添加新对象时仅更改配置,如果它的字段和功能是 same/similar一个现有的对象。
根据您的许可类型,配置文件可以访问的不同对象的数量可能也有限制。
Salesforce 有一个名为 Product 的标准对象。它是根据记录类型分类的单个对象。
如果这不是 salesforce,我会采用方法二。根据 salesforce 的工作方式及其施加的限制,似乎是一种更好、更简洁的解决方案。
我会说选项2。
为什么?
(1) 我会发现 table 有 200 多列更难维护。然后,您还必须为不需要所述字段的对象公开字段。
(2) 您还必须 "hide" 触发器内部的逻辑,然后根据部门类型等决定执行不同的操作...
(3) 选项 2 涉及更多 "scaffolding" 和单独的对象,但这些对象本质上更小且更易于维护,并且不会专门隐藏逻辑或导致任何歧义。
(4) 方案二遵循单一职责原则。不是每个人都遵循这一点,我理解,但我发现这是一个很好的指导原则,因为数据的责任在于个人 table,而触发行动的责任在于个人触发器,而不是仅仅作为一个庞然大物 entity/trigger.
** 我要声明的是,我只是从软件开发的角度来看这个问题,我不确定 SalesForce 是否会处理此设置,但这是我个人更喜欢的设计方式。 :)
我的选项 2。
你说通用数据很少,触发逻辑完全不同。以下是一些额外的技术注意事项。
选项 1 警告
触发器将是单点故障,错误将更难以调试。我曾使用过大型触发器,其中顶部附近的损坏逻辑已从 运行 停止底部附近的逻辑,有时是静默的!您还必须维护条件保护以根据数据控制逻辑流,这是另一个出错的机会。
我对索引不是很感兴趣,但我相信由于多用途数据没有自然顺序,性能会受到影响。更具体的表将产生更好的索引策略。此外,大行会导致索引碎片化。
在对与所讨论产品无关的每个剩余字段设置 nullable/default 限制时,您需要额外考虑。这些微妙之处可能会引入错误,并可能使您更难 if/when 您决定使用数据层技术,例如 Entity Framework。例如。 NULL、0 和 'None' 之间的逻辑差异,尤其是在共享列上。
我在一个项目中与两位顾问合作。问题是我们已经到了他们无法达成协议的地步,并且每个人都提供了不同的方法。
问题是我们有一家商店有四个部门,我们想找到在同一个数据库中处理所有部门的最佳方法。
每个部门销售不同的产品:汽车、船只、摩托艇和摩托车。
当在每个部门插入或更新数据时,会有一些触发器被触发,因此不同的工作流程将开始,当添加新车时,需要检查某些要求以及汽车的详细信息这与船完全不同。此外,关于数据,没有太多共同的字段,我想说到目前为止只有品牌、颜色、型号和年份,其他所有内容都是针对每个部门的,因为不同的产品以及它们如何使用它们。
一位顾问说:
为所有部门创建一个table并使用一列来标识该行属于哪个部门,这样您将只有一个触发器,然后在触发器内调用每个记录类型所需的 function/mehod。
原因:你只有一个table(超过200个字段)和一个触发器,更容易维护。此外,如果您需要报告,您只需查询一个 table 并根据记录类型进行过滤。如果您需要报告所有项目,则不需要多个连接。
顾问二说:
为每个部门创建一个 table 并为每个 table 创建一个触发器。
原因:您将有更小的 tables(每个大约 50 个字段)并且更灵活,并且您将它们全部分开。如果你想报告,你需要加入 tables,因为你想包含来自不同地方的数据。
我看到了将所有内容都放在一个地方的好处,但如果我想扩展或更改任何内容,我感觉我会随着数据的增长而创建一个野兽 table。
另一方面,将它分开看起来更吸引人,但需要为每个不同的东西设置所有内容 table。
您认为最好的方法是什么?
你可能应该听听二号顾问的意见。
事实是,所有设计都是权衡取舍。您需要评估每种方法的优缺点,并且需要考虑每种设计所带来的风险。
- 当你的设计成长时会发生什么? (部门 5,每种产品类型的更多详细信息,...)
- 当系统扩展到更高的交易量时会发生什么?
- 当您的业务规则发生变化时会发生什么?
我已经这样做了很长时间,我看到一些钟摆在谈到什么是 "in fashion" 数据库和软件最佳实践时来回摆动。
我想说现在流行的观点是 关注点分离 天生就是好的。这意味着您应该将每个部门的程序逻辑(触发代码)分开。这是有道理的,因为您的逻辑会因一种产品类型而异,因为它们大多具有不同的列。
第二点也很重要,因为您在交易系统基础上的利益应始终从第三范式开始(或更高,如有必要)。有时你可以不用它就可以逃脱,但是四种不同类型的对象具有 40 个或更多不同的属性,每个对象听起来不像是将所有东西都塞进一个 table 的好选择。例如,您如何跟踪哪些列属于哪种类型的产品?每种产品类型的单独 table 保持这种清晰和简单 - 重要的是 - 易于您的支持程序员理解。
与一位顾问所说的相反,如果一个触发器是一大碗意大利面条,或者甚至是四个整洁、编写良好的子例程与一个switch
类型语句。
现在,程序员喜欢简短的、原子的、单一用途的函数(触发器,在你的例子中)。
如果有足够多的公共数据和公共业务逻辑,做四次看起来很尴尬,那么也许你有一个很好的超类型/子类型设计的候选。
我说一个
这些都是产品,不管是自行车还是汽车。您可以通过 RecordTypes 和页面布局来控制字段和对象,这将使您免于拥有 4 个对象,这意味着可能有 8 个新的 类(如果它遵循我的模式,它可能高达 20+)+ 所有跨这些新对象的工作流规则和验证规则,将很难维护具有 4 个对象但都是同一事物的结构。跟踪产品。
如果您决定添加新产品(例如飞机),那么向该对象添加飞机将非常容易,并且如果需要,代码可以从那里获取。您肯定需要记录类型来管理每个产品。如果顾问正确构建触发器代码,则触发器代码不应该成为问题,这意味着触发器永远不应具有任何业务逻辑,因此只要遵循所有代码,所有代码都将是可维护的
我会和一个一起去。
我假设您有大量产品并且此列表将来会增加。所有这些最后都是产品。他们会有一些共同的领域和共同的逻辑。
如果您将 Process Builder 与 Invocable 类 而不是触发器一起使用,您可以在添加新对象时仅更改配置,如果它的字段和功能是 same/similar一个现有的对象。
根据您的许可类型,配置文件可以访问的不同对象的数量可能也有限制。
Salesforce 有一个名为 Product 的标准对象。它是根据记录类型分类的单个对象。
如果这不是 salesforce,我会采用方法二。根据 salesforce 的工作方式及其施加的限制,似乎是一种更好、更简洁的解决方案。
我会说选项2。
为什么?
(1) 我会发现 table 有 200 多列更难维护。然后,您还必须为不需要所述字段的对象公开字段。
(2) 您还必须 "hide" 触发器内部的逻辑,然后根据部门类型等决定执行不同的操作...
(3) 选项 2 涉及更多 "scaffolding" 和单独的对象,但这些对象本质上更小且更易于维护,并且不会专门隐藏逻辑或导致任何歧义。
(4) 方案二遵循单一职责原则。不是每个人都遵循这一点,我理解,但我发现这是一个很好的指导原则,因为数据的责任在于个人 table,而触发行动的责任在于个人触发器,而不是仅仅作为一个庞然大物 entity/trigger.
** 我要声明的是,我只是从软件开发的角度来看这个问题,我不确定 SalesForce 是否会处理此设置,但这是我个人更喜欢的设计方式。 :)
我的选项 2。
你说通用数据很少,触发逻辑完全不同。以下是一些额外的技术注意事项。
选项 1 警告
触发器将是单点故障,错误将更难以调试。我曾使用过大型触发器,其中顶部附近的损坏逻辑已从 运行 停止底部附近的逻辑,有时是静默的!您还必须维护条件保护以根据数据控制逻辑流,这是另一个出错的机会。
我对索引不是很感兴趣,但我相信由于多用途数据没有自然顺序,性能会受到影响。更具体的表将产生更好的索引策略。此外,大行会导致索引碎片化。
在对与所讨论产品无关的每个剩余字段设置 nullable/default 限制时,您需要额外考虑。这些微妙之处可能会引入错误,并可能使您更难 if/when 您决定使用数据层技术,例如 Entity Framework。例如。 NULL、0 和 'None' 之间的逻辑差异,尤其是在共享列上。