SQL操作三

一、自定义表:

1. 数据类型:

I. 字符串:

char(n):固定长度字符串,上限2000,最大长度为n,实际长度也是n,其余用空格填充。 (不设置长度时,默认长度为1)

例如:char(5) 'abcd' 最大长度5,实际长度5,不足位的使用空格填充。

 

varchar(n):上限4000工业标准,支持空字符串,Oracle的varchar2是非工业标准,改为存储null值。可能未来不支持,无法向后兼容。

 

varchar2(n):可变长度字符串,上限4000,最大长度为n,实际长度为字节个数。 (必须有固定长度)

例如:varchar2(5) '你好' 最大长度5,实际长度4  //存储字节:5个,存储字符:2个

 

nvarchar2(n):可变长度字符串,上限2000,最大长度为n,实际长度为字符个数。 (必须有固定长度)

例如:varchar2(5) '你好' 最大长度5,实际长度2  //存储字节:5个,存储字符:5个

 

II. 数字:

integer:任意长度的整数,超过15位后使用科学计数法显示xE10^N。  (只保留整数部分,输入小数自动失去精度)

 

number / number(n) / number(n,m):可用于描述整数长度和小数长度

例如:number 可存储任意长度的的小数

例如:number(5) 可存储总长度为5的整数    1234  //correct  最大(38,n)

例如:number(5,2) 可存储总长度为5的整数+小数  1234.00  //error(小数自动精确到具体长度,总长度不能超过指定值)

12.3实际存储值为12.30(长度为4)//correct

1234.5实际存储值为1234.50(长度为6) //error

 

III. 时间:

date:年月日时分秒,只精确到秒。通过sysdate获取的系统时间所对应的类型就是date。 //可用timestamp

 

IV.大对象类型【了解】:

CLOB:存储大本文(字符)数据。---Solr全文搜索

BLOB:存储较大二进制文件(多媒体文件,最大4GB)。---MapReduce+HDFS大数据分析+文件存储(PB级)

 

2. 约束:

I. 主键约束:primary key 唯一的标识表中的一行数据,此列的值不可重复,不可为null,一张表中只能有一个主键列。不变的列适合做主键。

 

II. 唯一约束:unique 唯一的标识表中的一行数据,不可重复,可以为null(可重复),一张表中可以有多个唯一列。

 

III. 非空约束:not null 此列必须有值。

 

IV. 检查约束:check 通过制定规则,约束此列中的值必须满足某条件才能插入。

//列:email,要求此列中的值必须包含'@zpark'

check( email like'%@zpark%' )

 

//列:password,要求此列中的值长度必须是6位。

check( length(password) = 6 )

check( password like'______' ) //6个_

 

//列:sex,要求此列中的值必须是'男'或者'女'

check( sex = '男' or sex = '女' )

check( sex in ('男','女') )

 

//列:age 要求此列中的值必须在1~160之间

check( age >= 1 and age <= 160)

check( age between 1 and 160)

 

V. 外键约束:foreign key引用外部表的某个列的值,插入数据时,约束此列的值必须是引用表中存在的数据。二者的数据类型必须相同。

语法:references 外部表(字段)  //clazz_id number(6) references clazz(clazz_id)

 

 

 

3. 建表【重点】

I. 语法:

create table 表名(

列名 数据类型 [约束],

列名 数据类型 [约束],

......

列名 数据类型 [约束] //最后一列的末尾不加逗号

);

 

create table 表名(列名1 数据类型 [约束]  , 列名2 数据类型 [约束]  , 列名3 数据类型 [约束] )

 

II. 用例:

//存储班级信息

班级编号 number(6) 主键

班级名称 varchar2(50) 非空

 

 

//存储学生信息

学号 varchar2(50) 主键

姓名 varchar2(50) 非空

性别 varchar2(1) 检查(M,F)

生日 date 非空

电话 varchar2(50) 唯一

邮箱 varchar2(30) 无

班级编号 number(6) 外键(班级表的班级编号)

 

//引用clazz表的clazz_id列的值作为外键,插入时约束学生的班级编号必须存在。

 

alter table t_student add clazz_Id integer; //添加列

alter table t_student add constraint pk_clazz_Id foreign key (clazz_Id) references t_clazz(clazz_Id); //添加外键约束

 

