我是否应该明确拒绝对不应更新的列进行更新?

Wor*_*DBA 26 database-design sql-server best-practices permissions

我习惯于在非常安全的环境中工作,因此我将权限设计为非常精细的粒度。我通常做的一件事是明确地为DENY用户提供UPDATE永远不应该更新的列的能力。

例如:

create table dbo.something (
    created_by varchar(50) not null,
    created_on datetimeoffset not null
);
Run Code Online (Sandbox Code Playgroud)

一旦设置了值,就不应更改这两列。因此,我明确DENYUPDATE他们的权限。

最近,在一次团队会议上,一位开发人员提出了一个观点,即确保字段永远不会更新的逻辑应该包含在应用程序层而不是数据库层中,以防“他们出于某种原因需要更新值”。对我来说,这听起来像是典型的开发人员心态(我知道,我曾经是其中之一!)

我是我公司的高级架构师,我一直遵循让应用程序运行所需的最少权限的原则。所有权限都会定期审核。

这种情况下的最佳实践是什么?

Aar*_*and 29

争论没有意义。我总是希望控件和约束尽可能接近数据。将它放在应用程序层意味着它只会影响使用应用程序层的人,并且还假设代码没有错误,并且这些代码路径周围的安全性将是防弹的。这些都是很大的假设。

如果他们绝对需要更新,那么可以由不受显式影响的人来完成DENY,或者可以暂时将人移到不受影响的角色,或者DENY可以暂时删除。作为 DBA,您可以轻松地围绕这些设置审计。在应用程序中?没那么多。


Sol*_*zky 16

我完全同意@Aaron 在这方面的技术方面。

除此之外,关于最佳实践,我想说的是:

  1. 鉴于保护数据是 DBA 的工作/责任,默认方法应该是这样做,因为 DBA 认为合适,并且需要一个可靠的业务案例来进行更改。一个假设的未来潜力在一定程度上可能给定的某些条件,稍后将进行头脑风暴,并在此之后得到确认,但可能会在以后或可能永远不会改变- 实际发生的原因(即“出于某种原因”)似乎有点站不住脚,尤其是当话题正在改变公司标准/实践时。

  2. 永远不要相信那些想要改变永远不应该改变的东西的人;-),(如果他们甚至不知道为什么要这样做,那就更是如此)。

  3. 告诉开发人员,欢迎他们将此类逻辑添加到应用程序代码中以阻止这些更新。但是,您也不会删除DENY. 如果/当这一天到来(并且它也许不会可能不会)有人在尝试更新这些列之一时出错,然后您可以讨论是否要删除DENY,这将需要实际的、可靠的理由来说明为什么有人会在第一名。

    重点是:应该有一个真正的商业案例来推动人们花时间。时间供不应求,因此您(和其他所有人)有比根据某人的意见更改系统更重要的事情要做。总会有各种各样的意见(空格还是制表符,有人吗?)如果那个开发人员离开并被一个强烈反对这些字段可更新的人所取代,你可能会花费数年时间来回改变这一点。如果没有客户要求这个(或需要它的东西),并且没有切实的好处(即使是延迟的好处,例如清理技术债务,这很难显示 ROI,但鉴于从长远来看,花费的时间不会导致实际成本节省的可能性很小甚至没有),然后要么关闭请求,要么将其以低优先级放在待办事项中,即使在理想主义说它应该改变的情况下(这不是这些情况之一,但对于那些认为它是的人提到了)。理想主义很适合谈话,但公司不能用理想来支付租金、水电费、员工、税收等。

  4. @jpmc26 关于交流的需要是正确的,但对于需要交流的内容并不完全正确。是的,您应该倾听其他人的要求并设法理解他们的推理,包括在您对任何事情不清楚时提出问题。

    然而,数据库并不从属于应用程序,数据库专业人员(管理员、工程师,无论您的公司使用什么名称)也不从属于开发人员(正如该答案中所暗示的那样)。你不是为开发人员工作,而是为公司工作,就像他们一样。这是一个团队的努力,你不应该因为你的工作而请求原谅。也就是说,我们计算机类型(通常)并不以我们的人际沟通技巧而闻名,因此,您确实需要确保其他人了解,您的推理是什么,您的职责是什么,以及这些东西实际上是如何工作的.

    我放在最后一部分是因为那里存在高度误解、错误信息和缺乏知识(甚至就在这一页上)。例如,似乎存在所有规则都是业务规则的概念。我们需要说明的是有数据的规则和业务规则(@Aaron简称本作中,有关这一问题的意见“的工作流程约束VS数据约束”)之间的区别,虽然大多数数据自然也属于应用,一些数据实际上属于数据模型。如果一个DBA支配的开发人员如何应用数据受到限制?当然不是。我们的工作是提供应用程序数据如何受到约束。如果违反与应用程序数据相关的业务规则可能会造成损害,并且应用程序不是100%操作数据的唯一方式,那么检查约束可能真的有帮助(并且它们并不难更改或删除) )。

    但是,从另一个方向来看,开发人员不应该规定如何处理数据模型数据(即元数据)。这包括审计字段(例如created_on/created_by列)和 PK / FK 列(这些值仅应在内部已知,而不应提供给客户)。此数据不是应用程序存储的关于客户的内容(即使应用程序可以看到值甚至使用它们,例如使用 ID),而是数据模型存储的关于应用程序数据的内容。

    所以使用数据规则来保护数据模型数据是有意义的。并且这样做并不意味着您即将开始对应用程序数据添加约束或限制。但是,如果不理解这种区别,就很难以真正富有成效的方式推进对话。

