数据库学习笔记

sql server DBMS 学习SQL必知必会 第4版做的笔记

空置检查 Is NULL

没有重复的  distinct

前五条   top  5

值范围在两者之间    between

以什么方式排序 order by     默认升序     desc为降序

求值顺序:处理OR前优先处理AND,需要用括号明确分组以免得到不符合预期的结果,括号消除歧义

 

IN操作符用来指定条件范围,范围中的每个条件都可以进行匹配。IN取一组由逗号分隔、括在圆括号中的合法值。下面的例子说明了这个操作
符:(这样写IN比OR执行得快)

SELECT prod_name, prod_price
FROM Products
WHERE vend_id IN ( 'DLL01', 'BRS01' )
ORDER BY prod_name;

 

NOT
WHERE子句中用来否定其后条件的关键字。

 

通配符搜索,只能用于文本段,在搜索串中,

%表示任何字符出现任意次数,可以在搜索模式任意位置使用,可使用多个通配符,只写一个%不会匹配NULL

_下划线通配符,只匹配单个字符,_总是刚好匹配一个字符,不能多也不能少。

[]通配符用来指定一个字符集,它必须匹配指定位置(通配符的位置)的一个字符。

select cust_contact
from Customers
where cust_contact like '[JM]%'  --代表找出cust_contact以J或M开头    [^JM]则表示不以J和M为开头的字符串
order by cust_contact;

通配符耗费时间更长

不要过度使用通配符。如果其他操作符能达到相同的目的,应该使用其他操作符。
在确实需要使用通配符时,也尽量不要把它们用在搜索模式的开始处。把通配符置于开始处,搜索起来是最慢的。
仔细注意通配符的位置。如果放错地方,可能不会返回想要的数据。

 

计算字段

在SQL语句内可完成的许多转换和格式化工作都可以直接在客户端应用程序内完成。但一般来说,在数据库服务器上完成这些操作比在客户
端中完成要快得多。

拼接字段可用+或者||来拼接(SQL SERVER用+),可将两列拼接成一列显示

SQL RTRIM(str)可去掉str右边空格字符 LTRIM去掉左边空格字符  TRIM去掉左右两边的空格字符  

使用AS可以给列赋予别名,给拼接后的列一个别名可以像正常列那样使用拼接后的列,可以用加减乘除等计算字段

 

SQL函数

SQLSERVER使用SUBSTRING提取字符串部分  数据类型转换CONVERT()  提取当前日期 GETDATE

UPPER返回大写形式字符串 LOWER小写 LEFT(str,num)返回左边num位的字符  LENGTH()返回字符串长度  RIGHT(str,num)返回右边num为字符

soundex寻找发音相似的字符串

DATEPART()函数
有两个参数,它们分别是返回的成分和从中返回成分的日期。yy年 mm月 dd日

数值处理函数:

abs()返回绝对值   cos()返回余弦  exp()返回指数值   PI()圆周率  SIN()正弦值   sqrt()平方根  tan()一个角度的正切

 

聚集函数

需要汇总表中的数据,而不需要实际数据本身。因此,返回实际表数据纯属浪费时间和处理资源(更不用说带宽了)。再说一遍,
我们实际想要的是汇总信息。

五个聚集函数

AVG()返回平均值,参数值为列名,忽略值为NULL的值

COUNT()返回某列的行数 

使用COUNT(*)对表中行的数目进行计数,不管表列中包含的是空值(NULL)还是非空值。
使用COUNT(column)对特定列中具有值的行进行计数,忽略NULL值。

MAX()返回某列的最大值,参数为列名,如果用于文本列则返回排序后的最后一列

MIN()返回某列的最小值,参数为列名,与MAX()相反

SUM()用来返回指定列值的和(总计),参数为列名

以上均可使用distinct,只包含不同的值,distinct不可用于COUNT(*)

可以组合使用聚集函数

警告:取别名
在指定别名以包含某个聚集函数的结果时,不应该使用表中实际的列名。虽然这样做也算合法,但许多SQL实现不支持,可能会产生模糊的
错误消息。

 

分组数据

使用分组可以将数据分为多个逻辑组,对每个组进行聚集计算。

group by 

