1

在 MSSQL 2016 中向受行级别安全保护的表添加新列时,尝试使用 SQL Server Data Tools 发布数据库时出现以下错误:

当前操作将导致表 X 上的数据移动。无法在此表上执行数据移动,因为它具有策略 Y 启用的行级安全性。要允许此操作,请使用带有选项 /p:AllowUnsafeRowLevelSecurityDataMovement 的 SqlPackage.exe

我怀疑它想要重新创建表,如果 RLS 谓词未授予部署用户对数据的访问权限,这可能会导致数据丢失。但是我找不到任何关于此的文档。

更重要的是,处理这种部署场景的最佳实践是什么?

4

1 回答 1

3

这个场景有两个方面:

  • 为什么添加列会导致发生数据移动操作?
  • 行级安全性带来的危险是什么?

最小化/避免数据移动

通常,添加新列不需要数据移动。如果添加到表定义的末尾,这可以通过 ALTER TABLE ADD COLUMN 操作来完成,SSDT 足够聪明,可以为您执行此操作。但是,如果添加到表的中间,则默认行为是执行完整的数据移动,这在大型表上可能会非常昂贵。为了避免这种情况:

  • 始终尝试在可能的情况下将列添加到末尾。
  • 如果这是不可能的,最新版本的 SSDT 和 SqlPackage 有一个IgnoreColumnOrder标志,它将把表中间的列添加视为添加到末尾。这可能会导致一些复杂性(例如,模式比较也必须设置此设置,否则它会显示源项目和表的数据库版本之间的差异),但通常值得这样做,以避免在部署期间不必要的数据移动

处理行级安全 (RLS) + 数据移动

如果您确实需要进行导致数据移动的更改,RLS 的风险是您的用户无权访问表中的所有行。由于数据移动将数据复制到临时表,然后删除原始表并进行重命名,因此您将丢失用户看不到的任何行。

解决方案是设置/p:AllowUnsafeRowLevelSecurityDataMovement标志,但要验证您的用户不属于任何行级过滤方案。一个好的做法是仅将这些方案应用于具有有限权限的用户(例如您的应用程序角色),而在部署时使用具有更大权限的角色(管理员角色)。如果你这样做,你可以安全地部署,但至少有一个标志来警告这个/避免意外的数据丢失。

于 2017-10-18T19:54:01.013 回答