所以:

  1. 是的,我喜欢DENY审计专栏上明确的想法,并且在我过去工作过的地方也提出过同样的想法。
  2. 有趣的是,当我开始添加外键时,我可能在 2000 年与首席开发人员(非常好的一次)进行了非常相似的对话。他(非常认真地)辩称,这是不必要的过度设计/理想主义(类似的事情,自那次谈话以来已经 17 年了)并且不值得对性能造成影响。他很清楚,清理相关数据应该在app层处理。(是的,我确实添加了 FK,因为他不会清理他的代码不可避免地创建的孤立数据)

    多年后,他为提出这个论点而道歉;-)


jpm*_*c26 7

这可能是一个 XY 问题。开发人员可能并不特别关心阻止对像created_on. 这个特殊的例子是一个非常温和的约束。

开发人员可能担心 DBA 团队(包括您)打算添加如此多或如此复杂的限制,从而开始阻碍他们有效工作的能力,或者当出现异常情况或发生变化时,DBA 团队将抵制更改并阻碍开发人员团队取得进展的能力。这是一个相对合理的担忧。官僚主义和失去影响所需变更的能力是真实发生的,编码过多或复杂的约束会对性能和响应需求变化的能力产生负面影响。

开发人员甚至可能没有意识到这是他们关注的本质。他们可能习惯于拥有数据库的自由支配权,而放弃这种自由程度是很困难的,尤其是如果您知道自己从未滥用过它。因此,他们对失去做他们需要做的事情的能力的担忧很可能是模糊和不明确的。

因此,您应该做一些事情来缓解这些恐惧:

  1. 与开发人员进行大量沟通。确保您了解他们正在尝试构建的功能的需求,并确保您在发生变化时做出响应。倾听他们的意见,并努力找到平衡他们与您的担忧的解决方案。当他们有正当需要时,愿意屈服。确保他们知道您是他们构建软件的盟友
  2. 谨慎设置限制。限制,即使是旨在提供完整性和安全性的限制,也会使适应变化或处理不可预见的情况变得更加困难。因此请理解,您添加的每个限制都可能会产生与之相关的成本,因为它可能会节省成本(主键和外键可能除外,它们几乎没有缺点)。确信你施加的限制是真正需要或有益的。
  3. 我没有看到您这样做的任何迹象,但我想向任何其他读者提及:不要将数据或数据库视为或您的团队的责任。数据是整个公司的资产。如果没有系统来存储它(数据库)脚本、工具或应用程序来创建、更新和获取它,数据就毫无价值。因为每个人都必须使用这个资产,所以数据是每个人的责任。数据库本身只是从数据中获取价值的一部分。