我习惯于在非常安全的环境中工作,因此我将权限设计得非常精细。我通常做的一件事是明确地让DENY
用户能够访问UPDATE
不应该更新的列。
例如:
create table dbo.something (
created_by varchar(50) not null,
created_on datetimeoffset not null
);
一旦设置了值,就不应更改这两列。DENY
因此,我会明确UPDATE
许可他们。
最近,在一次团队会议上,一位开发人员提出了确保字段永不更新的逻辑应该包含在应用程序层而不是数据库层中,以防“他们出于某种原因需要更新值”。对我来说,这听起来像是典型的开发者心态(我知道,我曾经是其中的一员!)
我是我公司的高级架构师,我一直遵循使应用程序运行所需的最少权限的原则。所有权限都会定期审核。
在这种情况下,最佳做法是什么?
争论没有意义。我总是希望控件和约束尽可能接近数据。将它放在应用层意味着它只会影响使用应用层的人,并且还假设代码将没有错误,并且这些代码路径的安全性将是无懈可击的。这些都是很大的假设。
如果他们绝对需要更新,那么可以由不受显式影响的人来完成
DENY
,或者可以暂时将人移到不受影响的角色中,或者DENY
可以暂时移除 。作为 DBA,这些对于您来说很容易设置审计。在应用程序中?没那么多。我在技术方面完全同意@Aaron。
除此之外,关于最佳实践,我想说:
鉴于保护数据是 DBA 的工作/责任,默认方法应该是这样做,因为 DBA 认为合适,并且需要可靠的业务案例来进行更改。假设-未来-潜力-在一定条件下可能会-稍后进行头脑风暴-并在此之后确认-但-可能-稍后改变-或-可能-永远不会-实际发生的原因(即“出于某种原因”)似乎有点站不住脚,尤其是当主题正在改变公司标准/实践时。
永远不要相信那些想要改变不应该改变的东西的人;-),(如果他们甚至不知道他们为什么要这样做,那就更是如此)。
告诉开发人员,欢迎他们将此类逻辑添加到应用程序代码中以防止这些更新。但是,你也不会删除
DENY
. 如果/当那一天到来时(它也许不会可能不会)有人在尝试更新这些列之一时出错,那么您可以讨论是否要删除DENY
第一名。要点是:应该有一个真实的商业案例来推动人们将时间花在什么上面。时间供不应求,因此您(和其他所有人)有比根据某人的意见更改系统更重要的事情要做。总会有各种各样的意见(空格与制表符,有人吗?),如果该开发人员离开并被强烈反对这些字段可更新的人取代,您可能会花费数年时间来回更改这一点。如果没有客户要求这个(或需要它的东西),并且没有切实的好处(甚至是诸如清理技术债务之类的延迟收益,这很难显示投资回报率,但考虑到从长远来看,花费的时间不会导致实际成本节约的可能性很小甚至没有),然后要么关闭请求,要么把它放在低优先级的积压工作中,即使在理想主义说它应该改变的情况下(这不是其中一种情况,但对于那些认为它是这样的人来说)。理想主义非常适合交谈,但公司无法用理想支付租金、水电费、员工、税金等。
@jpmc26 关于交流的需要是正确的,但关于需要交流的内容并不完全正确。是的,您应该倾听其他人的要求并寻求理解他们的推理,包括在您不清楚任何事情时提出问题。
但是,数据库不服从于应用程序,并且数据库专业人员(管理员、工程师,无论您的公司使用什么名称)都不服从于开发人员(正如该答案中所暗示的那样)。你不为开发人员工作,你为公司工作,和他们一样。这是一个团队的努力,你不应该原谅你的工作。也就是说,我们计算机类型(通常)并不以我们的人际沟通技巧而闻名,因此,您确实需要确保其他人理解您,您的推理是什么,您的责任是什么,以及这些东西实际上是如何工作的.
我放最后一部分是因为那里存在高度的误解、错误信息和缺乏知识(甚至在这一页上也有一些)。例如,似乎有这样一种观念,即所有规则都是业务规则。我们需要解释一下,数据规则和业务规则之间是有区别的(@Aaron 在对问题的评论中将此称为“工作流约束与数据约束”),虽然大多数数据自然属于应用程序,但有些数据实际上属于数据模型。DBA是否应该向开发人员指示如何约束应用程序数据?当然不是。我们的工作是提供应用程序数据如何受到约束。如果违反与应用程序数据相关的业务规则可能会造成损害,并且应用程序不是100% 操作数据的唯一方法,那么检查约束可能真的有帮助(并且它们不难更改或删除)。
但是,从另一个方向来看,开发人员不应该规定如何处理数据模型数据(即元数据)。这包括审计字段(例如
created_on
/created_by
列)和 PK / FK 列(这些值应该只在内部知道,而不是提供给客户)。这些数据不是应用程序存储的关于客户的内容(即使应用程序可以看到这些值,甚至可以使用它们,例如使用 ID),它是数据模型存储的关于应用程序数据的内容。因此使用数据规则来保护数据模型数据是有意义的。这样做并不意味着您即将开始对应用程序数据添加约束或限制。但是,如果不理解这种区别,就很难以真正富有成效的方式推进对话。
所以:
DENY
审计专栏中明确提出的想法,并且在我过去工作过的地方也提出了同样的建议。有趣的是,我可能在 2000 年开始添加外键时,与一位首席开发人员(一个非常好的)进行了非常相似的对话。他(非常认真地)争辩说,这是不必要的过度设计/理想主义(类似那样,距离那次谈话已经 17 年了),不值得对性能造成影响。他很清楚,清理相关数据应该在应用层处理。(是的,我确实添加了 FK,因为他不会成为清理他的代码不可避免地会创建的孤立数据的人)
多年后,他为提出这种论点而道歉;-)
这可能是一个 XY 问题。开发人员可能并不特别关心阻止对真正恒定字段(如
created_on
. 这个特殊的例子是一个非常温和的约束。开发人员可能担心 DBA 团队(包括您)打算添加如此多或如此复杂的限制,以致开始阻碍他们有效工作的能力,或者当出现异常情况或发生变化时,DBA 团队将抵制这些变化并阻碍开发团队取得进展的能力。这是一个相对合理的担忧。官僚主义和失去影响所需更改的能力是真实发生的,编码过多或复杂的约束可能会对性能和响应需求变化的能力产生负面影响。
开发人员甚至可能没有意识到这是他们关注的本质。他们可能已经习惯了对数据库的自由支配,而放弃这种程度的自由是很困难的,尤其是如果您知道自己从未滥用过它。因此,他们对失去做他们需要做的事情的能力的担忧很可能是模糊的和不明确的。
因此,您应该做几件事来缓解这些恐惧:
你有相互矛盾的陈述
真的由你来决定第一个吗?
在没有证明应用程序永远不需要更新值的情况下,您至少可以让应用程序运行。
谁负责数据完整性?
有了 SQL 约束,你能保证数据的完整性吗?不,你不能,因为经常有超出数据库可以做的业务规则。
VendorID永远不应该改变,但是如果两个供应商合并怎么办。永远不要把话说绝了。
如果应用程序团队污染了数据并且他们说他们需要该权限,那么它就在他们身上。如果应用程序团队为您工作,那么您可以发号施令。
适当的问题是应用程序是否应该更新数据。