zoukankan      html  css  js  c++  java
  • 视图、约束、索引

    一、视图

          本质上相当于一张“虚拟表”,可当作独立的一张表进行操作(增、删、改、查)

          作用:

           a)可通过权限控制,只将“表中的少数列”暴露给数据库用户,而不让该用户直接操纵数据库中“实际表”

           b)可将常用的,较复杂的SQL在数据库中预先定义好,使得外部调用不用每次都编写复杂的SQL语句,

           接当作一张“虚拟表”来调用即可

           Customers表中原始数据:

          Orders表中的原始数据:

          创建“查找运费在40到60之间的客户信息”的视图:

    1 use edisondb;
    2
    3  if object_id('FortyToSixtyFreightCusts')is not null
    4 drop view FortyToSixtyFreightCusts
    5  go
    6  create view FortyToSixtyFreightCusts
    7  as
    8
    9  select C.custid as '客户ID',C.name as '客户名', C.age as '年龄'
    10  from customers as C
    11  where Exists(
    12 select *
    13 from Orders as O
    14 where C.custid=O.custid and (O.freight between 40 and 60)
    15 );

         创建成功之后:

        将该视图当作一张“独立的表”进行查询操作:

    1 use edisondb;
    2  select 客户ID,客户名,年龄 from FortyToSixtyFreightCusts;
       执行结果如下:

       关于SCHEMABINDING选项的一些说明:

             作用:使得视图中引用的对象不能被删除,被引用的列不能被删除或者修改(防止:由于引用的列等被删除,造成视图无法使用的情况

        修改视图,使其指定SCHEMABINDING选项: 

    1 alter view FortyToSixtyFreightCusts with schemabinding
    2  as
    3
    4  select C.custid as '客户ID',C.name as '客户名', C.age as '年龄'
    5  from dbo.customers as C
    6  where Exists(
    7 select O.custid
    8 from dbo.Orders as O
    9 where C.custid=O.custid and (O.freight between 40 and 60)
    10 );
    11  go

    (以上表名,一定要以“dbo.***”的形式出现,否则会出现:名称 'customers' 对于架构绑定无效的错误)

         尝试删除Customers表中的age列:        

    1 use edisondb;
    2 alter table customers drop column age;
        执行结果:          

           

        附:可通过执行以下语句查看SQL Server中某对象的定义:      

    1 exec sp_helptext 'dbo.FortyToSixtyFreightCusts';
        执行结果如下: 


    二、约束

       1)检查约束【通常认为的“约束”

           创建检查约束:

    1 use edisondb;
    2  alter table staffinfo
    3  add constraint ck_StaffID check(StaffID between 5000 and 5999)

          成功创建之后:

          此时执行非法的插入行:

    1 use edisondb;
    2  insert into StaffInfo(StaffID,StaffName,Department)
    3 values(6000,'Wade','Dev');

         执行结果为:

       2)唯一性约束

          StaffInfo表原始数据:

         创建唯一性约束:

    1 use edisondb;
    2  alter table staffinfo
    3  add constraint uq_StaffName unique(StaffName);
         成功创建后:

              注:唯一性约束创建成功后,是在“键”中显示,而非“约束”

         此时执行非法的插入行:

    1 use edisondb;
    2  insert into StaffInfo(StaffID,StaffName,Department)
    3 values(5003,'keven','Dev');
        执行结果为:


          说明:要使某列的值唯一,既可以通过主键来实现,也可以通过“唯一性约束”来实现

       3)默认约束

         创建默认约束:

    1 use edisondb;
    2  alter table staffinfo
    3  add constraint df_Department default('部门待定') for Department;

         成功创建后:

        执行行插入:

    1 use edisondb;
    2  insert into StaffInfo(StaffID,StaffName)
    3 values(5003,'Murphy');
       执行结果为:


      注:主键和外键也属于一种约束


    三、索引

      1.聚集索引

           对应于数据库中数据文件的物理存储方式,每张表只能建立一个

           适用场合:a)select次数远大于insert、update的次数(insert、update时需要移动其他数据文件的物理位置)
                          b)建立聚合索引的列,既不能绝大多数都相同,又不能只有极少数相同(可从类似二维数组查找时间复杂的方式去理解)

           创建一个NewOrders表,用于对索引的测试:

    1 use edisondb;
    2
    3 create table NewOrders
    4 ( orderID numeric(18, 0) identity(1,1) not null,
    5 custID numeric(18, 0) not null,
    6 empID numeric(18, 0) not null,
    7 tradeDate datetime not null
    8 );

            在NewOrders表中插入10万条测试数据:

    1 use edisondb;
    2 set nocount on
    3 declare @i numeric(18,0)
    4 declare @custid numeric(18,0)
    5 declare @empid numeric(18,0)
    6 declare @tradeDateTime datetime
    7 begin
    8 set @i=0
    9 set @custid=100000
    10 set @empid=500000
    11 set @tradeDateTime=getdate()
    12 while @i<100000
    13 begin
    14 insert into neworders(custID,empID,tradeDate)
    15 values(@custid,@empid,@tradeDateTime)
    16 set @i=@i+1
    17 set @custid=@custid+1
    18 set @empid=@empid+1
    19 if (@i%1000)=0
    20 set @tradeDateTime=dateadd(day,1,@tradeDateTime)
    21 end
    22 end
    23 print 'Insert data over'
         插入数据成功之后,NewOrders表中的部分数据如下:

         进行查询测试

    1 use edisondb;
    2 declare @startDT datetime
    3 set @startDT=getdate()
    4 select * from neworders where tradedate> dateadd(day,10,'2011-9-20')
    5 print '耗时:'+replace(str(datediff(ms,@startDT,getdate())),' ','')+' 毫秒'

         执行结果为:

         现在对建立“聚集索引”的表进行测试

         删除表中所有行:

    1use edisondb
    2truncate table neworders;
         在NewOrders表的tradeDate列上创建“聚集索引”

    1use edisondb
    2create clustered index tradeDate_NewOrders on NewOrders(tradeDate)
        执行结果为:

         再次插入10万行数据后,进行测试,结果为:


           聚合索引使用的关键:合适的列建立(通常为:最多用作查询条件的列)

      2.非聚集索引

  • 相关阅读:
    关于区间数颜色的主席树解决
    1020考试总结
    QR算法
    新的征程
    端点星2020.12.2联赛
    自我介绍&友链
    3个搜索
    搜索格式这样写
    T107073 归并排序
    还有这个题
  • 原文地址:https://www.cnblogs.com/edisonfeng/p/2098793.html
Copyright © 2011-2022 走看看