必知必会SQL(贰) --索引(聚集[簇]索引和非聚[簇]集索引) vs 全文本索引
①联结
定义:基于两个表之间相等的查询:等值联结(equijoin)也称内部联结
eg:
SELECT a,b,c FROM A ,B WHERE A.a=B.a
SELECT a,b,c FROM A INNER JOIN B ON A.a=B.a
结果是一样但顺序可能不一样,当然了加一个ORDER BY 子句则上面两个是完全一样的
至于二者的区别:ANSI SQL规范首选是INNER JOIN语法。
假如:select 返回4条数据 select 返回5条数据
假如用UNION 联合查询返回几条数据呢?
8条数据 重复的不返回(重复的被取消)
要返回全部匹配行:UNION ALL
②索引
--创建表
--创建表 CREATE TABLE [dbo].[tabTest] ( [ID] [int] IDENTITY (1, 1) NOT NULL ,--非空约束 [unqValue] [uniqueidentifier] NOT NULL ,--非空约束 [intValue] [int] NOT NULL--非空约束 ) ON [PRIMARY]--注意格式中括号不可少 GO
聚集索引的区别
聚集索引:物理存储按照索引排序
非聚集索引:物理存储不按照索引排序
优势与缺点
聚集索引:插入数据时速度要慢(时间花费在“物理存储的排序”上,也就是首先要找到位置然后插入),查询数据比非聚集数据的速度快
聚集索引的区别
聚集索引:物理存储按照索引排序
非聚集索引:物理存储不按照索引排序
优势与缺点
聚集索引:插入数据时速度要慢(时间花费在“物理存储的排序”上,也就是首先要找到位置然后插入),查询数据比非聚集数据的速度快
索引是通过二叉树的数据结构来描述的,我们可以这么理解聚簇索引:索引的叶节点就是数据节点。而非聚簇索引的叶节点仍然是索引节点,只不过有一个指针指向对应的数据块
--添加聚集(簇)索引
要求:“既不能绝大多数都相同,又不能只有极少数相同”
ALTER TABLE [dbo].[tabTest] WITH NOCHECK ADD CONSTRAINT [PK_tabTest] PRIMARY KEY CLUSTERED ( [ID] ) ON [PRIMARY] GO
参数说明:重点是约束
WITH NOCHECK :重新启用的约束;WITH CHECK:新约束 ,
CONSTRAINT [kənˈstreint]强制;限制;约束:
MS SQL Server 提供的自动保持数据库完整性的一种方法,定义了可输入表或表的单个列中的数据的限制条件。
共有5 种约束:主关键字约束(Primary Key Constraint)、外关键字约束(Foreign Key Constraint)、惟一性约束(Unique Constraint)、检查约束(Check Constraint)和缺省约束(Default Constraint)
1、主关键字约束(Primary Key Constraint)
语法 : CONSTRAIN constraint_name PRIMARY KEY [CLUSTERED | NONCLUSTERED] (column_name1[, column_name2,…,column_name16])
constraint_name 指定约束的名称约束的名称,在数据库中应是惟一的。如果不指定,则系统会自动生成一个约束名。
CLUSTERED | NONCLUSTERED 指定索引类别,CLUSTERED 为缺省值。
column_name 指定组成主关键字的列名
如: 创建一个产品信息表,以产品编号和名称为主关键字
create table products ( p_id char(8) not null, p_name char(10) not null , price money default 0.01 , quantity smallint null , constraint pk_p_id primary key (p_id, p_name) ) on [primary]
2、外关键字约束:外关键字约束定义了表之间的关系(Foreign Key Constraint):
当一个表中的一个列或多个列的组合和其它表中的主关键字定义相同时,就可以将这些列或列的组合定义为外关键字,并设定它适合哪个表中哪些列相关联。这样,当在定义主关键字约束的表中更新列值,时其它表中有与之相关联的外关键字约束的表中的外关键字列也将被相应地做相同的更新。外关键字约束的作用还体现在,当向含有外关键字的表插入数据时,如果与之相关联的表的列中无与插入的外关键字列值相同的值时,系统会拒绝插入数据。与主关键字相同,不能使用一个定义为 TEXT 或IMAGE 数据类型的列创建外关键字。外关键字最多由16 个列组成。定义外关键字约束的语法:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
CONSTRAINT constraint_name FOREIGN KEY (column_name1[, column_name2,…,column_name16]) REFERENCES ref_table [ (ref_column1[,ref_column2,…, ref_column16] )] [ ON DELETE { CASCADE | NO ACTION } ] [ ON UPDATE { CASCADE | NO ACTION } ] ] [ NOT FOR REPLICATION ]
说明:
REFERENCES 指定要建立关联的表的信息。ref_table 指定要建立关联的表的名称。ref_column 指定要建立关联的表中的相关列的名称。
ON DELETE {CASCADE | NO ACTION} 指定在删除表中数据时,对关联表所做的相关操作。在子表中有数据行与父表中的对应数据行相关联的情况下,如果指定了值CASCADE([kæˈskeɪd]倾泻;小瀑布,瀑布状物),则在删除父表数据行时会将子表中对应的数据行删除;如果指定的是NO ACTION,则SQL Server 会产生一个错误,并将父表中的删除操作回滚。NO ACTION 是缺省值。
ON UPDATE {CASCADE | NO ACTION} 指定在更新表中数据时,对关联表所做的相关操作。在子表中有数据行与父表中的对应数据行相关联的情况下,如果指定了值CASCADE,则在更新父表数据行时会将子表中对应的数据行更新;如果指定的是NO ACTION,则SQL Server 会产生一个错误,并将父表中的更新操作回滚。NO ACTION 是缺省值。
NOT FORREPLICATION ([ˌrepliˈkeiʃən]复制,折叠;回答;反响;[植]反叠)指定列的外关键字约束在把从其它表中复制的数据插入到表中时不发生作用。如:创建一个订货表,与前面创建的产品表相关联 create table orders( order_id char(8), p_id char(8), p_name char(10) , constraint pk_order_id primary key (order_id) , foreign key(p_id, p_name) references products(p_id, p_name) ) on [primary]
注意:临时表不能指定外关键字约束。
3、惟一性约束:指定一个或多个列的组合的值具有惟一性,以防止在列中输入重复的值。惟一性约束指定的列可以有NULL 属性。由于主关键字值是具有惟一性的,因此主关键字列不能再设定惟一性约束。惟一性约束最多由16 个列组成。定义惟一性约束的语法如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
CONSTRAINT constraint_name UNIQUE [CLUSTERED | NONCLUSTERED] (column_name1[, column_name2,…,column_name16])
如:定义一个员工信息表,其中员工的身份证号具有惟一性。
create table employees ( emp_id char(8), emp_name char(10) , emp_cardid char(18), constraint pk_emp_id primary key (emp_id), constraint uk_emp_cardid unique (emp_cardid) ) on [primary]
4、检查约束:对输入列或整个表中的值设置检查条件,以限制输入值,保证数据库的数据完整性。可以对每个列设置符合检查。定义检查约束的语法如下:
CONSTRAINT constraint_name CHECK [NOT FOR REPLICATION] (logical_expression)
各参数说明如下: NOT FOR REPLICATION 指定检查约束在把从其它表中复制的数据插入到表中时不发生作用。 logical_expression 指定逻辑条件表达式返回值为TRUE 或FALSE。
如: 创建一个订货表其中定货量必须不小于10。
create table orders( order_id char(8), p_id char(8), p_name char(10) , quantity smallint, constraint pk_order_id primary key (order_id), constraint chk_quantity check (quantity>=10) , ) on [primary]
注意:对计算列不能作除检查约束外的任何约束。
5、缺省约束:通过定义列的缺省值或使用数据库的缺省值对象绑定表的列,来指定列的缺省值。SQL Server 推荐使用缺省约束,而不使用定义缺省值的方式来指定列的缺省值。
定义缺省约束的语法如下:
CONSTRAINT constraint_name DEFAULT constant_expression [FOR column_name]
如:
constraint de_order_quantity default 100 for order_quantity
注意:不能在创建表时定义缺省约束,只能向已经创建好的表中添加缺省约束。
6、 列约束和表约束对于数据库来说,约束又分为列约束(Column Constraint)和表约束(Table Constraint)。列约束作为列定义的一部分只作用于此列本身。表约束作为表定义的一部分,可以作用于多个列。
下面举例说明列约束与表约束的区别。如:
create table products ( p_id char(8) , p_name char(10) , price money default 0.01 , quantity smallint check (quantity>=10) , /* 列约束 */ constraint pk_p_id primary key (p_id, p_name) /* 表约束 */
约束说完继续索引
-- unqValue 建立普通索引
ALTER TABLE [dbo].[tabTest] ADD CONSTRAINT [DF_tabTest_unqValue] DEFAULT (newid()) FOR [unqValue] GO CREATE INDEX [IX_tabTest_unqValue] ON [dbo].[tabTest]([unqValue]) ON [PRIMARY] GO
--插入数据1000条
declare @i int declare @v int set @i=0 while @i<10000 begin set @v=rand()*1000 insert into tabTest ([intValue]) values (@v) set @i=@i+1 end
建立完成后:
查询
从图中可以看出,在第一个查询中,SQL Server使用了IX_tabTest_unqValue索引,根据箭头方向,计算机先在索引范围内找,找到后,使用Bookmark Lookup将索引节点映射到数据节点上,最后给出SELECT结果。在第二个查询中,系统直接遍历表给出结果,不过它使用了聚簇索引,为什么呢?不要忘了,聚簇索引的页节点就是数据节点!这样使用聚簇索引会更快一些(不受数据删除、更新留下的存储空洞的影响,直接遍历数据是要跳过这些空洞的)
具体想了解前往http://kb.cnblogs.com/page/44125/
③全文索引 全文检索是对大数据文本进行索引,在建立的索引中对要查找的单词进行进行搜索,定位哪些文本数据包括要搜索的单词
原理:先定义一个词库,然后在文章中查找每个词条(term)出现的频率和位置,把这样的频率和位置信息按照词库的顺序归纳,这样就相当于对文件建立了一个以词库为目录的索引,这样查找某个词的时候就能很快的定位到该词出现的位置。
--1 必须先启动全文本支持
EXEC sp_fulltext_database 'enable' --或者:disable
--2 创建全文本目录
CREATE FULLTEXT CATALOG catalog_tabTest
--3 创建全文本索引
CREATE FULLTEXT INDEX ON tablename
(索引列1,索引列2...)
KEY INDEX indexname
ON 索引目录名
indexname是指已存在的基于指定表的唯一索引名.而不是唯一索引列名.如果索引不存在,需要先创建唯一索引.
必须先设为主键primary key后再添加索引 要包括非聚集索引关键字(nonclustered)或聚集索引(clustered)这样: PK_t_employee nonclustered, unique, primary key located on PRIMARY id
不同点:
FREETEXT 进行简单的搜索,按意思进行匹配(不同精确文本匹配) 用来搜索包含可能与指定短语意思相同或类似的词或短语的行
CONTAINS 进行词和短语的搜索,包括近似词,派生词及相似词 用来搜索包含词、短语、部分短语、具有相同词干的词、近似搜索、同义词(用字典搜索)等……
相同点:
都用于 SELECT 和 WHERE 子句
管理目录和索引
更新:ALTER FULLTEXT
eg: ALTER FULLTEXT CATALOG catalog_test REBUILD
删除:DROP FULLTEXT
查看现有的目录和索引的更多细节
SELECT * FROM sys.fulltext_catalogs
用contains进行搜索:
--排序搜索结果
FULLTEXT搜索用:FULLTEXTTABLE() 函数排序
CONTAINS搜索用:CONTAINSTABLE() 函数排序
SELECT china.rank,* FROM tb,FREETEXTTABLE(tb,detail,'china' ) AS china WHERE tb.id=china.[key] ORDER BY id DESC SELECT china.rank,* FROM tb,CONTAINSTABLE(tb,detail,'china' ) AS china WHERE tb.id=china.[key] ORDER BY id DESC
案例使用FREETEXT(CONTAINSTEXT)类型搜索,使用了FREETEXTTABLE(CONTAINSTABLE)而不是使用WHERE子句进行过滤,并提供了一个搜索模式,指示全文引擎匹配包含china词的行
返回别名为china的一个表(能在列选择和联结中引用它)这个表包含名为key的一个列,它匹配被索引的表的主键,和一个名为rank的列,它是被赋予的等级值。案例中的等级值相等,说明他们的匹配等级是相等的
聚集索引、非聚集索引、全文索引区别:
1、非聚焦索引/聚焦索引是对字段值的排序
2、全文索引是对字段的具体内容进行分析,提到内容中的各种特征数据生成索引信息
比如查询一个值 a, 对于索引,是看某条记录的该字段值是否为 a, 对于全文索引,是查字段的内容中有没有这个信息
聚焦与非聚焦的区别,在于索引的存储与表数据之间的关系, 聚焦是和表的数据放在一齐的,决定表数据的顺序顺序,非聚焦是独立的(可以理解为原表的一个拆出来的子表)
参考文选:
全文索引:http://blog.csdn.net/raul17282/article/details/3774525
作者:PEPE
出处:http://pepe.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。