文库发布:sql基础教程_第1页
文库发布:sql基础教程_第2页
文库发布:sql基础教程_第3页
文库发布:sql基础教程_第4页
文库发布:sql基础教程_第5页
已阅读5页,还剩48页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

新疆大学软件学院-----数据库原理与技术SQL教程廖彬liaobin665@163.comSQL教程注:所使用的练习表为oralce数据库scott用户下的bonus,dept,emp,salgrade四张表。教程准备条件:1.如果您的机器上有安装oralce,请使用scott/tiger进入oracle进行学习。2.如果您的机器上没有安装oralce,那么可以使用oralce_scott_export_mysql.sql文件,在mysql中执行文件中的sql语句,创建练习的bonus,dept,emp,salgrade四张表。SQL

全名是结构化查询语言(StructuredQueryLanguage),是用于\o"数据库"数据库中的标准数据查询语言,\o"IBM"IBM

公司最早使用在其开发的数据库系统中。\o"1986年"1986年10月,美国\o"ANSI"ANSI

对SQL进行规范后,以此作为\o"关系式数据库管理系统"关系式数据库管理系统的标准语言(ANSIX3.135-1986),\o"1987年"1987年得到\o"国际标准组织"国际标准组织的支持下成为国际\o"标准"标准。不过各种通行的数据库系统在其实践过程中都对SQL规范作了某些编改和扩充。所以,实际上不同数据库系统之间的SQL语言不能完全相互通用。SQL语言包含4个部分:※数据定义语言(DDL),例如:CREATE、DROP、ALTER等语句。※数据操作语言(DML),例如:INSERT(插入)、UPDATE(修改)、DELETE(删除)语句,COMMIT、ROLLBACK。※数据查询语言(DQL),例如:SELECT语句。※数据控制语言(DCL),例如:GRANT、REVOKE、等语句。SQL语言包括三种主要程序设计语言类别的语句:数据定义语言(DDL),数据操作语言(DML)及数据控制语言(DCL)。1Mysql中创建bonus,dept,emp,salgrade四张表在mysql中创建数据库scott使用命令:CREATEDATABASEdatabase_nameCreatedatabasescott;Createdatabasescott;//创建数据库scottUsescott;//选择操作的数据库注:可用dropdatabasexxxx;(xxxx为数据库)命令来删除数据库,SQL中关键字不区分大小写在scott数据库中创建bonus,dept,emp,salgrade四张表如下为在oracle下对这几张表的解释,在oralce中的NUMBER在mysql中为INT1.2.2创建表语句CREATETABLE语句CREATETABLE语句用于创建数据库中的表。SQLCREATETABLE语法CREATETABLE表名称(列名称1数据类型,列名称2数据类型,列名称3数据类型,....)1.2.3bonus,dept,emp,salgrade四张表创建语句: CREATETABLEDEPT(DEPTNOINTPRIMARYKEY,DNAMEVARCHAR(14),LOCVARCHAR(13));CREATETABLEEMP(EMPNOINTPRIMARYKEY,ENAMEVARCHAR(10),JOBVARCHAR(9),MGRINT,HIREDATEDATE,SALINT,COMMINT,DEPTNOINTREFERENCESDEPT);CREATETABLEBONUS(ENAMEVARCHAR(10),JOBVARCHAR(9),SALINT,COMMINT);CREATETABLESALGRADE(GRADEINT,LOSALINT,HISALINT ); 在创建好的表中插入数据库Insertinto语句INSERTINTO语句用于向表格中插入新的行。语法INSERTINTO表名称VALUES(值1,值2,....)我们也可以指定所要插入数据的列:INSERTINTOtable_name(列1,列2,...)VALUES(值1,值2,....)向DEPT表中插入数据INSERTINSERTINTODEPTVALUES(10,'ACCOUNTING','NEWYORK');INSERTINTODEPTVALUES(20,'RESEARCH','DALLAS');INSERTINTODEPTVALUES(30,'SALES','CHICAGO');INSERTINTODEPTVALUES(40,'OPERATIONS','BOSTON');