GROUP BY子句可以包含任意数目的列,因而可以对分组进行嵌套,更细致地进行数据分组。
如果在GROUP BY子句中嵌套了分组,数据将在最后指定的分组上进行汇总。换句话说,在建立分组时,指定的所有列都一起计算(所以
不能从个别的列取回数据)。
GROUP BY子句中列出的每一列都必须是检索列或有效的表达式(但不能是聚集函数)。如果在SELECT中使用表达式,则必须在GROUP
BY子句中指定相同的表达式。不能使用别名。

如果分组列中包含具有NULL值的行,则NULL将作为一个分组返回。如果列中有多行NULL值,它们将分为一组。
GROUP BY子句必须出现在WHERE子句之后,ORDER BY子句之前。

过滤分组

where过滤行,having过滤分组

过滤是基于分组聚集值,而不是特定行的值。

WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤。

HAVING与WHERE非常类似,如果不指定GROUP BY,则大多数DBMS会同等对待它们。不过,你自己要能区分这一点。使用HAVING时应
该结合GROUP BY子句,而WHERE子句用于标准的行级过滤。

一般在使用GROUP BY子句时,应该也给出ORDER BY子句。这是保证数据正确排序的唯一方法。千万不要仅依赖GROUP BY排序数据。

SELECT子句及其顺序

 

使用子查询

在SELECT语句中,子查询总是从内向外处理。在处理上面的SELECT语句时,DBMS实际上执行了两个操作。

SELECT cust_id
FROM Orders
WHERE order_num IN (SELECT order_num
FROM OrderItems
WHERE prod_id = 'RGAN01');内部先返回一些值成为in操作符所需参数形式然后进行外部查询

包含子查询的SELECT语句难以阅读和调试,它们在较为复杂时更是如此。如上所示,把子查询分解为多行并进行适当的缩进,能极大地简
化子查询的使用。

在WHERE子句中使用子查询能够编写出功能很强且很灵活的SQL语句。对于能嵌套的子查询的数目没有限制,不过在实际使用时由于性
能的限制,不能嵌套太多的子查询。使用子查询并不总是执行这类数据检索的最有效方法

子查询中的WHERE子句与前面使用的WHERE子句稍有不同,因为它使用了完全限定列名,而不只是列名。它指定表名和列名

虽然子查询在构造这种SELECT语句时极有用,但必须注意限制有歧义的列。即内部查询与外部查询可能有相同列,所以要指定列名

没有具体指定就会返回错误结果,因为DBMS会误解你的意思。有时候,由于出现冲突列名而导
致的歧义性,会引起DBMS抛出错误信息。例如,WHERE或ORDER BY子句指定的某个列名可能会出现在多个表中。好的做法是,如果
在SELECT语句中操作多个表,就应使用完全限定列名来避免歧义。

 

联结

联结是利用SQL的SELECT能执行的最重要的操作,很好地理解联结及其语
法是学习SQL的极为重要的部分。

简单说,联结是一种机制,用来在一条SELECT语句中关联表,因此称为联结。使用特殊的语法,可以联结多个表返回一组输
出,联结在运行时关联表中正确的行。

用where创建联结 

SELECT vend_name, prod_name, prod_price
FROM Vendors, Products
WHERE Vendors.vend_id = Products.vend_id;

要保证所有联结都有WHERE子句,否则DBMS将返回比想要的数据多得多的数据。同理,要保证WHERE子句的正确性。不正确的过滤条件
会导致DBMS返回不正确的数据。

上述语句等价于 内联结

SELECT vend_name, prod_name, prod_price
FROM Vendors INNER JOIN Products
ON Vendors.vend_id = Products.vend_id;

这里,两个表之间的关系是以INNER JOIN指定的部分FROM子句。在使用
这种语法时,联结条件用特定的ON子句而不是WHERE子句给出。

SQL不限制一条SELECT语句中可以联结的表的数目。创建联结的基本规则也相同。首先列出所有表,然后定义表之间的关系

DBMS在运行时关联指定的每个表,以处理联结。这种处理可能非常耗费资源,因此应该注意,不要联结不必要的表。联结的表越多,性能
下降越厉害。

内连接表顺序无要求

 

高级联结

使用表别名,as也可以给表取别名,表别名只在查询执行中使用。与列别名不一样,表别名不返回到客户端。

Oracle没有 as,直接取别名

用自联结而不用子查询,自联结要使用as避免对同一张表查询引起歧义

 

无论何时对表进行联结,应该至少有一列不止出现在一个表中(被联结的列)。标准的联结(前一课中介绍的内联结)返回所有数据,相同的
列甚至多次出现。自然联结排除多次出现,使每一列只返回一次。

 

