*SQL必知必会笔记*
*第一课 了解SQL*
\1. 数据库概念database
保存有组织的数据的容器(通常是一个文件和一组文件)
\2. 数据库软件应被称为数据库管理系统(DBMS),数据库是通过DBMS创建和操纵的容器
\3. 表(table):某种特定类型数据结构化清单。
\4. 模式(schema)关于数据库和表的布局及特性的信息
\5. 列(column)表中的一个字段,所有表都是由一个或多个列组成
\6. 数据类型(datatype)所允许的数据的类型,每个表列都有相应的数据类型,它限制(或允许)该列中存储的数据。
\7. 数据类型及名称是SQL不兼容的一个主要原因
\8. 行(row)表中的一个记录,有时称为数据库记录(record),多半可交替,但行为术语
\9. 主键(primary key)一列(或一组列),其值能够唯一标识表中每一行。
\10. 表中任意列都可以作为主键,但需满足四个条件
-
任意两行都不具有相同的主键值
-
每一行都必须具有一个主键值(主键列不允许NULL值)
-
主键列中的值不允许修改或更新
-
主键值不能重用(如果某行从表中删除,它的主键不能赋给以后的新行)
1.什么是SQL?
答:Structured Query language 结构化查询语言,专门用来与数据库沟通的语言
\2. SQL的优点有什么?
答:SQL不是特定数据库供应商专有语言,几乎所有DBMS都支持SQL
SQL简单易学,单词少
SQL可进行复杂和高级的数据库操作
第二课 *检索数据*
\1. 关键字(keyword)作为SQL组成的保留字,不能作为表和列的名字
\2. 检索单个列:
Select 列名 from 表名;
\3. 结束SQL语句用“;”
\4. SQL语句中空格被省略,且不区分大小写,一般关键字大写,表名,列名小写方便阅读
\5. 检索多个列:
Select 列名,列名,列名 from 表名;
\6. 检索所有列:使用通配符*
Select * from 表名; (可检索到未知列,但少用,数据多时,效率低,影响性能)
\7. distinct去重,只返回不同的值,重复的pass (注意:不能部分使用distinct)
例:select distinct 列名 from 表名
\8. 如果只返回一定数量的行数不同DBMS语句略有不同
SQL Server和Access select top 5 列名 from 表名
DB2 select 列名 from 表名 FETCH first 5 rows only
Oracle select 列名 from 表名 rownum <=5 行计数器
MYSQL,MariaDB,PostgreSQL,SQLite select 列名 from 表名 limit 4; 如果从第五行起的第五行数据 select 列名 from 表名 limit 4 offset 5
\9. 注释 作用:描述性注释;说明;暂时停止要执行的sql代码
第一种行内注释: select name --这是一条注释
from product
第二种行内注释: #这是一条注释 一整行都为注释
Select name from products;
第三种多行注释:/*这是一条
注释*/
Select name from products; 多用于代码注释
第三课 *排序检索数据*
\1. 子句(clause)SQL语句由子句组成,有些是必须的,有些是可选的。
\2. 排序检索数据例子
Select 列名 from 表名 order by 列名
*order by 子句必须是句尾,否则出现错误信息
*order by 子句可以通过非选择列进行排序
\3. 按照多个列名排序例子
Select 列名1,列名2,列名3
From 表名
Order by 列名2,列名3
\4. 按照列位置排序
Select 列名1,列名2,列名3
From 表名
Order by 2,3; 先按列2排序,再按列3排序(默认进行排序的列在select清单中)
\5. 指定排序方向(desc降序,默认为:asc升序)
Select 列名1,列名2,列名3
From 表名
Order by 列名1 DESC;
*DESC只应用到直接位于前面的列名,如果多列进行降序排序,必须每列指定DESC关键字
第四课 *过滤数据*
\1. 使用where子句过滤数据
Select 列名 from 表名 where 条件=XX
\2. 如果有排序order by ,where在前,且在from之后
\3. Where 子句操作符包含
= 等于 !=和<> 不等于
<小于 >大于
!<不小于 !>不大于
<= 小于等于 >=大于等于
BETWEEN 在指定两个值之间
IS NULL 为NULL值
\4. 不匹配检查
Select 列名,列名 from 表名 where 列名<>’列名’
5.范围检查
Select 列名,列名 from 表名 where between 低端值 and 高端值;
第五课 *高级数据过滤*
1,操作符(operator)用于联结或改变where子句中的子句关键词,也称逻辑操作符例如and和or,in
2,And操作符
Select 列名,列名 from 表名 where 条件1 and 条件2;
用and操作符连接需要同时满足所有给定条件
3,Or操作符
Select 列名,列名 from 表名 where 条件1 or 条件2;
用or操作符连接需要满足其中一个给定条件
4, and操作符的优先级高于or操作符,一般同时存在时利用更高级的()来消除歧义
Select 列名,列名
From 表名
Where (条件1 or 条件2)
And 条件3;
5, in操作符
用于指定条件范围,范围中的每个条件都可以进行匹配,in取一组有逗号分隔,括号中的合法值。
Select 列名,列名
From 表名
Where 列名 in(列名1,列名2)
Order by 列名;
6, In操作符更直观,in比and和or执行更快,且可以包含其他select语句
7, Not操作符
Not 用于where子句中用来否定其后条件的关键词
Select 列名,列名
From表名
Where not 条件1 也可以where 列名<>值
第六课 *使用通配符进行过滤*
\1. like操作符
\2. 通配符(wildcard):用来匹配值的一部分的特殊字符
\3. 搜索模式(search pattern)由字面值和通配符组成构成的搜索条件
\4. 谓词(predicate)操作符何时不是操作符?作为谓词时候。
\5. 百分号%通配符
表示任何字符出现任意次数
以x开头 x%
以x结尾 %x
以x开头y结尾 x%y
包含x %x%
第二个字符是x _x%
第二个是x倒数第三个是y x%y
百分号通配符不能匹配产品名称为NULL的行
\6. 下划线(_)通配符
_总是刚好匹配一个字符,%能匹配多个字符
\7. 方括号([])通配符
用来匹配一个字符集,它必须匹配指定位置(通配符的位置)的一个字符
只有Access和SQL Server支持集合
例如:找出名字以J或M起头的联系人,可进行以下查询
Select people from customers
Where people like ‘[JM]%’
Order by people;
前缀字符^(脱字号)来否定,例如:查询匹配以J和M之外任意字符起头的任意联系人名
Select people from customers
Where people like ‘[^JM]%’
Order by people;
*如果用Access中用[!JM]而不是[^JM]
\8. 通配符缺点
耗时,效率低,尽量不要处于开始处,如果位置不同,结果可能不同。
第七课 *创建计算字段*
\1. 字段(field)基本上与列(column)的意思相同,经常互换使用,不过数据库列一般称为列,而术语字段通常与计算字段一起使用。
\2. 拼接(concatenate):将值连接到一起构成单个值
Access和SQL Server用+号拼接
DB2,Oracle,PostgreSQL,SQLite和Open Office Base使用||拼接
\3. 去空格
RTRIM()去掉字符右边的所有空格
LTRIM() 去掉字符左边的所有空格
TRIM() 去掉字符左右两边的空格
\4. 取别名(又称’导出列‘)
当拼接出新的字段,可以起别名(alias)作为字段或值的替换名,用AS关键字赋予
例如:select RTRIM(列名)+’ (’+RTRIM(列名)+’)’ AS 新列名
From 表名
Order by 列名
*别名可以为单词也可以为字符串,但一般为单词,免得歧义。
第八课 *使用函数处理数据*
\1. 不同DBMS函数的差异
提取字符串的组成 | Access使用MID()DB2,Oracle,PostgreSQL和SQLite使用SUBSTR()MYSQL,SQL Server使用SUBSTRING() |
---|---|
数据类型转换 | Access和Oracle使用多个函数,每种类型的转换有个函数DB2,PostgreSQL使用CAST()MariaDB,MySQL,SQL Server使用Convert() |
取当前日期 | Access使用NOW()DB2,PostgreSQL使用CURRENT_DATEMariaDB,MySQL使用CURDATE()Oracle使用SYSDATESQL Server使用GETDATE()SQLite使用Date() |
\2. 常用文本处理函数
函数 | 说明 |
---|---|
LEFT() | 返回字符串左边的字符 |
LENGTH() | 返回字符串长度 |
LOWER() | 将字符串转换为小写 |
UPPER() | 将字符串转换为大写 |
LTRIM() | 去掉字符串左边空格 |
RTRIM() | 去掉字符串右边空格 |
SOUNDEX() | 返回字符串的SOUNDEX的值 |
*SOUNDEX是将任何文本串转换为描述语音表示的字母数字模式的算法,考虑了发音字符和音节,使能对字节进行发音比较而不是字母。
例如:
Select 列名1,列名2
From 表名
Where SOUNDEX(列名)=SOUNDEX(‘马歇尔’);
可能搜索到类似马歇尔读音的马谢贰
\2. 在oracle中用两种方式查询2020年的全部订单
Select order_num
From orders
Where to_number (to_char(order_date,’YYYY’))=2020
其中to_char()函数用于提取日期的成分,
to_number()用于提取处的成分转换为数值以便与2020比较
另一种方式利用Between关键字
Selcet order_num
From orders
Where order_date Between to_date(‘01-01-2020’)
And to_date(‘12-31-2020’);
其中to_date()函数用于将两个字符转换为日期
查询期间的订单。
MySQL和MariaDB用YEAR()提取年份
SQL Server用CONVERT()替代to_date()
SQLite用where strftime(‘%Y’,order_date)=’2020’
3.数值处理函数
函数 | 说明 |
---|---|
ABS() | 返回一个数的绝对值 |
COS() | 返回一个角度的余弦 |
EXP() | 返回一个数的指数值 |
PI() | 返回圆周率 |
SIN() | 返回一个角度的正弦 |
SQRT() | 返回一个数的平方根 |
TAN() | 返回一个角度的正切 |
*第九课 汇总数据*
1.聚集函数(aggregate function)对某些行运行的函数,计算并返回一个值
SQL聚集函数表
函数 | 说明 |
---|---|
AVG() | 返回某列的平均值 |
COUNT() | 返回某列的行数 |
MAX() | 返回某列的最大值 |
MIN() | 返回某列的最小值 |
SUM() | 返回某列值之和 |
\3. AVG()函数
通过表中行数计算其列值之和,求得该列的平均值
例如:select avg(price) as avg_price
From products
AVG()函数忽略值为NULL的行。
\4. COUNT()函数
可以利用COUNT()确定表中行的数目或符合特定条件的行的数目
如果指定列名COUNT()函数会忽略列值为null的行,但如果COUNT()则不忽略
\5. MAX()函数
返回指定列中的最大值,要求指定列名
例如:select MAX(price) AS max_price
From products;
*MAX()函数通常找出最大数值或日期值,如果用于文本数据,则返回按该列排序后的最后一行。
*MAX(),MIN(),SUM()忽略列值为NULL的行
\6. MIN()函数
返回指定列中的最小值,同样需要指定列名
*对于非数据使用MIN()返回该列排序后最前面的行
\7. SUM()函数
返回指定列值的和(统计)
例如:select SUM(quantity) AS all_ordered
From orderItems
Where order_num=2000;
统计2000号订单中物品数量之和
\8. ALL为默认不需指定,distinct只包含不同的值。
\9. 组合聚集函数
例如:select count(*) AS num_items,
MIN(prod_price)AS price_min,
MAX(prod_price)AS price_max,
AVG(prod_price) AS price_avg,
From Products;
*第十课 分组数据*
1.数据分组,将数据分为多个逻辑组,方便对每组进行聚集计算。
2.创建分组例子
Select 列名,count(*) as 别名
From 表名
Group By 列名1
*可通过相对位置指定列,例如group by 2,3 表示按选择的第二列分组,然后再按第三个列分组。但是并非所有SQL都支持,容易在编辑语句时出错
\3. 过滤分组(having)
Having子句过滤分组,Where语句过滤行。
例如:select cust_id,count(*) AS orders
From Orders
Group By cust_id
Having Count(*) >=2;
Having与Where的区别
Where是在数据分组之前过滤,Having是数据分组后进行过滤。使用having需要结合group by
第十一课 *使用子查询*
第十二课 *联结(join)表*
\1. 可伸缩(scale):能够适应不断增加的工作量而不失败,设计良好的数据库或应用程序称为可伸缩性好(scale well)
\2. 联结是一种机制,用来在一条SELECT语句中关联表,因此称为联结
\3. 创建联结表
例:SELECT vend_name,prod_name,prod_price
From Vendors,Products
WHERE Vendors,vend_id=Products.vend_id;
\4. 笛卡尔积(cartesian product)由没有联结条件的表关系返回的结果为笛卡儿积。检索出的行的数目将是第一个表中的行数乘以第二个表中的行数。
\5. 叉联结(cross join)有时,返回笛卡儿积的联结,也称叉联结。
\6. 等值联结(equijoin):基于两个表之间的相等测试。也称为“内联结(inner join)”
\7. 联结表很消耗资源,降低效率,尽量减少不必要的联结。
第十三课 *创建高级联结*
\1. 使用表别名,SQL除了可以对列名和计算字段使用别名,还允许给表起别名,这样1可以缩短SQL语句,2允许再一条SELECT语句中多次使用相同的表
例如:SELECT cust_name,cust_contact
FROM Customers AS C,Order AS O,OrderItems AS OI
WHERE C.cust_id=O.cust_id,
AND OI.Order_num=O.order_num
AND prod_id=’RGAN01’;
*Oracle中不支持AS ,要在Oracle中使用别名,简单地指定列名即可(因此应该是
Customers C而不是Customers AS C)
\2. 联结方式除了 内联结或等值联结还有 自联结(self-join)自然联结(natural join)和外联结(outer join)
\3. 自联结,效率一般优于子查询
\4. 自然联结,迄今为止建立的每个内联结都是自然联结,很可能永远用不到不是自然联结的内联结。
\5. 外联结:联结包含了那些在相关表中没有关联行的行。这种联结称为外联结。
外联结outer join必须使用left或right还有全外联结full。全外联结包含两个表的不关联的行。
第十四课 *组合查询(使用UNION操作符将多条select语句组合成一个结果集)*
\1. 并(union),复合查询(compound query):执行多个查询(多条SELECT语句),并将结果作为一个查询结果集返回。
\2. 有两种情况需要组合查询:
*在一个查询中从不同的表中返回结构数据
*对一个表执行多个查询,按一个查询返回数据
\3. UNION操作符使用规则
*UNION必须由两条或两条以上的select语句组成,语句之间用union分隔。
*UNION每个查询必须包含相同的列,表达式或聚集函数(每个列不需以相同的次序列出)
*列数据类型必须兼容:类型不必完全相同,但必须是DBMS可以隐含转换的类型
*UNION自动取消重复的行,如果不取消则使用UNION ALL
*在有UNION的组合查询只能由一个order by且在最后,排序所有结果。
第十五课 *插入数据*
\1. 关键词INSERT数据插入(或添加)
插入完整的行 INSERT INTO Customers
VALUES(1000,
‘TOM’,
‘USA’,
NULL);
这种写法虽然很简单,但是不安全
可以写成 INSERT INTO Customers(cust_num,
cust_name,
cust_place,
cust_email)
VALUES(1000,
‘TOM’,
‘USA’,
NULL); *即使表结构改变,语句能正常工作
*如果表的定义允许,可以在insert操作中省略某些列,但必须满足
该列允许null值,在表定义中给出默认值。如果不允许null值,却被忽略,则产生错误,无法进行插入。
\2. 插入检索出的数据
例: INSERT INTO Customers(cust_id,
cust_contact,
cust_email)
SELECT cust_id,
cust_contact,
cust _ email
From CustNew;
\3. 有一种数据插入不用INSERT语句,要将一个表的内容复制到一个全新的表,可以使用SELECT INTO。(DB2不支持)
Select into是将数据复制到一个新表,导出数据
Insert select 是插入数据
例如: select *
Into CustCopy
FROM Castomers;
创建CustCopy新表,将Castmers数据插入新表。
第十六课 *更新(UPDATE)和删除(DELETE)数据*
\1. 有两种使用UPDATE的方式:
更新表中的特定行
更新表中的所有行。
\2. UPDATE语句需要
要更新的表
列名和它们的新值
确定要更新哪些行的过滤条件
例:UPDATE Customers
SET cust_email=’1154901868@qq.com’
Where cust_id=’111’;
如果要删除某一列的值,可以将它设置为NULL,(假定定义允许NULL值)
\3. DELETE不能省略WHERE子句,否则删除所有行。
DELETE不需要列名和通配符,删除整行或者所有行,但不删除表,还有列,如果删除列需要update。
*如果想从表中删除所有行,TRUNCATE TABLE语句,速度更快。
第十七课 *创建和操纵表*
\1. 创建表的基础:
新表的名字,在关键字CREAT TABLE之后给出
表列的名字和定义用逗号分割
有的DBMS还要求指定表的位子
\2. 删除表
例:DROP TABLE CustCopy;
\3. 更新表ALTER TABLE
例:ALTER TABLE Vendors
ADD vend_phone CHAR(20);
\4. 重命名表
数据库名 | 重命名关键字 |
---|---|
DB2,MariaDB,MySQL,Oracle,PostgreSQL | RENAME |
SQL Server | sp_rename |
SQLite | ALTER TABLE |
第十八课 *使用视图*
\1. 视图是虚拟的表,与包含数据的表不同,视图只包含使用时动态检索数据的查询
\2. Access不支持视图
MySQL从版本5开始支持视图
SQLite只读视图不能改
\3. 为什么使用视图?
*重用SQL语句
*简化复杂SQL操作
*使用表的一部分,不是整个表
*保护数据,授予用户访问表的特定部分的权限,而不是整个表的权限
*更改数据格式和表示,视图可返回与底层表的表示和格式不同的数据
\4. 视图的规则
*与表一样,视图必须唯一命名
*可创建视图数目没限制
*创建视图,必须有足够访问权限
*视图可以嵌套,可利用从其他视图中检索数据的查询来构成视图。
*许多DBMS禁止在视图中使用Order by
*有些DBMS要求返回的所有列进行命名,计算字段起别名
*视图不能索引,和有关联的触发器或默认值
\5. 创建视图
CREATE VIEW 删除视图 DROP VIEW viewname,在覆盖和更新视图,必须先删除再创建。
例: CREATE VIEW ProductCustomers AS
SELECT cust_name,cust_contact,prod_id
From Customers,Orders,OrderItems
Where Customers.cust_id=order.cust_id
And OrderItem.order_num=Order.order_num;
这条语句创建了ProductCustomers视图,联结三个表,可在这基础上进行查询简化了sql语句。
\6. 用视图过滤不想要的数据
例: CREATE VIEW CustomerEMailList AS
Select cust_id,cust_name,cust_email
From Customers
Where cust_email is not null;
创建视图过滤没有电子邮件的顾客。
\7. 使用视图与计算字段
例:select prod_id,quantity,item_price,quantity*item_price AS expanded_price
From OrderItems
WHERE order_num=2008;
如果转化为视图
CREATE VIEW OrderItemsExpanded AS
Select order_num,
Prod_id,
Quantity,
Item_price,
Quantity*item_price AS expanded_price
From orderItems;
检索订单2008的详细内容如下
Select * from OrderItemsExpanded
Where order_num=2008;
第十九课 *使用存储过程*
\1. 存储过程就是为以后使用而保存的一条或多条SQL语句。
\2. Access和SQLite不支持存储过程
MySQL5之后支持存储过程
\3. 存储过程优点:简单,安全,高性能
\4. 存储过程缺点:不同DBMS的存储过程语法不同
编辑存储过程比编写基本SQL语句复杂,需要更丰富经验。
创建存储过程
例如:CREATE PROCEDURE MailingListCount(
ListCount OUT INTEGER
)
IS
v_rows INTEGER;
BEGIN
SELECT COUNT(*) INTO v_rows
FROM Customers
WHERE NOT cust_email IS NULL;
ListCount :v_rows;
END;
创建一个名为ListCount的参数。此参数从存储过程返回一个值,关键词OUT指示这种行为。Oracle支持IN(从传递值给存储过程),OUT(从存储过程返回值),INPUT(即传递值给存储过程,也可以从存储过程传回值)。存储过程的代码在BEGIN和END语句中。
*第二十课 管理事务处理(利用COMMIT和ROLLBACK语句管理事务)*
1,事务处理,通过确保成批的SQL操作要么完全执行,要么完全不执行。保证数据库不包含不完整的操作结果。
2,事务处理的术语
事务(transaction)指一组SQL语句
回退(rollback)指撤销指定SQL语句的过程
提交(commit)指将未存储的SQL语句结果写入数据库表
保留点(savepoint)指事务处理中设置的临时占位符(placeholder),可以对它发布回退
*事务处理管理insert,update,delete,不能回退select,create,drop
不同DBMS事务
数据库 | 事务标识 |
---|---|
SQL Server | BEGIN TRANSACTION…COMMIT TRANSACTION |
MariaDB和MySQL | START TRANSACTION… |
Oracle | Set transaction… |
PostgreSQL | BEGIN… |
没明确标识何处结束,事务便一直存在,直到被中断,通常COMMIT用于保存更改,ROLLBACK用于撤销
\4. ROLLBACK(回退)
用于撤销SQL语句
例:DELETE FROM Orders;
ROLLBACK;
\5. Commit (提交)
例:SET TRANSACTIOM
DELETE OrderItems WHERE order_num=12345;
DELETE Orders WHERE order_num=12345;
COMMIT;
Oracle中事务,保证订单不会部分删除,如果第一条起作用,第二天失败,则delete不会提交。
\6. 保留点SAVEPOINT
回退和提交都是针对整个事务,如果回退或提交部分事务就可以用关键字SAVEPOINT
例:SAVEPOINT delete1;
保留点越多,越能灵活的进行回退
*第二十一课 使用游标*
\1. 结果集(result set)SQL查询所检索出的结果。
\2. 游标(cursor)是一个存储在DBMS服务器是的数据库查询,它不是一条select语句,而是该语句检索出来的结果集。
\3. 游标的特性
-
能标记游标为只读,不能更新和删除
-
能够控制可以执行的定向操作
-
能够标记某些列为可编辑的,某些列为不可编辑的
-
规定范围,使游标对创建它的特定请求或对所有请求可以访问
-
指示DBMS对检索出的数据进行复制,使数据在游标打开和访问期间不变化。
Access不支持游标
MySQL5之后支持游标
SQLite支持的游标为步骤(step),语法略有不同
使用游标需要注意几点
*使用前必须声明(定义)它
*一旦声明必须打开游标以供使用
*对于填有数据的游标,根据需要取出(检索)各行
*结束游标必须关闭,可能的话,释放游标
创建游标(DB2,MariaDB,MySQL,SQL Server)
例: DECLARE CustCursor CURSOR
FOR
SELECT * FROM Customers
WHERE cust_eamil IS NULL;
Oracle和PostgreSQL版本
例:DECLARE CURSOR CustCursor
IS
SELECT * FROM Customers
WHERE cust_email IS NULL; DECLARE语句用于定义和命名游标
使用游标:OPEN CURSOR
访问游标数据:FRTCH
关闭游标:CLOSE CustCursor
例:DECLARE @cust_id CHAR(10), 创建游标
@cust_name CHAR(50),
OPEN CustCursor 使用游标
FETCH NEXT FROM CustCursor 访问数据
INTO @cust_id,@cust_name
WHILE @@FETCH_STATUS=0
BEGIN
FETCH NEXT FROM CustCursor
INTO @cust_id,@cust_name
…
END
CLOSE CustCursor;
为检索出的每一列声明一个变量,FRTCH检索一行并保存到这些变量中,使用while循环处理每一行,最后关闭游标
*第二十二课 高级SQL特性(约束,索引,触发器,数据安全)*
\1. 约束(constraint):管理如何插入或处理数据库数据的规则。
\2. 主键是一种特殊的约束,保证一列或一组列中的值是唯一的,而且永不改动。
\3. 主键需满足的条件
*任意两行主键不能相同。
*每行都具有一个主键值(列中不允许出现NULL)
*包含主键值的列从不修改和更新
*主键值不能重用
\4. 外键是表中的一列,其值必须列在另一表的主键中,外键是保证引用完整性的极其重要部分,还防止意外删除。
\5. 唯一约束。用来保证一列中的数据是唯一的,类似主键,但有以下区别:
*表可以包含多个唯一约束,主键只有一个
*唯一约束包含NULL,主键不允许
*唯一约束可修改和更新,主键不可以
*唯一约束列的值可以重复使用。主键不可以
*唯一约束不能用来定义外键,主键可以
\6. 检查约束:用于保证一列中的数据满足一组指定的条件。特点为:
*检查最小或最大值。
*指定范围
*只允许特定值
\7. 索引用来排序数据以加快搜索和排序操作的速度。
索引特点:
*索引改善操作的性能,降低数据插入,修改,删除的性能。
*索引数据可能占用大量存储空间
*并非所有数据适合做索引
*索引用于数据过滤和数据排序
*可以在索引中定义多个列
例:索引用CREATE INDEX 来创建
CREATE INDEX prod_name_ind
ON Products(prod_name);
索引名为prod_name_ind,ON用于指定被索引的表,而索引中包含的列在表名后的圆括号中给出。
\8. 触发器:是一种特殊的存储过程,在特定的数据库活动发生时自动执行。与表关联。
触发器具有以下数据的访问权:
*insert操作中的所有新数据
*update操作中所有新数据和旧数据
*delete操作中删除的数据
\9. 触发器的用途:
*保证数据一致
*基于某个表的变动在其他表上执行活动。
*进行额外的验证并根据需要回退数据
*计算列的值和更新时间戳
语句是CREATE TRIGGER customer_state
AFTER INSERT OR UPDATE
FOR EACH NOW
BEGIN
UPDATE Customers
SET cust_state=Upper(cust_state)
WHERE Customers.cust_id-:OLD.cust_id
END;
*约束比触发器快,更推荐约束
\10. 数据安全
安全性使用SQL的GRANT 和REVOKE语句来管理