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.非聚集索引

  • 相关阅读:
    sql2slack alash3al 开源的又个轻量级工具
    pgspider fetchq 扩展docker镜像
    godns 集成coredns 的demo
    godns 简单dnsmasq 的dns 替换方案
    aviary.sh 一个基于bash的分布式配置管理工具
    使用coredns 的template plugin实现一个xip 服务
    nginx 代理 coredns dns 服务
    基于nginx proxy dns server
    几个不错的geodns server
    spring boot rest api 最好添加servlet.context-path
  • 原文地址:https://www.cnblogs.com/edisonfeng/p/2098793.html
Copyright © 2011-2022 走看看