1.3.3向EMP表中插入数据INSERTINSERTINTOEMPVALUES(7369,'SMITH','CLERK',7902,'1980-12-17',800,NULL,20);1.3.4向SALGRADE表中添加数据示例代码为:INSERTINSERTINTOSALGRADEVALUES(1,700,1200);2数据库查询select关键字2.1简单查询语句SQLSELECT语句SELECT语句用于从表中选取数据。结果被存储在一个结果表中(称为结果集)。SQLSELECT语法SELECT列名称FROM表名称以及:SELECT*FROM表名称注释:SQL语句对大小写不敏感。SELECT等效于select。示例1:select*fromemp;

示例2:selectempno,ename,salfromemp;2.1.1为列起别名我们可以为返回列的名称起别名:示例3:selectempnobianhao,enamexingming,jobgongzuofromemp;注:还可以添加as关键字,也可以使用中文(如果支持)如:selectempnoasbianhao,enameasxingming,jobasgongzuofromemp;扩展:读懂下面sql语句:selecte.empnobianhao,e.enamexingming,e.jobgongzuofromscott.empase;2.1.2DISTINCT关键字想查询有哪些工作类型:Selectjobfromemp;有重复的列,怎样消除重复的列?-----使用distinct关键字:关键词DISTINCT用于返回唯一不同的值。语法:SELECTDISTINCT列名称FROM表名称如:selectdistinctjobfromemp;2.1.3SQL中的四则运算示例:要求查询出员工姓名及年薪?Selectename,sal*12fromemp;2.2WHERE关键字限定简单查询如需有条件地从表中选取数据,可将WHERE子句添加到SELECT语句。语法为:SELECT列名称FROM表名称WHERE列运算符值(条件)下面的运算符可在WHERE子句中使用:注释:在某些版本的SQL中,操作符<>可以写为!=。除了上面的操作符还包括,IN,NOTIN,AND,OR,BETWEENAND,ISNULL,NOTISNULL,LIKE,NOTLIKE。示例1:查询出工资大于2000的员工?(运算符的使用)Select*fromempwheresal>2000;示例2:查询出每月可以得到奖金的员工?(ISNOTNULL)Select*fromempwherecommISNOTNULL;示例3:查询出没有奖金的员工?Select*fromempwherecommISNULL;示例4:查询出工资大于1500并且可以拿奖金的员工?(AND关键字)Select*fromempwheresal>1500andcommISNOTNULL;示例5:查询出工资大于1500,或者可以拿奖金的员工?(OR关键字)Select*fromempwheresal>1500ORcommISNOTNULL;示例6:查询出工资不大于1500并且不可以拿奖金的员工?(NOT关键字)Select*fromempwhereNOT(sal>1500andcommISNOTNULL);示例7:查询出工资大于1500但是小于3000的员工?(betweenand关键字)Select*fromempwheresal>1500andsal<3000;等同于:Select*fromempwheresalbetween1500and3000;注意betweenand之间的数字是有顺序的!原则是从小到大!字段between最小值and最大值思考:为什么查询出来分别是4行记录和7行记录?操作符BETWEEN...AND会选取介于两个值之间的数据范围。这些值可以是数值、文本或者日期。SQLBETWEEN语法:SELECTcolumn_name(s)FROMtable_nameWHEREcolumn_nameBETWEENvalue1ANDvalue2