外联结

许多联结将一个表中的行与另一个表中的行相关联,但有时候需要包含没有关联行的那些行。即将没有关联的行也显示出来

Select Customers.cust_id,Orders.order_num
from Customers Left outer join Orders
on Customers.cust_id=Orders.cust_id

外联结还包括没有关联行的行。RIGHT指出的是OUTER JOIN右边的表,而LEFT指出的是OUTER JOIN左边的表

要记住,总是有两种基本的外联结形式:左外联结和右外联结。它们之间的唯一差别是所关联的表的顺序。换句话说,调
整FROM或WHERE子句中表的顺序,左外联结可以转换为右外联结。因此,这两种外联结可以互换使用,哪个方便就用哪个。

要记住,总是有两种基本的外联结形式:左外联结和右外联结。它们之间的唯一差别是所关联的表的顺序。换句话说,调
整FROM或WHERE子句中表的顺序,左外联结可以转换为右外联结。因此,这两种外联结可以互换使用,哪个方便就用哪个。
还存在另一种外联结,就是全外联结(full outer join),它检索两个表中的所有行并关联那些可以关联的行。与左外联结或右外联结包含一个表
的不关联的行不同,全外联结包含两个表的不关联的行。

聚集函数也可以方便地与其他联结一起使用。

总结:

注意所使用的联结类型。一般我们使用内联结,但使用外联结也有效。
关于确切的联结语法,应该查看具体的文档,看相应的DBMS支持何种语法(大多数DBMS使用这两课中描述的某种语法)。
保证使用正确的联结条件(不管采用哪种语法),否则会返回不正确的数据。
应该总是提供联结条件,否则会得出笛卡儿积。
在一个联结中可以包含多个表,甚至可以对每个联结采用不同的联结类型。虽然这样做是合法的,一般也很有用,但应该在一起测试它们
前分别测试每个联结。这会使故障排除更为简单。

多数SQL查询只包含从一个或多个表中返回数据的单条SELECT语句。但是,SQL也允许执行多个查询(多条SELECT语句),并将结果作为一
个查询结果集返回。这些组合查询通常称为并或复合查询。

多数情况下,组合相同表的两个查询所完成的工作与具有多个WHERE子句条件的一个查询所完成的工作相同。换句话说,任何具有多
个WHERE子句的SELECT语句都可以作为一个组合查询

 

UNION指示DBMS执行两条SELECT语句,并把输出组合成一个查询结果集

从多个表(而不是一个表)中检索数据的
情形,使用UNION可能会使处理更简单。

UNION中的每个查询必须包含相同的列、表达式或聚集函数

UNION从查询结果集中自动去除了重复的行;换句话说,它的行为与一条SELECT语句中使用多个WHERE子句条件一样。因为Indiana州有一个
Fun4All单位,所以两条SELECT语句都返回该行。使用UNION时,重复的行会被自动取消。

使用UNION ALL,DBMS不取消重复的行。因此,这里返回5行,其中有一行出现两次。

在用UNION组合查询时,只能使用一条ORDER BY子句,它必须位于最后一条SELECT语句之后。对
于结果集,不存在用一种方式排序一部分,而又用另一种方式排序另一部分的情况,因此不允许使用多条ORDER BY子句。

实际上,UNION在需要组合多个表的数据时也很有用,即使是有
不匹配列名的表,在这种情况下,可以将UNION与别名组合,检索一个结果集。

 

数据插入:

insert into 接表名 (列名,列名2..) values(值1,值2..)

INSERT INTO Customers(cust_id,
cust_name,
cust_address,
cust_city,
cust_state,
cust_zip,
cust_country,
cust_contact,
cust_email)
VALUES('1000000006',
'Toy Land',
'123 Any Street',
'New York',
'NY',
'11111',
'USA',
NULL,
NULL);

因为提供了列名,VALUES必须以其指定的次序匹配指定的列名,不一定按各列出现在表中的实际次序。其优点是,即使表的结构改变,这
条INSERT语句仍然能正确工作。

不要使用没有明确给出列的INSERT语句。给出列能使SQL代码继续发挥作用,即使表结构发生了变化。

 

INSERT可将select选出的数据插入另一个表中

SELECT

INSERT通常只插入一行。要插入多行,必须执行多个INSERT语句。INSERT SELECT是个例外,它可以用一条INSERT插入多行,不
管SELECT语句返回多少行,都将被INSERT插入。

 

