主页 > 知识库 > 数据库 > SQL server >

SQL Server索引进阶第八篇:唯一索引

来源:博客园 作者:宋沄剑 发表于:2012-09-12 09:17  点击:
索引设计是数据库设计中比较重要的一个环节,对数据库的性能其中至关重要的作用,但是索引的设计却又不是那么容易的事情,性能也不是那么轻易就获取到的,很多的技术人员因为不恰当的创建索引,最后使得其效果适得其反,可以说成也索引,败也索引。 本系列文
索引设计是数据库设计中比较重要的一个环节,对数据库的性能其中至关重要的作用,但是索引的设计却又不是那么容易的事情,性能也不是那么轻易就获取到的,很多的技术人员因为不恰当的创建索引,最后使得其效果适得其反,可以说“成也索引,败也索引”。
   本系列文章来自Stairway to SQL Server Indexes,翻译和整理后发布在agilesharp和博客园,希望对广大的技术朋友在如何使用索引上有所帮助。

唯一索引和约束

   唯一索引和其它索引本质上并没有什么不同,唯一不同的是唯一索引不允许索引键中存在相同的值。因为索引中每一个条目都与表中的行对应。唯一索引不允许重复值被插入索引也就保证了对应的行不允许被插入索引所在的表,这也是为什么唯一索引能够实现主键和候选键。
   为表声明主键或唯一约束时,SQL Server会自动创建与之对应的唯一索引。你可以在没有唯一约束的情况下创建唯一索引,但反之则不行。定义一个约束时,SQL Server会自动创建一个与之同名的索引,并且你不能在删除约束之前删除索引。但可以删除约束,删除约束也会导致与之关联的索引被删除。
   每个表中可以包含多个唯一索引。比如说AdventureWorks的Product表,含有四个唯一索引,分别是 ProductID,ProductNumber,rowguid和ProductNameColumn,设置Product表的人将ProductID 作为主键,其它三个作为候选键。
    你可以通过Create INDEX语句创建唯一索引,比如:
双击代码全选
1
2
CREATE UNIQUE NONCLUSTERED INDEX [AK_Product_Name] ON Production.Product (
[Name] );
 

    也可以通过直接定义约束创建唯一索引:
双击代码全选
1
2
ALTER TABLE Production.Product ADD CONSTRAINT PK_Product_ProductID PRIMARY KEY
CLUSTERED ( ProductID );
 

   上面第一种方法,你Prodcut表中不能含有相同的ProductName,第二种情况表中不允许存在相同的ProductID。
   因为定义一个主键或是定义约束会导致索引被创建,所以你必须在约束定义时就给出必要的索引信息,因此上面ALTER TABLE语句中包含了”CLUSTERED”关键字。
   如果唯一索引或约束所约束的列在当前的表中已经含有了重复值,那么创建索引会失败。
   而当唯一索引创建成功后,所有违反这个约束的DML语句都会失败,比如,我们打算加入一条当前表中存在的的ProductName,语句如下:
双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<p>INSERT    Production.Product
                    ( Name ,
                      ProductNumber ,
                      Color ,
                      SafetyStockLevel ,
                      ReorderPoint ,
                      StandardCost ,
                      ListPrice ,
                      Size ,
                      SizeUnitMeasureCode ,
                      WeightUnitMeasureCode ,
                      [Weight] ,
                      DaysToManufacture ,
                      ProductLine ,
                      Class ,
                      Style ,
                      ProductSubcategoryID ,
                      ProductModelID ,
                      SellStartDate ,
                      SellEndDate ,
                      DiscontinuedDate
                    )
          VALUES    ( 'Full-Finger Gloves, M' ,
                      'A unique product number' ,
                      'Black' ,
                      4 ,
                      3 ,
                      20.00 ,
                      40.00 ,
                      'M' ,
                      NULL ,
                      NULL ,
                      NULL ,
                      0 ,
                      'M' ,
                      NULL ,
                      'U' ,
                      20 ,
                      3 ,
                      GETDATE() ,
                      GETDATE() ,
                      NULL
                    ) ; </p>
  <div style=" display:block; width:100%; padding-top:15px; margin:0px auto; height:90px; overflow:hidden; text-align:center;"><script src="/2011/ads/tech_content_end_468x60.js"></script><script type="text/javascript"><!--
google_ad_client = "pub-5977682010997732";
/* 468x60,  09-9-9 */
google_ad_slot = "4048873275";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script><ins style="display:inline-table;border:none;height:60px;margin:0;padding:0;position:relative;visibility:visible;width:468px"><ins id="aswift_1_anchor" style="display:block;border:none;height:60px;margin:0;padding:0;position:relative;visibility:visible;width:468px"><iframe allowtransparency="true" hspace="0" marginwidth="0" marginheight="0" onload="var i=this.id,s=window.google_iframe_oncopy,H=s&&s.handlers,h=H&&H[i],w=this.contentWindow,d;try{d=w.document}catch(e){}if(h&&d&&(!d.body||!d.body.firstChild)){if(h.call){i+='.call';setTimeout(h,0)}else if(h.match){i+='.nav';w.location.replace(h)}s.log&&s.log.push(i)}" vspace="0" id="aswift_1" name="aswift_1" style="left:0;position:absolute;top:0;" frameborder="0" height="60" scrolling="no" width="468"></iframe></ins></ins>
</div>

有帮助
(0)
0%
没帮助
(0)
0%