示例8:查询出姓名为SMITH的员工的信息(字符串查询)。Select*fromempwhereename=’SMITH’;注意:对于字符串查询时区分大小写的,如SMITH和smith是有区别的。示例8:查询出编号为7499,7566,7698的员工的信息(IN关键字)。IN操作符允许我们在WHERE子句中规定多个值。SQLIN语法:SELECTcolumn_name(s)FROMtable_nameWHEREcolumn_nameIN(value1,value2,...)Select*fromempwhereempno=7499orempno=7566orempno=7698;可以尝试IN关键字当然也可以在关键字加NOT:Select*fromempwhereempnoin(7499,7566,7698);练习:查询姓名为ALLEN,SMITH,JONES的员工信息?思考:select*fromempwhereenamein(‘ALLEN’,‘SMITH’,‘JONES’,’%%%$$$###@’);会有查询结果吗?如果有,查询结果是什么?示例9:查询第二个字母为M的员工的信息(LIKE关键字)。Select*fromempwhereenamelike‘_M%’;LIKE操作符用于在WHERE子句中搜索列中的指定模式。其中’%’可以匹配任意长度的内容,’_’可以匹配一个长度的内容。思考:select*fromempwhereenamelike‘%%’;的执行结果。2.2.1对查询结果进行排序(ORDERBY子句)ORDERBY语句用于对结果集进行排序ORDERBY语句默认按照升序(ASC)对记录进行排序。如果您希望按照降序对记录进行排序,可以使用DESC关键字。示例10:查询所有员工的信息,并按照工资降序排列。Select*fromemporderbysaldesc;示例10:查询emp记录的条数。(count函数)查询这个公司中的工作种类的数量。(count函数+distinct)计算所有员工的平均工资。(avg函数) 查询最高工资的员工的姓名及编号。(MAXMIN)查询最低工资的员工的姓名及编号查询最早来公司的员工的姓名及编号。2.3练习示例1:查询出部门编号是20的员工信息。示例2:查询出工作为clerk的员工信息。示例3:查询出奖金大于工资的员工信息。示例4:查询出奖金大于工资50%的员工信息。示例5:查询出部门编号为10中的所有MANAGER和部门20中所有CLERK的所有信息。示例6:找出有奖金员工所从事的工作。示例7:找出没有奖金或者奖金小于100的员工信息。示例8:找出名字中不含有字母R的员工信息。3数据表,数据的修改3.1基本表结构的修改语法格式:ALTERTABLE<基本表名>[ADD<新列名><数据类型>[完整性约束]][DROP<列名>[CASCADE│RESTRICT]][MODIFY<列名><数据类型>];<表名>:要修改的基本表ADD子句:增加新列和新的完整性约束条件DROP子句:删除指定的列MODIFY子句:修改原有列的宽度和数据类型注意:CASCADE方式表示:在基本表中删除某列时,所有引用到该列的视图和约束也要一起自动地被删除。RESTRICT方式表示:在没有视图或约束引用该属性时,才能在基本表中删除该列,否则拒绝删除操作。示例1:向emp表中添加住址EADDRESS(varchar(50))字段。代码:altertableempaddeaddressvarchar(50);示例2:删除emp表中EADDRESS字段。代码:示例3:修改emp表中ENAME字段,增长为varchar(50)。代码:3.2表数据的更新(修改update)语句格式UPDATE<表名>SET<列名>=<表达式>[,<列名>=<表达式>…]│ROW=(元组)[WHERE<条件>];功能修改指定表中满足WHERE子句条件的元组示例1:修改emp表中姓名为ALLEN的员工工资为1200。代码:示例2:更新编号为7499的员工工作为分析员(ANALYST)。代码:3.3表数据的删除(delete,truncate)语法格式:DELETEFROM<表名>[WHERE<条件>];功能删除指定表中满足WHERE子句条件的元组WHERE子句指定要删除的元组缺省表示要删除表中的所有元组示例1:删除emp表中姓名为SIMTH的员工。代码:示例2:删除emp表中工资小于1000的员工。代码:4多表查询问题:查询出员工的编号,员工的姓名,部门的编号,部门的名称及部门的位置。请思考怎么查询?4.1多表查询的概念以上教程我们进行的查询都是简单查询,都只针对一张表进行操作。当我们同时正对两张以上的表进行查询操作时,即为多表查询。语法格式:SELECT{DISTINCT}*|查询列1别名1,查询列2别名2,查询列3别名3,…..FROM表名称1别名1,表名称2别名2,……{WHERE条件(S)}{ORDERBY排序字段ASC|DESC}概念:集合EMP(R1,R2……R14)*DEPT(D1….D4)示例1:使用多表查询,查询emp,和dept两个表。代码:Select*fromemp,dept;截图:4.1.1笛卡尔积的概念笛卡尔(Descartes)乘积又叫直积。假设集合A={a,b},集合B={0,1,2},则两个集合的笛卡尔积为{(a,0),(a,1),(a,2),(b,0),(b,1),(b,2)}。可以扩展到多个集合的情况。类似的例子有,如果A表示某学校学生的集合,B表示该学校所有课程的集合,则A与B的笛卡尔积表示所有可能的选课情况。笛卡尔积的运算性质:由于有序对<x,y>中x,y的位置是确定的,因此A×B的记法也是确定的,不能写成B×A.笛卡尔积也可以多个集合合成,A1×A2×…×An.笛卡尔积的运算性质.一般不能交换.笛卡尔积,把集合A,B合成集合A×B,规定A×B={<x,y>½xÎAÙyÎB}在任意集合A上都可以定义笛卡尔积因为对任意两个集合A和B,用A中元素为第一元素,B中元素为第二元素构成有序对,所有这样的有序对组成的集合就是集合A和B的笛卡尔积.当集合A=B时,笛卡尔积就记作AA.笛卡尔积的案例:给出三个域:D1=SUPERVISOR={张清玫,刘逸}D2=SPECIALITY={计算机专业,信息专业}D3=POSTGRADUATE={李勇,刘晨,王敏}则D1,D2,D3的笛卡尔积为D:D=D1×D2×D3={(张清玫,计算机专业,李勇),(张清玫,计算机专业,刘晨),(张清玫,计算机专业,王敏),(张清玫,信息专业,李勇),(张清玫,信息专业,刘晨),(张清玫,信息专业,王敏),(刘逸,计算机专业,李勇),(刘逸,计算机专业,刘晨),(刘逸,计算机专业,王敏),(刘逸,信息专业,李勇),(刘逸,信息专业,刘晨),(刘逸,信息专业,王敏)}这样就把D1,D2,D3这三个集合中的每个元素加以对应组合,形成庞大的集合群。本个例子中的D中就会有2X2X3个元素,如果一个集合有1000个元素,有这样3个集合,他们的笛卡尔积所组成的新集合会达到十亿个元素。假若某个集合是无限集,那么新的集合就将是有无限个元素。4.2多表查询的注意事项1.由于多表查询是进行笛卡尔积,假设现在进行5张表的多表查询,每一张表中有1000条记录(实际情况也许比这个假设多很多),那么会有多少操作,多少结果?1000*1000*1000*1000*1000=1000^5这个操作所耗费的资源是不可想象的。所以在实际的开发中,我们要尽量的减少多表查询。2.注意在多表查询中养成取别名的习惯问题:那么怎样才能消除笛卡尔积呢?(where)示例2:查询出员工的编号,员工的姓名,部门的编号,部门的名称及部门的位置。代码:Selecte.empno,e.ename,e.deptno,d.dname,d.locFromempe,deptdWheree.deptno=d.deptno;截图:示例3:查询出每个员工的姓名,工作,和直接上级领导的姓名。代码:Selecte.ename,e.job,m.enameFromempe,empmWheree.mgr=m.empno;截图:示例4:在示例3的基础上将员工的部门名称也一起查询出来。代码:Selecte.enameasemployee,e.jobaswork,m.enameasleader,d.dnameasdeptNameFromempe,empm,deptdWheree.mgr=m.empnoande.deptno=d.deptno;截图:示例5:查询出每个雇员的姓名,工资,部门名称,工资在公司的等级。代码:Selecte.empno,e.ename,e.sal,d.dname,sg.gradeFromempe,deptd,salgradesgWheree.deptno=d.deptnoand(e.salbetweensg.losalandsg.hisal);截图:4.3左,右,自然连接查询(leftjoin,rightjoin,naturaljoin)自学示例4:查询出员工的编号,员工的姓名,部门的编号,部门的名称及部门的位置。代码:截图:发现什么问题????5分组函数与分组查询什么是分组?比如:将班上的同学分为男同学和女同学两组,分别计算男同学和女同学的平均分。将员工按照部门进行分组,计算平均工资。思考?分组是按照什么进行分组?5.1分组函数COUNT()计数函数MAX()求出最大值函数MIN()求出最小值函数AVG()求平均数函数SUM()求和函数5.2分组统计(groupby)语法格式:SELECT{DISTINCT}*|查询列1别名1,查询列2别名2,查询列3别名3,…..FROM表名称1别名1,表名称2别名2,……{WHERE条件(S)}{GROUPBY分组条件}{ORDERBY排序字段ASC|DESC}示例1:查询出每个部门的员工数量。代码:Selectdeptno,count(empno)FromempGroupbydeptno;截图:示例2:查询出每个部门的平均工资。代码:Selectdeptno,avg(sal)FromempGroupbydeptno;截图:注意:在使用分组函数的时候,查询中不能出现分组函数和分组条件之外的字段。比如:查询出每个部门的员工数量。代码:Selectdeptno,empno,count(empno)FromempGroupbydeptno;截图:Oracle11g提示错误信息如下:(mysql也许不一样),错误原因:在使用分组函数的时候,查询中不能出现分组函数和分组条件之外的字段。如:empno示例3:按部门分组,并显示部门的名称,以及每个部门的员工数量。(注意分组条件与查询列保持一致性问题)代码:selectd.dname,count(e.deptno)fromscott.empe,scott.deptdwheree.deptno=d.deptnogroupbyd.dname;截图:示例4:要求查询出平均工资大于2000的部门编号和平均工资。代码:selecte.deptno,avg(e.sal)fromscott.empewhereavg(e.sal)>2000groupbye.deptno;错误截图:注意:分组函数只能在分组中使用,不能出现在where语句之中,如果要指定分组的条件,使用HAVING关键字。语法格式:SELECT{DISTINCT}*|查询列1别名1,查询列2别名2,查询列3别名3,…..FROM表名称1别名1,表名称2别名2,……{WHERE条件(S)}{GROUPBY分组条件{HAVING分组条件}}{ORDERBY排序字段ASC|DESC}所以正确的代码为:代码:selecte.deptno,avg(e.sal)fromscott.empegroupbye.deptnohaving(avg(e.sal)>2000);截图:示例5:查询出非salesman工作名称及其从事同一工作的员工的工资总和,并按照工资总和的升序进行排列。代码:selecte.job,sum(e.sal)fromscott.empewheree.job!='SALESMAN'groupbye.job;截图:分组注意事项:只有一列上存在重复的内容才有可能去考虑用分组解决问题。6嵌套查询(子查询)在一个查询的内部还包括另外一个查询,这样的查询我们称为嵌套查询。

1.嵌套查询在一个外层查询中包含有另一个内层查询。其中外层查询称为主查询,内层查询称为子查询。

2.SQL允许多层嵌套,由内而外地进行分析,子查询的结果作为主查询的查询条件.3.子查询中一般不使用order

by子句,只能对最终查询结果进行排序语法格式:SELECT{DISTINCT}*|查询列1别名1,查询列2别名2,查询列3别名3,…..FROM表名称1别名1,表名称2别名2,(SELECT{DISTINCT}*|查询列1别名1,查询列2别名2,查询列3别名3,…..FROM表名称1别名1,表名称2别名2,……{WHERE条件(S)}{GROUPBY分组条件{HAVING分组条件}}{ORDERBY排序字段ASC|DESC})as别名3……{WHERE条件(S)(SELECT{DISTINCT}*|查询列1别名1,查询列2别名2,查询列3别名3,…..FROM表名称1别名1,表名称2别名2,……{WHERE条件(S)}{GROUPBY分组条件{HAVING分组条件}}{ORDERBY排序字段ASC|DESC})}{GROUPBY分组条件{HAVING分组条件}}{ORDERBY排序字段ASC|DESC};注意:所有的子查询语句都必须出现在()中,并且注意省略分号;子查询的分类:单列子查询:返回的结果是一列内容单行子查询:返回多个列,结果为一条完整的记录多行子查询:返回多条记录示例1:要求查询出比员工编号7654的员工工资高的全部雇员信息。第一步:查询出7654工资代码:Selecte.salFromscott.empeWheree.empno=7654;1250第二步:代码:Select*Fromscott.empemWhereem.sal>(Selecte.salFromscott.empeWheree.empno=7654);截图:示例2:要求查询出比员工编号7654的员工工资高,同时与7788从事相同工作的全部雇员信息。代码:Select*Fromscott.empemWhereem.sal>(Selecte.salFromscott.empeWheree.empno=7654)andem.job=(selectp.jobfromscott.emppwherep.empno=7788);截图:示例3:要求查询出工资最低的雇员姓名,工作,工资。第一步:查找出最低工资代码:Selectmin(e.sal)Fromscott.empe;截图:步骤二代码:Selectem.ename,em.job,em.salFromscott.empemWhereem.sal=(Selectmin(e.sal)Fromscott.empe);示例4:要求查询出:部门名称(dept),部门的员工数(count(empno)),部门的平均工资(avg(sal))方法一(不使用嵌套查询):代码:selectd.dname,count(e.empno),avg(e.sal)fromscott.deptd,scott.empewhered.deptno=e.deptnogroupbyd.dname;截图:方法二(使用嵌套查询)第一种子查询:提示:程序需要关联dept和emp表1.首先求出每个部门的部门编号,员工数量,平均工资,需要在emp表中进行分组统计2.在1的基础上(将1的查询结果看做一张新的表)进行嵌套查询代码:临时表:selecte.deptno,count(e.empno),avg(e.sal)fromscott.empe,scott.deptdwheree.deptno=d.deptnogroupbye.deptno;selectde.dname,temp.empnum,temp.salavgfromscott.deptde,(selecte.deptnono,count(e.empno)empnum,avg(e.sal)salavgfromscott.empe,scott.deptdwheree.deptno=d.deptnogroupbye.deptno)astempwherede.deptno=temp.no;截图:示例5:求出每个部门的最低工资的雇员信息。(IN,ANY,ALL关键字)第一步:找出每个部门的最低工资代码:Selectmin(e.sal)Fromscott.empeGroupbye.deptno;截图:步骤二:代码:Select*Fromscott.empemWhereem.salin(Selectmin(e.sal)Fromscott.empeGroupbye.deptno);ANY关键字:=ANY:与IN的效果完全一样>ANY:比里面最小的值要大<ANY:比里面最大的值要小ALL关键字:>ALL:比最大的值要大<ALL:比最小的值要小7约束(CONSTRAINT)注意:以下的代码,在oracle下只需要将int类型变为number便可执行。7.1约束的概念:简单说来:约束就是指对插入数据的各种限制,例如:人员的姓名不能为空,人的年龄只能在0~150岁之间。约束可以对数据库中的数据进行保护。约束可以在建表的时候直接声明,也可以为已建好的表添加约束。在实际的软件开发中,应该对数据库建立约束,保证数据库中数据的完整性,确保数据库数满足业务规则。7.2约束的种类:约束包括:NOTNULL,UNIQUE(唯一性),PRIMARYKEY(主键),FOREIGNKEY(外键)以及CHECK(限定取值范围)等5种类型。7.3NOTNULL非空约束例如:姓名不能为空CREATETABLEperson(pidint,nameVARCHAR(30)NOTNULL);--插入数据INSERTINTOperson(pid,name)VALUES(11,'zhangsan');--错误的数据,会受到约束限制,无法插入INSERTINTOperson(pid)VALUES(12);7.4PRIMARYKEY主键约束主键很重要,在以后的开发过程中,养成习惯:在表中添加id字段:对于业务来说,没有意义,但是对于数据库来说很有意义。·不能重复,不能为空·例如:身份证号不能为空。现在假设pid字段不能为空,且不能重复。DROPTABLEperson;CREATETABLEperson(pidintPRIMARYKEY,nameVARCHAR(30)NOTNULL);--插入数据INSERTINTOperson(pid,name)VALUES(11,'zhangsan');--主键重复了INSERTINTOperson(pid,name)VALUES(11,'lisi');7.5UNIQUE唯一性约束(空值除外)如人员中有电话号码,电话号码不能重复。DROPTABLEperson;CREATETABLEperson(pidintPRIMARYKEYNOTNULL,nameVARCHAR(30)NOTNULL,telVARCHAR(50)UNIQUE);--插入数据INSERTINTOperson(pid,name,tel)VALUES(11,'zhangsan','1234567');--电话重复了INSERTINTOperson(pid,name,tel)VALUES(12,'lisi','1234567');7.6CHECK约束注意:在mysql中对CHECK约束的支持不是很好。在oracle等大型数据库中有很好的支持。例如:人员有年龄,年龄的取值只能是0~150岁之间DROPTABLEperson;CREATETABLEperson(pidintPRIMARYKEYNOTNULL,nameVARCHAR(30)NOTNULL,telVARCHAR(50)NOTNULLUNIQUE,ageintCHECK(ageBETWEEN0AND150));--插入数据INSERTINTOperson(pid,name,tel,age)VALUES(11,'zhangsan','1234567',30);--年龄的输入错误INSERTINTOperson(pid,name,tel,age)VALUES(12,'lisi','2345678',-100);7.7FOREIGNKEY外键约束创建外键约束一定要在一(父表)对多(子表)的多方(子表)表中创建。一对多的表另外还可以叫做子表(多)-父表(子)例如:有以下一种情况:一个人有很多本书:Person表Book表:而且book中的每一条记录表示一本书的信息,一本书的信息属于一个人CREATETABLEbook(bidintPRIMARYKEYNOTNULL,nameVARCHAR(50),--书应该属于一个人pidint);如果使用了以上的表直接创建,则插入下面的记录有效:INSERTINTObook(bid,name,pid)VALUES(1001,'JAVA',12);以上的代码没有任何错误,但是没有任何意义,因为一本书应该属于一个人,所以在此处的pid的取值应该与person表中的pid一致。此时就需要外键的支持。修改book的表结构,修改如下:DROPTABLEbook;CREATETABLEbook(bidintPRIMARYKEYNOTNULL,nameVARCHAR(50),--书应该属于一个人pidint,CONSTRAINTbook_pid_fkFOREIGNKEY(pid)REFERENCESperson(pid)--建立约束:book_pid_fk,与person中的pid为主-外键关系--写法:CONSTRAINT外键名FOREIGNKEY(外键字段)REFERENCES关联表名(关联字段));INSERTINTObook(bid,name,pid)VALUES(1001,'JAVA',12);7.8级联删除(ONDELETECASCADE)如果假设一个人的人员信息没有了,那么此人所拥有的书还应该存在吗?最好,如果person中的一条数据没了,则对应在book中的数据也应该同时消失。在之前的结构上执行delete语句,删除person表中的一条记录:DELETEFROMpersonWHEREpid=12;提示不能删除的错误:因为book中存在了此项的关联,如果person表中的一条数据删除了,则肯定会直接影响到book表中数据的完整性,所以不让删除。如果非要删除,则应该先删除book表中的对应数据,之后再删除person表中的对应数据。此时如果想完成删除person表的数据同时自动删除掉book表的数据操作,则必须使用级联删除。在建立外键的时候必须指定级联删除(ONDELETECASCADE)。CREATETABLEbook(bidintPRIMARYKEYNOTNULL,nameVARCHAR(50),--书应该属于一个人pidint,--建立约束:book_pid_fk,与person中的pid为主-外键关系CONSTRAINTbook_pid_fkFOREIGNKEY(pid)REFERENCESperson(pid)ONDELETECASCADE);7.9约束的SQL语句执行下面的代码:以上两张表中没有任何约束,下面使用alter命令为表添加约束DROPTABLEbook;DROPTABLEperson;CREATETABLEperson(pidint,nameVARCHAR(30)NOTNULL,telVARCHAR(50),ageint);CREATETABLEbook(bidint,nameVARCHAR(50),pidint);1.为两个表添加主键:·person表pid为主键:语法格式:ALTERTABLE+表名+ADDCONSTRAINT+约束名+约束类型(约束字段);ALTERTABLEpersonADDCONSTRAINTperson_pid_pkPRIMARYKEY(pid);·book表bid为主键:ALTERTABLEbookADDCONSTRAINTbook_bid_pkPRIMARYKEY(bid);2.为person表中的tel添加唯一约束:ALTERTABLEpersonADDCONSTRAINTperson_tel_ukUNIQUE(tel);3.为person表中的age添加检查约束:ALTERTABLEpersonADDCONSTRAINTperson_age_ckCHECK(ageBETWEEN0AND150);4.为book表中的pid添加与person的主-外键约束,要求带级联删除ALTERTABLEbookADDCONSTRAINTperson_book_pid_fkFOREIGNKEY(pid)REFERENCESperson(pid)ONDELETECASCADE;5.删除约束ALTERTABLEbookDROPCONSTRAINTperson_book_pid_fk;altertablestudentdropunique(tel);6.启用约束,禁用约束ALTERTABLEbookenableCONSTRAINTperson_book_pid_fk;ALTERTABLEbookdisableCONSTRAINTperson_book_pid_fk;8序列数据库中的主键,尽量不要和我们的业务挂钩。什么序列?一组有序的数字。8.1mysql中的AUTO_INCREMENT在mysql中的AUTO_INCREMENT关键字可以帮助表自动生成自增的主键值。在软件开发中,数据库表中的主键往往是与具体的软件业务无关的,所以我们在软件开发中希望数据库帮我们自动生成主键值,而不需要我们去人工管理。TheAUTO_INCREMENTattributecanbeusedtogenerateauniqueidentityfornewrows:CREATETABLEanimals(idintNOTNULLAUTO_INCREMENT,nameCHAR(30)NOTNULL,PRIMARYKEY(id));INSERTINTOanimals(name)VALUES('dog'),('cat'),('penguin'),('lax'),('whale'),('ostrich');SELECT*FROManimals;但是,oracle中没有自增类型的字段的,所以通常情况下需要定义一个sequence来作为自动增长类型字段的数据。8.2Oracle中的序列(sequence)如何定义一个序列,格式为:createsequence<序列名称>startwith<起始数>incrementby<增长量>[maxvalue

值][minvalue

值][cycle当到达最大值的时候,将继续从头开始][Nocycle

--一直累加,不循环][Cache缓存]可使用NEXTVAL和CURRVAL关键字访问序列值。NEXTVAL返回序列中的下一个编号,而CURRVAL提供对当前值的访问。sequence不属于某个表,也不属于某个字段,sequence仅仅属于某个用户。注意:第一次NEXTVAL返回的是初始值;随后的NEXTVAL会自动增加你定义的INCREMENTBY值,然后返回增加后的值。CURRVAL总是返回当前SEQUENCE的值,但是在第一次NEXTVAL初始化之后才能使用CURRVAL,否则会出错。一次NEXTVAL会增加一次SEQUENCE的值。下面创建一个序列:createsequencemyseqstartwith1incrementby2maxvalue9999minvalue1nocycle;问题:在那里可以查出我们刚刚创建好的序列seq_test?回答:问题:怎样使用sequence?第一步:创建一个测试表Createtabletest_seq(nextvnumber,currvnumber);利用序列,插入数据库:Insertintotest_seq(nextv,currv)values(myseq.nextval,myseq.currval);查询,并观察结果:Select*fromtest_seq;然后再插入,再查询:Insertintotest_seq(nextv,currv)values(myseq.nextval,myseq.currval);查询,观察结果:Select*fromtest_seq;练习:创建一个序列,实现10.1节中animals表的功能,主键自动增长1,并插入数据进行测试。9索引9.1索引的概念在数据库中,索引的含义与日常意义上的“索引”一词并无多大区别(想想查字典时候的索引),它是用于提高数据库表数据访问速度的数据库对象。A)索引可以避免全表扫描。多数查询可以仅扫描少量索引页及数据页,而不是遍历所有数据页。B)对于非聚集索引,有些查询甚至可以不访问数据页。C)聚集索引可以避免数据插入操作集中于表的最后一个数据页。