有一种数据插入不使用INSERT语句。要将一个表的内容复制到一个全新的表(运行中创建的表),可以使用SELECT INTO语句。

SELECT *
INTO CustCopy
FROM Customers;

这条SELECT语句创建一个名为CustCopy的新表,并把Customers表的整个内容复制到新表中。因为这里使用的是SELECT *,所以将
在CustCopy表中创建(并填充)与Customers表的每一列相同的列。要想只复制部分的列,可以明确给出列名,而不是使用*通配符。

任何SELECT选项和子句都可以使用,包括WHERE和GROUP BY;
可利用联结从多个表插入数据;
不管从多少个表中检索数据,数据都只能插入到一个表中。

SELECT INTO是试验新SQL语句前进行表复制的很好工具。先进行复制,可在复制的数据上测试SQL代码,而不会影响实际的数据。

update 要更新的表set列名和它们的新值where确定要更新哪些行的过滤条件。

要删除某个列的值,可设置它为NULL(假如表定义允许NULL值)

DELETE FROM Customers
WHERE cust_id = '1000000006';删除某行

 

外键

简单联结两个表只需要这两个表中的常用字段。也可以让DBMS通过使用外键来严格实施关系(这些定义在附录A
中)。存在外键时,DBMS使用它们实施引用完整性。例如要向Products表中插入一个新产品,DBMS不允许通过未知的供应商id插入它,
因为vend_id列是作为外键连接到Vendors表的。那么,这与DELETE有什么关系呢?使用外键确保引用完整性的一个好处是,DBMS通常可
以防止删除某个关系需要用到的行。例如,要从Products表中删除一个产品,而这个产品用在OrderItems的已有订单中,那么DELETE语句
将抛出错误并中止。这是总要定义外键的另一个理由。

 

外键是保证数据库一致性的重要手段

 

如果想从表中删除所有行,不要使用DELETE。可使用TRUNCATE TABLE语句,它完成相同的工作,而速度更快(因为不记录数据的变
动)。

UPDATE和DELETE语句都有WHERE子句,这样做的理由很充分。如果省略了WHERE子句,则UPDATE或DELETE将被应用到表中
所有的行。换句话说,如果执行UPDATE而不带WHERE子句,则表中每一行都将用新值更新。类似地,如果执行DELETE语句而不带WHERE子
句,表的所有数据都将被删除。

有的DBMS允许数据库管理员施加约束,防止执行不带WHERE子句的UPDATE或DELETE语句。如果所采用的DBMS支持这个特性,应该
使用它。

 

创建表

CREATE TABLE Products
(
prod_id CHAR(10) NOT NULL,
vend_id CHAR(10) NOT NULL,
prod_name CHAR(254) NOT NULL,
prod_price DECIMAL(8,2) NOT NULL,
prod_desc VARCHAR(1000) NULL
);

只有不允许NULL值的列可作为主键,允许NULL值的列不能作为唯一标识。

默认值在CREATE TABLE语句的列定义中用关键字DEFAULT指定.

更新表定义,可以使用ALTER TABLE语句。虽然所有的DBMS都支持ALTER TABLE,但它们所允许更新的内容差别很大。以下是使用ALTER
TABLE时需要考虑的事情。

警告:小心使用ALTER TABLE
使用ALTER TABLE要极为小心,应该在进行改动前做完整的备份(模式和数据的备份)。数据库表的更改不能撤销,如果增加了不需要的
列,也许无法删除它们。类似地,如果删除了不应该删除的列,可能会丢失该列中的所有数据。

 

删除表(删除整个表而不是其内容)非常简单,使用DROP TABLE语句即可

重命名表

重命名表
每个DBMS对表重命名的支持有所不同。对于这个操作,不存在严格的标准。DB2、MariaDB、MySQL、Oracle和PostgreSQL用户使
用RENAME语句,SQL Server用户使用sp_rename存储过程,SQLite用户使用ALTER TABLE语句。

 

视图

视图是虚拟的表。与包含数据的表不一样,视图只包含使用时动态检索数据的查询。

作为视图,它不包含任何列或数据,包含的是一个查询

重用SQL语句。
简化复杂的SQL操作。在编写查询后,可以方便地重用它而不必知道其基本查询细节。
使用表的一部分而不是整个表。
保护数据。可以授予用户访问表的特定部分的权限,而不是整个表的访问权限。
更改数据格式和表示。视图可返回与底层表的表示和格式不同的数据。

 