注:

1).如创建后需要删除表,使用drop table 表名;

2).创建关系表时,先创建主表,再创建从表添加引用

3).删除关系表时,先删除从表,再删除主表。

 

二、数据操作(增删改):

1. 插入(insert):

I. 语法:insert into 表名(列1,列2,列3...) values(值1,值2,值3...);

II. 详解:表名后的列名和values后的值要一一对应。

III. 用例:

//添加一条班级信息(10、17级79班)

insert into clazz (clazzid , clazzname) values(10,'17级79班');

 

//添加一名学生信息(1001、tom、M、1995-1-1、10)

insert into t_student (student_id , student_name , sex , borndate , phone , clazz_id)

values(1001,'tom','M',to_date('1995-01-01','yyyy-mm-dd'),'13900000001',10);

注:输入外键时,必须保证此值在主表中已经存在,否则无法插入。

 

//省略列名(输入所有值)

insert into t_student

values(1003,'marry','F',to_date('1995-02-02','yyyy-mm-dd'),'13900000003',10);

注:顺序和个数必须和列的定义一致

 

//省略列名(输入部分值)

insert into t_student

values(1003,'marry','F',to_date('1995-02-02','yyyy-mm-dd'),null,10);

注:缺省部分使用null填充

 

 

2. 修改(update):

I. 语法:update 表名 set 列1 = 新值1, 列2 = 新值2 ,...  where 条件;

II. 详解:set后跟多个 列名 = 值 ,绝大多数情况下都要加where条件,否则为全表更新。

III. 用例:

//修改1001的电话为13900001111

update t_student set phone = '13900001111' where student_id = '1001';

 

//修改1002的名字为'marry'、性别为'女'

update t_student set s_name = 'marry', sex = 'F' where s_id = '1002';

 

//修改班级名称为'2017级79班'学生的班级编号为20

update t_student set clazz_id = 20 where clazz_id = (select clazz_id from t_clazz where clazz_name = '2017级79班')

 

3. 删除(delete):

I. 语法:delete from 表名 where 条件;

II. 详解:删除表中满足where条件的数据。

III. 用例:

//删除学号为J003的学生信息

delete from student where student_id = 'J003';

 

//删除班级名称为'2017级79班,并且叫tom的男同学

delete from t_student

where student_name = 'tom' and sex = 2 and clazz_id = (select clazz_id from clazz where clazz_name = '2017级79班')

 

//删除班级编号为10的班级信息

delete from clazz where clazz_id = 10; //ERROR  删除被引用的数据时,必须先删从表数据,再删主表数据。不允许从表数据孤立。

 

4. 补充:联合主键、联合约束(Excel)

问题描述:创建成绩表,分别存储学生ID和科目名称。描述一个学生的一门课程的成绩。

应用场景:约束一个学生在输入成绩时,相同科目,只能输入一次成绩。拒绝重复数据插入(学生ID+课程编号)。

解决方案:将学生姓名和科目名称作为联合主键。

create table t_score(

       student_name varchar2(20) not null,

       subject_name varchar2(50) not null,

       score number(5,2) check(score between 1 and 100) not null ,

       primary key(student_name , subject_name) //联合主键(通过多个字段值来唯一标识一行数据)

);

//或者使用  unique(字段1,字段2,...) //联合约束

 

三、事务:

问题1:

insert into clazz(clazz_id,clazz_name) values (49,'Java49班');

A客户端执行一条班级表的插入的语句,使用B客户端查询不到数据?

原因:只有执行了commit才会改变数据库中的数据。

 

 

问题2:

转账操作:A给B转账10000元。A账户减,B账户加。

通过事务来控制原子操作

update account set balance = balance - 10000 where id = '6222020200001111';  ---将'6222020200001111'账户余额减10000

如果此时系统断电,下面的SQL语句将不会执行

update account set balance = balance + 10000 where id = '6222020200002222';  --将'6222020200002222'账户余额加10000

 

1. 概念:

事务是一个原子操作,可以由一条或多条SQL组成。

在同一个事务当中,所有的SQL都成功执行时,整个事务成功,有一条SQL执行失败,整个事务都执行失败。

 