D)一些情况下,索引还可用于避免排序操作。当然,众所周知,虽然索引可以提高查询速度,但是它们也会导致数据库系统更新数据的性能下降,因为大部分数据更新需要同时更新索引。9.2创建索引的原则创建索引:创建索引一般有以下两个目的:维护被索引列的唯一性和提供快速访问表中数据的策略。--在select操作占大部分的表上创建索引;--在where子句中出现最频繁的列上创建索引;--在选择性高的列上创建索引(补充索引选择性,最高是1,eg:primarykey)--复合索引的主列应该是最有选择性的和where限定条件最常用的列--小于1M的表,最好不要使用索引来查询,表越小,越适合用全表扫描。9.3索引的数据结构-B-TREE我们常见的数据库系统,其索引使用的数据结构多是B-Tree或者B+Tree。例如,MsSql使用的是B+Tree,Oracle及Sysbase使用的是B-Tree。所以在最开始,简单地介绍一下B-Tree。B-Tree不同于BinaryTree(二叉树,最多有两个子树),一棵M阶的B-Tree满足以下条件:

1)每个结点至多有M个孩子;

2)除根结点和叶结点外,其它每个结点至少有M/2个孩子;

3)根结点至少有两个孩子(除非该树仅包含一个结点);

4)所有叶结点在同一层,叶结点不包含任何关键字信息;

5)有K个关键字的非叶结点恰好包含K+1个孩子;另外,对于一个结点,其内部的关键字是从小到大排序的。以下是B-

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论