创建视图 create view view name AS 后接select语句   

因为视图只包含一个SELECT语句,而这个语句的语法必须遵循具体DBMS的所有规则和约束,所以会有多个创建视图的语句版本。

一个最常见的视图应用是隐藏复杂的SQL

视图极大地简化了复杂SQL语句的使用。利用视图,可一次性编写基础的SQL,然后根据需要多次使用。

 

创建可重用的视图

视图为虚拟的表。它们包含的不是数据而是根据需要检索数据的查询。视图提供了一种封装SELECT语句的层次,可用来简化数据处理,重新格式化或保护基础数据。

 

存储过程

我们使用的大多数SQL语句都是针对一个或多个表的单条语句。并非所有操作都这么简单,经常会有一些复杂的操作需要多条语句
才能完成。

存储过程就是为以后使用而保存的一条或多条SQL语句。可将其视为批文件,虽然它们的作用不仅限于批处
理。

使用存储过程的理由

通过把处理封装在一个易用的单元中,可以简化复杂的操作。
由于不要求反复建立一系列处理步骤,因而保证了数据的一致性。如果所有开发人员和应用程序都使用同一存储过程,则所使用的代码都
是相同的。
这一点的延伸就是防止错误。需要执行的步骤越多,出错的可能性就越大。防止错误保证了数据的一致性。
简化对变动的管理。如果表名、列名或业务逻辑(或别的内容)有变化,那么只需要更改存储过程的代码。使用它的人员甚至不需要知道
这些变化。
这一点的延伸就是安全性。通过存储过程限制对基础数据的访问,减少了数据讹误(无意识的或别的原因所导致的数据讹误)的机会。
因为存储过程通常以编译过的形式存储,所以DBMS处理命令的工作较少,提高了性能。
存在一些只能用在单个请求中的SQL元素和特性,存储过程可以使用它们来编写功能更强更灵活的代码。

使用存储过程有三个主要的好处,即简单、安全、高性能

存储过程的执行远比编写要频繁得多

执行存储过程的SQL语句很简单,即EXECUTE

 

创建存储过程

CREATE PROCEDURE MailingListCount   --无参数
AS
DECLARE @cnt INTEGER    
SELECT @cnt = COUNT(*)
FROM Customers
WHERE NOT cust_email IS NULL;
RETURN @cnt;

调用刚才创建的存储过程

DECLARE @ReturnValue INT
EXECUTE @ReturnValue=MailingListCount;
SELECT @ReturnValue;

(SQL Server中
所有局部变量名都以@起头)

 

create procedure NewOrder @cust_id Char(10)  --传入一个参数
as
declare @order_num Integer
Select @order_num=MAX(order_num)
from Orders
Select @order_num=@order_num+1
insert into Orders(order_num,order_date,cust_id)
values(@order_num,GETDATE(),@cust_id)
return @order_num;

用select @@identity得到上一次插入记录时自动产生的ID

 

事务处理(transaction processing),通过确保成批的SQL操作要么完全执行,要么完全不执行,来维护数据库的完整性。

用来管理必须成批执行的SQL操作,保证数据库不包含不完整的操作结
果。利用事务处理,可以保证一组操作不会中途停止,它们要么完全执行,要么完全不执行(除非明确指示)。如果没有错误发生,整组语句
提交给(写到)数据库表;如果发生错误,则进行回退(撤销),将数据库恢复到某个已知且安全的状态。

事务(transaction)指一组SQL语句;

回退(rollback)指撤销指定SQL语句的过程;
提交(commit)指将未存储的SQL语句结果写入数据库表;
保留点(savepoint)指事务处理中设置的临时占位符(placeholder),可以对它发布回退(与回退整个事务处理不同)。

事务处理用来管理INSERT、UPDATE和DELETE语句。不能回退SELECT语句(回退SELECT语句也没有必要),也不能回
退CREATE或DROP操作。事务处理中可以使用这些语句,但进行回退时,这些操作也不撤销。

 

BEGIN TRANSACTION
...
COMMIT TRANSACTION  在这之间的代码要么完全执行要么完全不执行

 

ROLLBACK命令用来回退(撤销)SQL语句