2. 事务的边界:

I. 开始:上一个事务结束后的第一条增删改的语句,即事务的开始。

 

II. 结束:

1). 提交:

a. 显示提交:commit;

b. 隐式提交:一条创建、删除的语句,正常退出(SQL*Plus EXIT);

 

2). 回滚:

a. 显示回滚:rollback;

b. 隐式回滚:非正常退出(断电、Down机)。

 

3. 事务的原理:

数据库会为每一个客户端都维护一个空间独立的缓存区(回滚段),一个事务中所有的增删改语句的执行结果都会缓存在回滚段中,只有当事务中所有SQL语句均正常结束(commit),才会将回滚段中的数据同步到数据库。否则无论因为哪种原因失败,整个事务将回滚(rollback)。

 

注:create、drop、alter语句,自带commit。

 

4. 生产环境:基于增删改语句的操作结果(均返回操作后受影响的行数),可通过程序逻辑手动控制事务提交或回滚。

 

5. 事务的特性:ACID

I. 原子性(Atomic) :同一事务中的多个sql是不可分割的整体,都成功才成功,有一个失败,就全部失败。

II. 一致性(Consistency) :事务开始前和事务结束后,数据库中数据保持一致。

III. 隔离性(Isolation) :事务与事务之间相互独立,互不干涉。

IV. 持久性(Durability):事务执行后,对数据库的影响是永久的。

 

四、操作优化:

1. 序列【重点】

I. 语法:create sequence序列名 [参数];

II. 详解:用来生成一列自动增长的值。

create sequence seq_class

[minvalue 值] //最小值

[maxvalue 值] //最大值

[start with ] //起始值

[increment by 值] //递增数

[cache 缓存个数] //每次生成时,可一次获取多个序列编号,避免每次生成都访问数据库服务器。

[cycle] //循环,当生成序列数达到maxvalue后,是否循环使用。根据业务,允许不唯一的列可以使用。

[order] //保证获取顺序。当数据量庞大时,序列只能保证顺序的唯一性,而不保证数据的序列数的顺序。1~10,21~30,11~20

注:默认start with 1 increment by 1

 

III. 用例:

select seq_student.nextval from dual; //获取下一个递增值。

select seq_student.currval from dual; //获取当前序列值,必须在使用nextval获取过之后使用。

 

//使用sequence自动生成序列值作为主键

insert into t_student(s_id,s_name,sex,borndate,age,c_id)

values(seq_student.nextval,'aaa',1,to_date('1990-01-01','yyyy-mm-dd'),19,46);

 

注:drop sequence 序列名; //删除序列

 

2. 视图:

I. 语法:create view 视图名 as select......

II. 详解:保存SQL语句的虚表,简化查询。(如方法调用)

III. 用例:

//查询员工信息(编号、名字、薪资、部门名称)

create view v_emp as //附加  //不能并行使用*作为列名,如:e.*, d.*

select e.employee_id , e.first_name , e.salary , d.department_name

from employees e inner join departments d on e.department_id = d.department_id;

 

//查询编号是203的员工信息(编号、名字、薪资、部门名称)

select * from v_emp where employee_id = 203;

 

注:视图不会独立存储数据,原表发生改变,视图也发生改变。没有优化任何查询性能。

drop view 视图名; // 删除视图,不会影响原表数据。

grant create view to hr; //授权给...

revoke create view from hr; //撤销自...

 

3. 索引:

I. 语法:create index 索引名 on 表(列)

II. 详解:索引类似与字典的目录,用于加快数据检索的速度。

III. 用例:

//为员工表的薪资列创建索引

create index emp_salary_ix on employees(salary);  //Oracle自动使用查询引擎检索。

 

//为学生表的姓名创建索引

create index stu_name_ix on t_student(student_name);

注:

1).查询频率较高的字段,可以创建索引来提高查询效率,一个字段只能有一个索引。

2).索引并非创建的越多越好(占用存储空间,增删改的同时需要维护索引,消耗内存、CPU),提高查询速度,降低了增删改效率。

3).Oracle默认在主键和唯一键上自动创建索引。

drop index 索引名; //删除索引

猜你喜欢

转载自blog.csdn.net/sugar_map/article/details/79811819