提交需求
*
*

*
*
*
立即提交
点击”立即提交”,表明我理解并同意 《美创科技隐私条款》

logo

    产品与服务
    解决方案
    技术支持
    合作发展
    关于美创

    申请试用
      运维日记|SQL server 所有权链(上篇)
      发布时间:2020-09-01 阅读次数: 348 次

      XXX,你好,我们的工作人员在删除数据时意外将整表删除了,现已恢复数据,想咨询下有什么办法防止这种误删操作吗?


      在了解了客户需求后,发现该工作人员必须每天删除固定时间段内的数据,所以,简单一刀切(回收delete的权限)的方法明显不可用……


      是不是真的束手无策了???哈哈哈,那我今天就给大家带来一个SQL server鲜为人知的知识点:SQL server 所有权链


      一、什么是SQL server所有权链


             当一个对象引用另外一个对象且两个对象有相同的所有者时,就形成了所有权链。当所有权链形成时,SQL Server 将仅仅检查第一个对象的权限,即便第二个对象拒绝了用户的权限。


      二、理解SQL server对象的有效所有者


             上面提到,一个对象引用另一个对象,很好理解,可是拥有相同的所有者,该如何理解呢?


             在SQL server 2005以后,我们创建数据库对象,比如表、存储过程的时候不会特意的去指定其所有者,但并不代表没有,细致的朋友肯定发现,默认情况下我们的表、存储过程的所有者是dbo,但这不代表只要创建对象,其所有者就是dbo。


          是不是听起来有点绕口,因为我们平时很少会去关注所有者这一概念,下面我们演示一下,方便大家理解。



      2.1 创建3个架构


             为什么要创建架构呢,因为,架构必须存在所有者,如果创建的时候不指定,那么创建的用户就会成为该架构的所有者。


      --1、创建架构schema_1、schema_2和schema_3(其中schema_3指定所有者为db_datareader)



      --2、查询架构及其所有者



      2.2 创建三个对象


      --1、创建表TestTable、存储过程QueryTestTable和表TestTable_1



      --2 、查询三个对象的所有者



      呦呵,TestTable_1表的所有者不是dbo,那么这个时候我们就明白了,所谓对象的所有者,在不指定的时候其实就是该对象所属架构的所有者。


      三、所有权链使用演示


      3.1 创建用户user_1



      3.2 往schema_1.TestTable里插入数据



      3.3 使用user_1登录查询该表



      3.4 使用user_1执行存储过程



      妈耶,什么鬼,同样是user_1,为啥直接查询被拒绝,通过存储过程就可行呢,真神奇……


      四、总结


      通过上面的演示,我们可以看到,dsz.schema_1.TestTable表和

      `schema_2`.`QueryTestTable`存储过程拥有相同的所有者dbo,所以在用存储过程调用表的时候,只验证用户是否有执行该存储过程的权限,不会去对调用的表做第二次权限校验,这就是SQL server所有权链。


      所以,针对前文客户所提的需求,我们只需要用存储过程调用表,通过传递日期参数进行删除,不提供对表直接进行delete,这样就完美避免了误删全表的可能,很有魅力吧。


      如果大家对所有权链很有兴趣,可持续关注公众号,后续我会分享不同数据库间如何实现所有权链以及如何合理使用。

      免费试用
      服务热线

      马上咨询

      400-811-3777

      回到顶部