要支持回退部分事务,必须在事务处理块中的合适位置放置占位符。这样,如果需要回退,可以回退到某个占位符。
在SQL中,这些占位符称为保留点。在MariaDB、MySQL和Oracle中创建占位符,可使用SAVEPOINT语句:

在SQL Server中,可检查一个名为@@ERROR的变量,看操作是否成功。(其他DBMS使用不同的函数或变量返回此
信息。)如果@@ERROR返回一个非0的值,表示有错误发生,事务处理回退到保留点

提示:保留点越多越好   SAVE可以设置保留点
可以在SQL代码中设置任意多的保留点,越多越好。为什么呢?因为保留点越多,你就越能灵活地进行回退。

 

SQL检索操作返回一组称为结果集的行,这组返回的行都是与SQL语句相匹配的行(零行或多行)。简单地使用SELECT语句,没有办法得到第
一行、下一行或前10行。但这是关系DBMS功能的组成部分。

DECLARE CustCursor CURSOR
FOR
SELECT * FROM Customers
WHERE cust_email IS NULL

CURSOR游标

OPEN CURSOR CustCursor打开游标

CLOSE CustCursor关闭游标

 

约束:

主键 PRIMARY KEY

主键是一种特殊的约束,用来保证一列(或一组列)中的值是唯一的,而且永不改动。换句话说,表中的一列(或
多个列)的值唯一标识表中的每一行。这方便了直接或交互地处理表中的行。没有主键,要安全地UPDATE或DELETE特定行而不影响其他行会
非常困难。

任意两行的主键值都不相同。
每行都具有一个主键值(即列中不允许NULL值)。
包含主键值的列从不修改或更新。(大多数DBMS不允许这么做,但如果你使用的DBMS允许这样做,好吧,千万别!)
主键值不能重用。如果从表中删除某一行,其主键值不分配给新行。

 

外键

外键是表中的一列,其值必须列在另一表的主键中。外键是保证引用完整性的极其重要部分。

CREATE TABLE Orders
(
order_num INTEGER NOT NULL PRIMARY KEY,
order_date DATETIME NOT NULL,
cust_id CHAR(10) NOT NULL REFERENCES Customers(cust_id)  --REFERENCES即定义外键
);

外键还有另一个重要作用。在定义外键后,DBMS不允许删除在另一个表中具有关联行的行。例
如,不能删除关联订单的顾客。删除该顾客的唯一方法是首先删除相关的订单(这表示还要删除相关的订单项)。由于需要一系列的删除,
因而利用外键可以防止意外删除数据。
有的DBMS支持称为级联删除(cascading delete)的特性。如果启用,该特性在从一个表中删除行时删除所有相关的数据。例如,如果启
用级联删除并且从Customers表中删除某个顾客,则任何关联的订单行也会被自动删除。

 

唯一约束

唯一约束用来保证一列(或一组列)中的数据是唯一的。它们类似于主键,但存在以下重要区别。

表可包含多个唯一约束,但每个表只允许一个主键。
唯一约束列可包含NULL值。
唯一约束列可修改或更新。
唯一约束列的值可重复使用。
与主键不一样,唯一约束不能用来定义外键。

 

检查约束

检查约束用来保证一列(或一组列)中的数据满足一组指定的条件。

检查最小或最大值。例如,防止0个物品的订单(即使0是合法的数)。
指定范围。例如,保证发货日期大于等于今天的日期,但不超过今天起一年后的日期。
只允许特定的值。例如,在性别字段中只允许M或F。

CREATE TABLE OrderItems
(
order_num INTEGER NOT NULL,
order_item INTEGER NOT NULL,
prod_id CHAR(10) NOT NULL,
quantity INTEGER NOT NULL CHECK (quantity > 0),  利用这个约束,任何插入(或更新)的行都会被检查,保证quantity大于0。
item_price MONEY NOT NULL
);

 

索引

索引用来排序数据以加快搜索和排序操作的速度。想像一本书后的索引(如本书后的索引),可以帮助你理解数据库的索引。

主键数据总是排序的,这是DBMS的工作。因此,按主键检索特定行总是一种快速有效的操作。

但是,搜索其他列中的值通常效率不高。例如,如果想搜索住在某个州的客户,怎么办?因为表数据并未按州排序,DBMS必须读出表中所有
行(从第一行开始),看其是否匹配。这就像要从没有索引的书中找出词汇一样。
解决方法是使用索引。可以在一个或多个列上定义索引,使DBMS保存其内容的一个排过序的列表。在定义了索引后,DBMS以使用书的索引
类似的方法使用它。DBMS搜索排过序的索引,找出匹配的位置,然后检索这些行。

