Oracle笔记2-数据库设计
数据库的设计
软件开发的流程:
立项->需求分析->概要设计->详细设计->实现->测试->交付->维护
[含数据库设计]
通过需求分析,就可以抽取出关键业务中的"实体类",这些实体类都是
用来封装数据的,这些数据最终都是要存储到数据库中.
数据库设计的基本流程:
根据业务的需求找出相应的实体类,然后把这些实体类映射成数据库
对象(表),再考虑实体的属性,也就是表格的列,最后考虑实体之间的
关系,也就是表格之间的关系.
数据库设计的常用工具:
1.sybase公司,PowerDesigner,功能强大,收费
2.ERWIN-Studio,功能比较强大,收费
3.JUDE,日本开发的开源,免费
E-R图(Entity-Relationship),实体关系映射图
它的核心就是映射(mapping):
1.实体名,映射成表名
2.属性,映射成列名
3.对象标示符,映射成主键约束
4.实体关系,映射成表之间的关系(外键约束)
映射举例:
实体类 表
名字 User 表名:tbl_user
属性 id 主键:id
属性 name 列名:name
属性 password 列名:password
实体类之间的关系:
一对一 映射成外键
一对多 映射成外键
多对多 拆分成2个一对多,再映射成外键
自关联 映射成外键
注意:
1.外键一般出现在表多的一方,映射具有方向性.
2.实体类中没有外键的概念,数据库表中才有外键的概念.
-----------------------------------------------------------
数据库的三大范式,也就是数据库设计的原则:
作用:是用来指导数据库设计人员的一种设计思想,保证数据库的设计
是具备可拓展性,无数据的冗余,结构清晰简单明了.
1NF:原子性,也就是说表中任何一个列都是唯一的,不可再拆分的
如:
R(id,name,age),此关系中name可以分为first_name和last_name,
所以,此设计不符合1NF,应该重新设计为:
R(id,first_name,last_name,age)
2NF:在1NF的基础上,不存在非关键列部分依赖于关键列,也就是说
所有的非关键列都必须完全依赖于关键列.
如:
R(sno,sname,cname,score)
1 张三 数学 90
由于以上不管是以哪一列作为关键列,都存在其他非关键列部分依赖
于关键列,所以此设计不符合2NF,应该重新设计为:
R1(sno,sname),存放学生信息的表
R2(cno,cname),存放课程信息的表
R3(sno,cno,score),存放学生与课程考试成绩的中间表
3NF:在2NF的基础上,不存在非关键列传递函数依赖于关键列,也就是
说,所有的非关键列都必须直接依赖于关键列
如:
如果A依赖于B,B依赖于C,我们就说A传递函数依赖于C
学生考入某所大学的信息表:
R(sno,sname,uno,uname,phone,address)
如果以sno作为关键列,sanme,uno是直接依赖于sno,但是uname,phone,
address这三列都是直接依赖于uno,间接依赖于sno,所以此设计不符合
3NF,应该重新设计为:
R1(sno,sname,uno),存放学生信息的表
R2(uno,uname,phone,address),存放大学信息的表
------------------------------------------------------------
DDL(create,drop,alter,rename to)
创建表格分为2个步骤:
1.定义列和数据类型
2.添加约束
约束(constraint)
作用:相对于数据类型而言,用来进一步限定表中数据,使得添加到
表中的数据都是合法有效,符合业务需求的数据,不会出现无效数据.
Oracle中的5种约束类型:
1.primary key PK P 含义:主键约束,非空唯一(表中最多只能含有一个主键约束)
2.not null NN C 含义:非空
3.unique UK U 含义:唯一
4.check CK C 含义:自定义约束
5.foreign key FK R 含义:外键约束(表示此列的值是引用自其它表的主键)
注意:能够被外键所引用的列,其本身也必须是主键约束或者唯一性约束.
创建表格的第一种方法:
语法
create table table_name(
列名 数据类型 [default 默认值] [约束],
列名 数据类型 [default 默认值] [约束],
...
列名 数据类型 [default 默认值] [约束]
);
约束的名字:
在创建表格时,如果不定义约束的名字,则数据库会给约束提供默认名,
并且把这些内容存储到数据字典中
--查询当前用户下所有的约束名
select constraint_name from user_constraints;
添加约束名字的语法:
constraint 约束名 约束类型;
约束名的命名规则:
table_name_列名_约束类型缩写
例如:
--创建用户表
create table tbl_user(
id number(5) constraint tbl_user_id_pk primary key,
username varchar2(25) constraint tbl_user_uname_uk unique not null,
password varchar2(25) default '000000'
);
添加约束的2种方法:
1.列级语法添加--边定义列,边添加约束
--创建账户表
create table tbl_account(
id number(5) constraint tbl_acc_id_pk primary key,
accountno varchar2(25) constraint tbl_acc_accno_uk unique not null,
realname varchar2(25),
password char(6) default '000000',
balance number(10,2) constraint tbl_acc_bal_ck check(balance>=0)
);
2.表级语法添加--先定义列,然后再添加约束
create table tbl_account(
id number(5),
accountNo varchar2(25) constraint tbl_acc_ano_nn not null,
realName varchar2(25),
password char(6) default '000000',
balance number(10,2),
constraint tbl_acc_id_pk primary key(id),
constraint tbl_acc_ano_uk unique(accountNo),
constraint tbl_acc_bal_ck check(balance>=0)
);
注意:not null约束不支持表级语法,只能采用列级语法添加!!!
当然,也可以采用如下方法变通实现
create table tbl_account(
id number(5),
accountNo varchar2(25),
realName varchar2(25),
password char(6) default '000000',
balance number(10,2),
constraint tbl_acc_id_pk primary key(id),
constraint tbl_acc_ano_nn check(accountNo is not null),
constraint tbl_acc_ano_uk unique(accountNo),
constraint tbl_acc_bal_ck check(balance>=0)
);
--创建员工表(自关联)
create table tbl_emp(
id number(5),
name varchar2(25) constraint tbl_emp_name_nn not null,
title varchar2(25),
salary number(10,2),
manager_id number(5),
constraint tbl_emp_id_pk primary key(id),
constraint tbl_emp_title_ck check(title in('经理','办事','销售','财务')),
constraint tbl_emp_sal_ck check(salary>1850),
constraint tbl_emp_mgr_fk foreign key(manager_id)
references tbl_emp(id)
);
补充:
创建表格的第二种方法(根据已经存在的某张表创建一张新表格):
--复制了某张表格的指定列,构建一张新表格(拷贝了数据)
create table 新表格名 as select 列,列,... from 原表格;
例如:创建一张s_emp表格中id,first_name,salary三列数据的新表
create table new_emp as select id,first_name,salary from s_emp;
--复制了某张表格的指定列,构建一张新表格(不拷贝数据,取表格结构)
create table 新表格名 as select 列,列,... from 原表格
where 恒假条件;
例如:创建一张s_emp表格中id,first_name,salary三列的新表,不需要数据
create table new_emp as select id,first_name,salary from s_emp
where 1=2;
注意:此处1=2表示恒false,则数据不会被拷贝,只能得到一张空表
删除表格(注意约束控制):
drop table table_name [cascade constraints];
注意:cascade constraints表示连带约束一起删除,如果不添加,
则如果有外键引用,则删除不成功.
修改表格:
--列相关
1.添加列
alter table 表名 add 列名 数据类型 默认值 约束;
--给tbl_user表添加一列(age)
alter table tbl_user add age number(3) default 18 not null;
2.删除列
alter table 表名 drop column 列名;
--删除tbl_user表中的age列
alter table tbl_user drop column age;
3.修改列(修改列的数据类型和约束)
alter table 表名 modify 原列名 新数据类型 新默认值 新约束;
--修改tbl_user表中password列为char(6) 默认值'00000' 非空
alter table tbl_user modify password char(6) default '000000' not null;
4.修改列名
alter table 表名 rename column 原列名 to 新列名;
--修改tbl_user表中password列名为pwd
alter table tbl_user rename column password to pwd;
--约束相关
1.添加约束
alter table 表名 add constraint 约束名 约束类型(列名);
注意:如果是添加非空约束,则:
alter table 表名 add constraint 表名_列名_nn check(x is not null);
**********************************************************************
--删除表格
drop table tbl_emp;
--创建表格
create table tbl_emp(
id number(5),
name varchar2(25) constraint tbl_emp_name_nn not null,
title varchar2(25),
salary number(10,2),
manager_id number(5)
);
--添加约束
alter table tbl_emp add constraint tbl_emp_id_pk primary key(id);
alter table tbl_emp add constraint tbl_emp_title_ck check(title in('经理','办事','销售','财务'));
alter table tbl_emp add constraint tbl_emp_sal_ck check(salary>1850);
alter table tbl_emp add constraint tbl_emp_mgr_fk foreign key(manager_id)
references tbl_emp(id);
--初始化数据
insert into tbl_emp values(...);
insert into tbl_emp values(...);
insert into tbl_emp values(...);
--提交数据
commit;
**********************************************************************
2.删除约束
alter table 表名 drop constraint 约束名;
3.使约束生效
alter table 表名 enable constraint 约束名;
4.使约束失效
alter table 表名 disable constraint 约束名;
------------------------------------------------------------
DML(insert,update,delete)
1.插入数据
insert into 表名(列,列,列,...) values(值,值,值...);
//当插入的数据时与表格列一一对应的话,则列可以省略
insert into 表名 values(值,值,值...);
例如:
--给tbl_user表添加一条记录
insert into tbl_user (id,username,password) values(1,'jack','123456');
insert into tbl_user values(2,'tom','456789');
2.更新数据
update 表名 set 列=新值 where 条件;
例如:
--修改tbl_user表中第二行记录中的用户名
update tbl_user set username='ben' where id=2;
--提高当前订单表中所有状态是未付款的订单价格10%
update tbl_order set price=price*1.1 where status='unpayment';
注意:修改操作千万要注意条件!!!
3.删除数据
delete 表名 where 条件;
例如:
--删除用户表第三行数据
delete tbl_user where id=3;
注意:此处不能违反约束
---------------------------------------------------------
DML语句和DDL语句的不同:
1.DML语句不会自动提交,也就是说当运行完DML语句后,数据库中
真实的数据还没有发生变化,当前自己事务中看到的仅仅是内存
中的情况,所以此时,另一个事务是无法看到修改结果的.
如果要把修改后的结果同步到数据库中,则必须手动使用如下指令:
--提交数据,把内存中的数据同步到数据库中
commit;
--回滚操作,撤销还没有提交的操作
rollback [to 回滚点名字];
--设置回滚点
savepoint 回滚点名字;
即:一个事务无法读取到另一个事务还没有提交的数据!!!
注意:navicat中默认情况下DML语句也会自动提交
2.DDL语句是自动提交的
---------------------------------------------------------
数据字典
定义:数据字典就是用来描述用户对象的对象.
Oracle是一个用表(系统表)来维护表(用户表)的数据库系统,这里
的系统表就是我们所说的数据字典.
Oracle数据库定义的数据字典都遵循一定的命名规则,它内置了上
千张表.
命名规则:
前缀_数据库对象+s/es
常用的前缀:
user
all
dba
$
常用的数据库对象:
table,user,constraint,sequence,index,view...
常用的数据字典:
user_users 存放用户的信息
user_tables 存放用户表的信息
user_constraints 存放表中约束的信息
user_sequences 存放序列的信息
user_indexes 存放索引的信息
user_views 存放视图的信息
user_cons_columns 存放约束与列对应关系的信息
--查看当前用户下有哪些约束
select * from user_constraints;
--查看当前用户下有哪些表格
select table_name from user_tables;
--查看TBL_EMP表中所有的约束名和约束类型
select constraint_name,constraint_type from user_constraints
where table_name='TBL_EMP';
--查看当前用户(jsd1510)下所有状态为不可用的约束名字,以及该约束作用的表格名
select constraint_name,table_name,status from user_constraints
where status='DISABLED' and owner='JSD1510';
注意:此处表名一定要大写!
-------------------------------------------------------------
DTL,数据事务语言
事务的定义:
就是指一组相关的SQL操作,我们所有的操作都是处在事务中的.
注意:在数据库中,执行业务的基本单位是事务,不是以某一条SQL.
数据库在默认情况下,事务都是打开的,也就是说它是一直
处在事务中的,一个事务的结束,代表着下一个事务的开启.
执行commit或者rollback指令时,会结束当前事务.
作用:用来保证数据的平稳性和可预测性.
例如:银行转账业务
A帐号向B帐号转账10000
SQL1:
update tbl_account set balance=balance-10000 where accountNo=A帐号;
SQL2:
update tbl_account set balance=balance+10000 where accountNo=B帐号;
SQL1和SQL2必须处在同一个事务中,从而保证同时成功或者同时失败.
事务的四大特性(ACID):
atomic,原子性,事务是不可再分割的,要么同时成功,要么同时失败
consistency,一致性,事务一旦结束,内存中的数据和数据库中的数据是保持一致的
isolation,隔离性,事务之间互不干扰,一个事务的结束意味着下一个事务的开启
duration,持久性,事务一旦提交,则数据持久化到数据库中,永久保存
在Oracle中,操作事务的命令:
1.commit,提交事务
把事务中所有的数据持久化到磁盘中
2.rollback [TO 回滚点],回滚事务
把事务中所做的操作全部取消,回到初始状态
3.savepoint 回滚点,设置回滚点
事务回滚时,回到的起点
总结:
1.目前主流的数据库都是支持事务的,而且其中Oracle支持的最好,
2.一个事务不能读取到另一个事务还没有提交的数据.
3.DDL语句都会自动提交事务
4.DML语句不会自动提交事务,需要手动commit
---------------------------------------------------------
多事务的并发处理机制:
原因:多个事务同时操作一个表中的同一行数据,如果这些操作是
修改操作的话,就会产生并发问题,如果不处理,则会造成数
据不一致的情况.
数据库可能产生的并发问题包括:
1.脏读
是指一个事务正在访问数据,并且对这个数据进行修改,而这种修改
还没有提交到数据库中,而另一个事务也访问了这个数据,并且使用
了这个数据.
解决方法:一个事务在修改数据时,该数据不能被其他事务访问
2.不可重复读
是指一个事务多次读取同一条记录,如果此时另一个事务也访问并且
修改了该数据,则就会出现多次读取出现数据不一致的情况,原来的
数据变成了不可重复读取的数据
解决方法:只有在修改事务完全提交过后才可以读取到数据
3.幻读
是指一个事务修改表中的多行记录,但是此时另一个事务对该表格进行
了插入数据的操作,则第一个事务会发现表格中会出现没有被修改的行,
就像发生了幻觉一样.
解决方法:在一个事务提交数据之前,其他事务不能添加数据
Oracle中采用'锁'来做并发处理:
1.表级排它锁(X) exclusive mode
2.表级共享锁(S) share mode
3.表中行级排它锁(SRX) share row exclusive
注:这三种锁是通过专门的命令来申请的
语法:
lock table table_name in mode;
例如:
--以共享锁锁表
lock table tbl_emp in share mode;
--以排它锁锁表
lock table tbl_emp in exlusive mode;
4.行级共享锁(RS) row share
5.行级排它锁(RX) row exclusive
注:这两种锁无需通过专门命令申请,而是通过DQL和DML来自动申请的
注意:
1.所有的DQL语句默认情况下都会自动申请RS锁
2.所有的DML语句默认情况下都会自动申请RX锁,每一行记录都会唯一的RX锁
3.在项目中,为了满足业务要求,一般select语句需要申请RX锁
select语句通过for update来申请RX锁:
select * from s_emp for update;
select * from s_emp for update wait 5;//等待5秒钟
select * from s_emp for update nowait;
-----------------------------------------------------------
其他数据库对象:
序列(SEQUENCE)
索引(INDEX)
视图(VIEW)
1.序列(SEQUENCE)
对应的数据字典:user_sequences
作用:用来产生唯一性值的数据库特殊对象
创建序列的语法:
create sequence 序列名
[start with n] --表示从几开始,默认值是1
[increment by n] --每计数一次增加多少,默认是1
[MAXVALUE n] --序列最高峰值n
[MINVALUE n] --序列最低峰值n
[cache n] --提供n个预分配的序列,保存在内存中
[cycle | nocycle] --是否循环
[order | noorder] --有序还是无序序列
例如:
--给员工表创建一个序列
create sequence tbl_emp_id start with 4;
如何使用序列?
nextval:取序列的下一个值(tbl_emp_id.nextval)
currval:取序列的当前的值(tbl_emp_id.currval)
在插入数据时使用:
insert into tbl_emp values(tbl_emp_id.nextval,.........);
删除序列:
drop sequence 序列名;
补充:MySQL
create table tbl_user(
id int auto increment,
username varchar(25),
password varchar(25)
);
---------------------------------------------------------
2.索引(INDEX)
对应的数据字典:user_indexes
它是一个比较重要的数据库对象,作用是可以有效的提高数据库的
查询效率 (数据库性能优化).
创建索引的2种方式:
1.自动创建
当表中的列添加了主键约束或者唯一性约束时,则系统会自动为此列
创建唯一性的索引,索引名就是约束名.
2.手动创建
语法:
create index 索引名 on 表名(列名...);
注意:
1.索引有自己独立的存储空间和命名空间
2.创建索引也会相对牺牲一些数据库性能
索引的原理:
1.默认情况下,索引是采用BTree(二叉树)的数据结构
2.伪列(rowid),存放的数据行记录的真正"物理地址".
--根据物理地址查询某一行记录
//先获取行记录的rowid
select rowid from s_emp where id=1;//AAADXqAABAAAI16AAA
//根据行记录rowid查找相应的记录
select * from s_emp where rowid='AAADXqAABAAAI16AAA';
==>子查询
select * from s_emp where rowid=
(select rowid from s_emp where first_name='Carmen');
3.索引建立的原理:
把创建索引的列值与rowid合成一个键值对,这个键值对就是索引,
然后把它们存放到指定的数据结构中(二叉树,位图)中,并且是独
立的索引空间.
4.索引查询的原理:
当我们的查询语句中where条件的列建立了索引,则查询分为以下2步:
a.先查索引,在句列中的值直接找到rowid
b.根据第一步得到的rowid直接定位到相应的行记录结束查询
5.建立索引的策略:
a.主键列和唯一性列 适合
b.不经常发生改变的列 适合
c.满足以上2个条件,经常作为查询条件的列 适合
d.重复值太多的列 不合适
e.null值太多的列 不合适
6.删除索引
drop index 索引名;
-----------------------------------------------------------
视图(VIEW)
对应的数据字典:user_views
它是一个数据库对象,它的表格的一个"窗口",用来保存查询语句
的对象,视图时依附于表的,并且他与表格共享存储空间.
定义:本质就是一条合法的查询语句
作用:
1.配合权限,根据业务来做分级管理
2.减少复杂性,增强数据的安全性
创建视图的语法:
create [or replace] view 视图名 as 字句;
[with read only] -- 此视图只读
[with check option [constraint 约束名]]
例如:
create view view_name as
select id,salary from s_emp with read only;
注意:
操作视图必须拥有一定的权限!!!
删除视图:
drop view 视图名;
视图的分类:
关系视图,内嵌视图,对象视图,物化视图
----------------------------------------------------------
补充:
--查询当前用户可执行的主要操作
select * from session_privs;
--查询某个权限可执行的所有操作
select * from DBA_SYS_PRIVS where grantee='DBA';(需要DBA)
--查询当前用户被赋予的系统角色
select * from SESSION_ROLES order by role;
授予权限的两种方式:
1.grant create any view to 用户名;
2.grant connect,resource,dba to 用户名;
练习:
--创建41部门所有员工的简单视图(必须拥有操作视图的权限!)
create view view_emp_41 as select * from s_emp where dept_id=41;
Oracle笔记2-数据库设计的更多相关文章
- Oracle基础<1>--数据库设计
一:为什么需要使用数据库设计 数据库设计可以使数据库通过健壮的数据库结构 高效并且健康 的进行工作. 二.数据库设计原则 (数据库设计.系统设计.架构设计) 1.熟悉需求 保证之后需求的变更 不会 ...
- Oracle笔记(十六) 数据库设计范式
数据库设计范式是一个很重要的概念,但是这个重要程度只适合于参考.使用数据库设计范式,可以让数据表更好的进行数据的保存,因为再合理的设计,如果数据量一大也肯定会存在性能上的问题.所以在开发之中,唯一可以 ...
- SQL笔记 --- 数据库设计步骤(转)
SQL笔记 --- 数据库设计步骤 目录 总体设计过程需求分析概念结构设计逻辑结构设计数据库物理设计数据库实施数据库运行和维护 总体设计过程 0 » 下一篇:vim 命令集 posted @ 2012 ...
- Oracle数据库设计实例-实时生产效率系统数据库设计
Oracle数据库设计实例-实时生产效率系统数据库设计 引言 1.1 设计前提 某部门经理要求IT部门设计一个流水线实时生产效率系统,用来统计实时的生产量和效率.流水线有数百条,实时间隔为1min. ...
- Microsoft-PetSop4.0(宠物商店)-数据库设计-Oracle
ylbtech-DatabaseDesgin:Microsoft-PetSop4.0(宠物商店)-数据库设计-Oracle DatabaseName:PetShop(宠物商店) Model:宠物商店网 ...
- Django开发笔记之数据库的设计
后台采用Django开发,可以体会到开发的便利之处,对于一个项目来说,首先最重要的是数据库的设计,那么在Django下数据库设计主要是如下步骤: 1,需求分析,这点子不用多说,而我也深刻体会到了没有原 ...
- MySQL 数据库设计 笔记与总结(2)逻辑设计
[实例演示 —— 实体之间的关系] [逻辑设计的工作] ① 将需求转化为数据库的逻辑模型 ② 通过 ER 图的形式对逻辑模型进行展示 ③ 同所选用的具体的 DBMS 系统无关 [名词解释] 候选码可以 ...
- MySQL 数据库设计 笔记与总结(1)需求分析
数据库设计的步骤 ① 需求分析 ② 逻辑设计 使用 ER 图对数据库进行逻辑建模 ③ 物理设计 ④ 维护优化 a. 新的需求进行建表 b. 索引优化 c. 大表拆分 [需求分析] ① 了解系统中所要存 ...
- MySQL数据库设计复习笔记及项目实战
最近手头上有3个项目开动,其他2个都是从底层开始的,一个已经开始了一段时间的了,在小城市小团队开发的条件下,都没有专门的DBA来做数据库的设计和维护,往往都是开发人员顶上,可是看了很多的数据库的设计, ...
随机推荐
- 认识WCF
WCF 一.什么是WCF? 1.Windows Communication Foundation(WCF)是由微软发展的一组数据通信的应用程序开发接口,可以翻译为Windows通讯接口.它是.NET框 ...
- android学习之RadioButton和CheckBox
移通152 余继彪 RadioBuuton是一个单选按钮,CheckBox是一个复选按钮 . RadioButton的使用 ,首先要将RadioButton放在RadioGroup中,RadioGro ...
- android 多个notifycation向同一个Actiivity传递不同数据
如果你有这方面的需求,那你实践的时候可能会发现,多个Notifycation点击的时候会传递相同的数据. 通常情况下我们可能这样写. Notification notification = new N ...
- Oracle表解锁语句
如果你发现无法对一个表进行修改.删除等操作时,你可以利用以下语句查询是否是该表被锁住了 --查询锁select sess.sid,sess.serial#, lo.oracle_username,lo ...
- Java特性-Collection和Map
创建博客的目的主要帮助自己记忆和复习日常学到和用到的知识:或有纰漏请大家斧正,非常感谢! 之前面试,被问过一个问题:List和Set的区别. 主要区别很明显了,两者都是数组形式存在的,继承了Colle ...
- 【转】图像灰度化方法总结及其VC实现
转载自: http://blog.csdn.net/likezhaobin/article/details/6915754 最近一段时间作者开始进行运动目标识别定位系统设计,本文以及后续的几篇文章都 ...
- STM32F之IAR6.5 J-Link程序下载错误
错误01:Keil环境下使用J-Link SW模式下载程序,而IAR6.5则出现如图1-1的错误.
- x.1
最近公司人事变动略频 昨日老板召集众骨干动员,谈心,表示有信心,没资金压力. 今日各种谈心,唉…… 人事姐姐约逻辑组长聊,美术主管就找上了我,一通倾述.内容实事求是,但是行业内各公司都这样,唉,还想着 ...
- iOS开发一个用户登录注册模块需要解决的坑
最近和另外一位同事负责公司登录和用户中心模块的开发工作,开发周期计划两周,减去和产品和接口的协调时间,再减去由于原型图和接口的问题,导致强迫症纠结症状高发,情绪不稳定耗费的时间,能在两周基本完成也算是 ...
- iOS推送生成服务器端p12文件
生成服务器端推送p12文件 所需文件:A.开发证书 aps_production.cer B.本地导出的私钥 : aps_production.p12 C.生成证书时用到的请求文件:Push.c ...