索引改善检索操作的性能,但降低了数据插入、修改和删除的性能。在执行这些操作时,DBMS必须动态地更新索引。

索引数据可能要占用大量的存储空间。
并非所有数据都适合做索引。取值不多的数据(如州)不如具有更多可能值的数据(如姓或名),能通过索引得到那么多的好处。
索引用于数据过滤和数据排序。如果你经常以某种特定的顺序排序数据,则该数据可能适合做索引。
可以在索引中定义多个列(例如,州加上城市)。这样的索引仅在以州加城市的顺序排序时有用。如果想按城市排序,则这种索引没有用
处。

大多数DBMS提供了可用来确定索引效率的实用程序,应该经常使用这些实用程序。

CREATE INDEX用于创建索引

CREATE INDEX prod_name_ind
ON PRODUCTS (prod_name);

索引必须唯一命名。这里的索引名prod_name_ind在关键字CREATE INDEX之后定义。ON用来指定被索引的表,而索引中包含的列(此例中仅
有一列)在表名后的圆括号中给出。

索引的效率随表数据的增加或改变而变化。许多数据库管理员发现,过去创建的某个理想的索引经过几个月的数据处理后可能变得不再理想
了。最好定期检查索引,并根据需要对索引进行调整。

使用索引:

SELECT 字段名表

FROM 表名表

WITH (INDEX(索引名))

WHERE 查询条件

 

触发器

触发器是特殊的存储过程,它在特定的数据库活动发生时自动执行。触发器可以与特定表上的INSERT、UPDATE和DELETE操作(或组合)相
关联。

与存储过程不一样(存储过程只是简单的存储SQL语句),触发器与单个的表相关联。与Orders表上的INSERT操作相关联的触发器只
在Orders表中插入行时执行。类似地,Customers表上的INSERT和UPDATE操作的触发器只在表上出现这些操作时执行。

触发器内的代码具有以下数据的访问权:
INSERT操作中的所有新数据;
UPDATE操作中的所有新数据和旧数据;
DELETE操作中删除的数据。
根据所使用的DBMS的不同,触发器可在特定操作执行之前或之后执行。

 

下面是触发器的一些常见用途。
保证数据一致。例如,在INSERT或UPDATE操作中将所有州名转换为大写。
基于某个表的变动在其他表上执行活动。例如,每当更新或删除一行时将审计跟踪记录写入某个日志表。
进行额外的验证并根据需要回退数据。例如,保证某个顾客的可用资金不超限定,如果已经超出,则阻塞插入。
计算计算列的值或更新时间戳。

create trigger tr_COMMISSIONINFO_INSERT on COMMISSION_INFO_    
for insert
as
begin
declare @COMMISSIONID varchar(20),@DATE datetime
set @COMMISSIONID=(select ID_ from INSERTED)
set @DATE=getdate()
insert into COOPERATE_YEARS_(COMMISSION_ID_, CONTRACT_START_DATE_, RE_CONTRACT_START_DATE_) VALUES(@COMMISSIONID, @DATE, @DATE)
end

约束是实施引用完整性的重要部分,索引可改善数据检索的性能,触发器可以用来执行运行前后的处
理,安全选项可用来管理数据访问。

 

关系数据库中,关系是一张表,表中的每行(即数据库中的每条记录)就是一个元组,每列就是一个属性,列中所对应的值为域(也称为字段)

一个事务只能使用一个回滚段来存放它的回滚信息,而一个回滚段可以存放多个事务的回滚信息。 
短事务应该不是一个事务占用一个段,应该是多个事务在一个段。
给长事务分配大回滚段
字典管理表运行的效率很低,会产生磁盘碎片。


事务
  • 原子性(ATOMIC) 整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节
  • 一致性(Consistency)在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏
  • 隔离性(Isolation)两个事务的执行是互不干扰的,一个事务不可能看到其他事务运行时中间某一时刻的数据
  • 持久性(Durability)在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
DDL—数据定义语言(CREATE,ALTER,DROP,DECLARE)
 
DML—数据操纵语言(SELECT,DELETE,UPDATE,INSERT)
 
DCL—数据控制语言(GRANT,REVOKE,COMMIT,ROLLBACK)

转载于:https://www.cnblogs.com/linfangpeng/p/6130586.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值