Oracle学习总结(2)——Oracle数据库设计总结(三大范式)

一、实体与表对应关系

表<=>实体,字段<=>属性。

二、表与表的关系(实体间的关系):一对一、一对多、多对多

一对一:一条记录只对应其他表中的一条记录有关系

学生基本信息表t_student,成绩表t_studentScore含有一个外键studentId。基本信息表中的studentId和成绩表中的studentId就是一对一的关系。

一对多:A表一条记录对应B表中多条记录有关系,B表的记录不被A表记录共享(有关系)。

班级表和学生表,一个班级有多个学生,对班级来说就是一对多的关系。

多对多:A表一条记录和B表多条记录有关系,B表的一条记录也和A表的多条记录有关系(互相共享)。

学生表和科目表,学生可以选择多个科目,每个科目可以被多个学生选择。

三、基本表的完整性

(1)原子性。字段是不可再分解的。

(2)原始性。记录是原始数据(基础数据)的记录。

(3)稳定性。结构是相对稳定的,表中的记录是要长期保存的。

(4)演绎性。由基本表与代码表中的数据,可以派生出所有的输出数据。

四、其他常用表

1.中间表

中间表是针对多对多关系的。就比如做公交查询系统,里面有两个表,分别是车站表t_busstation、线路表t_road,根据常识,一个站有多个线路经过,而每个线路又有多个车站,怎么才能将两个表联系起来呢,如果是一对一,一对多,我们一个表, 两个表就可以将他们实现了。但是多对多呢,这样我们就必须借助中间表用来连接两个表。一般中间表只有一个自增主键+两个表的主键。中间表是没有属性的因为它不是一个基本表。

2.临时表

临时表是那些以#号开头为名字的数据表,它主要是用来存放临时数据的,当用户断开连接但没有清除临时表里的数据时,系统会自动把临时表里的数据清空。临时表是放在系统数据库 tempdb中的,而不是当前数据库。

临时表分两种:本地临时表和全局临时表。

a.本地临时表

本地临时表是以#开头的,只对当前的数据库用户可见,而其他的用户是不可见的。当数据库实例断开后当然也就丢失了数据了,不管是显式清空还是系统回收。

b.全局临时表

以“##”开头的,而且是对所有的用户都是可见,当你断开数据库实例连接时,只要还有别的系统项目在引用它,连着数据库,那么数据就存在,只有当别的系统也全部断开连接时,系统才会清除全局临时表的数据。

建立临时表的语句:

本地临时表:

create table #student(
studentID int ,
studentName nvarchar (40),
classID int
)

全局临时表:

create table ##student
(
studentID int ,
studentName nvarchar (40).
classID int
)

也可以用SQL语句完成:

select * from employee into #student

五、三大范式

第一范式:如果每列(或者每个属性)都是不可再分的最小数据单元(也称为最小的原子单元),则满足第一范式.比如一个工人的基本信息表,里面有工人的工号,性别,年龄,这些属性都是不可分割的,所以这个表就符合了第一范式。

第二范式: 就是在第一范式的基础上延伸,使之表里的每个字段都与主键发生关系。假如一个关系满足第一范式,并且除了主键以外的其它字段,都依赖于该主键,则满足第二范式.例如:订单表(订单编号、产品编号、定购日期、价格、……),"订单编号"为主键,"产品编号"和主键列没有直接的关系,即"产品编号"列不依赖于主键列,这个列我们就可以把它删除。

第三范式:在第二范式的基础上更进一步,也就是为了实现表里的列都与主键列直接相关,不是间接相关。这个我们可以用“Armstrong 公理”中的传递规则来推理。

定义:设U是关系模式R 的属性集,F 是R 上成立的只涉及U 中属性的函数依赖集。若X→Y 和 Y→Z在R 上成立,则X →Z 在R 上成立。因此我们就来看在网上搜索到的例子:例如:订单表(订单编号,定购日期,顾客编号,顾客姓名,……),初看该表没有问题,满足第二范式,每列都和主键列"订单编号"相关,再细看你会发现"顾客姓名"和"顾客编号"相关,"顾客编号"和"订单编号"又相关,最后经过传递依赖,"顾客姓名"也和"订单编号"相关。为了满足第三范式,应去掉"顾客姓名"列,放入客户表中。这里其实就是为了说明数据库的表里步要出现冗余,在顾客表里已经有了"顾客姓名"了,而在订单表里就别出现了,而直接根据顾客编号相关联就可以,否则造成资源浪费。

三大范式延伸:

第一范式:1NF是对属性的原子性约束,要求属性具有原子性,不可再分解;

第二范式:2NF是对记录的惟一性约束,要求记录有惟一标识,即实体的惟一性;

第三范式:3NF是对字段冗余性的约束,即任何字段不能由其他字段派生出来,它要求字段没有冗余。

其实在设计数据库的时候我们最多的要遵循的就是第三范式,但是并不是越满足第三范式数据库就设计的越完美,这种错误是错误的。有时候增加点冗余相反的会提高访问速率,因此在实际的设计过程中应降低对范式的要求。以前对数据冗余并不是很了解,在百度知道里的定义是这样的:在一个数据集合中重复的数据称为数据冗余. 但是不是说我们表的主键在其他表里重复出现就是冗余,这不是,而是为了连接两个表。只有非键字段就是既不是主键外键等约束的键如果重复出现,就会形成数据冗余。数据冗余也包括重复性冗余和派生冗余。比如工人表里有"基本工资","奖金"两列,然后还有一个"总工资"的列,这个总工资就是派生冗余。低级的重复性冗余一定要避免,杜绝,但是像派生冗余还是提倡的因为它能提高访问的效率。

六、数据库设计中具体要注意的几点;

1.凡是用户输入的不能作为主键

这点大概都知道,主键是唯一的,一般不能让客户做任何操作;

2.凡是有业务意义的不能作为主键

既然是具有业务意义,客户随时都有可能提出这个业务,要求修改业务,也会有变动的可能!

3.除非确定是有必要的字段,其他都允许为空

设计数据库时,约束简单点最好,约束多则在系统中开发时要注意的就多,开发效率相对会底,因为系统是可以通过验证辅助完成这些约束的!

4.不能缺少时间或日期字段

有时间是永远前进,时间的用处很多,打个很简单的比方,在用户表中我们有一个用户创建的时间,在吧项目交个客户后使用一段时间,客户提出新的需求,

比如说:要搞一个周年庆活动,每个满5个月的用户都奖励200代金卷,等等。在这时我们如国有时间字段,那就很容易加上这个业务,但要是没有呢?将会如何?修改数据库?公司的利益会受到严重的打击;

5. 业务的时效(时间有效)性;

6.数据的采集宁滥毋缺

这点非常重要,这就是数据库设计者的后瞻能力了,也就是说我们能在用户还没有提出一些新的需求是,已经把数据都采集好了,就等客户提出需求很轻松的搞定一些业务;有了数据什么都不怕;但有些人也会问,我们前期就把没有用到的数据存进去,后期可以利用也就罢了,如果没有利用到呢?是不是很浪费空间;其实这个问题,我可以这样回答,绝大多数公司在很多方面都是以空间换取时间的;(相信大家都明白!比如在web中使用的AJAX技术)

7.外键字段需要维护或变更,就需要表来维护,如果字段简单,不需要经常变更的,可以直接是程序维护;

总结

数据库设计就是根据业务系统的具体需要,结合我们所选用的DBMS(数据库管理系统),为这个业务系统构造出最优的数据存储模型,并建立好数据库中的表结构及表与表之间的关联关系的过程。使之能有效的对应用系统中的数据进行存储,并可以高效的对已经存储的数据进行访问。

展开阅读全文

学习贴】Oracle总结+++

01-22

[color=#0000FF]/*============================================================================rn *Author: MartriWang@gmail.comrn *Date: 09/05/2007rn *Description:ORACLE Summaryrn *==========================================================================*/rnrn汇总:rnset autotrace onrnset autotrace traceonly explainrnset timing onrnrn或通过SQL*PLUS trace,然后查看user_dump_dest下的跟踪文件,使用tkprof工具格式化后阅览。rnalter session set events '10046 trace name context forever,level 12';rnalter session set events '10046 trace name context off';rnSELECT p.spid,s.username FROM v$session s,v$process p WHERE s.audsid=USERENV('sessionid') AND s.paddr = p.addr;rnrn使用方法示例:rnDBserver% sqlplus perf/perfrnSQL*Plus: Release 9.2.0.6.0 - Production on Mon Oct 17 14:32:29 2005rnCopyright (c) 1982, 2002, Oracle Corporation. All rights reserved.rnConnected to:rnOracle9i Enterprise Edition Release 9.2.0.6.0 - 64bit ProductionrnWith the Partitioning, OLAP and Oracle Data Mining optionsrnJServer Release 9.2.0.6.0 - ProductionrnSQL> set timing onrnSQL> set autotrace onrnSQL> select count(*) from perf_sdcch_nn where start_time = (select max(start_time) from perf_sdcch_nn);rnCOUNT(*)rn----------rn638rnElapsed: 00:00:00.80rnExecution Planrn----------------------------------------------------------rn0 SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=1 Bytes=8)rn1 0 SORT (AGGREGATE)rn2 1 INDEX (RANGE SCAN) OF 'IDX02_PERF_SDCCH_NN' (NON-UNIQUE)rn(Cost=2 Card=1495 Bytes=11960)rnrn3 2 SORT (AGGREGATE)rn4 3 INDEX (FULL SCAN (MIN/MAX)) OF 'IDX02_PERF_SDCCH_NN'rn(NON-UNIQUE) (Cost=1 Card=3852090 Bytes=30816720)rnStatisticsrn----------------------------------------------------------rn0 recursive callsrn0 db block getsrn15 consistent getsrn0 physical readsrn0 redo sizern492 bytes sent via SQL*Net to clientrn656 bytes received via SQL*Net from clientrn2 SQL*Net roundtrips to/from clientrn0 sorts (memory)rn0 sorts (disk)rn1 rows processedrnSQL>rn从上面的示例我们可以看到,该SQL语句执行花了0.8秒,select语句和inline view,都使用了名为'IDX02_PERF_SDCCH_NN'的索引rn物理读为0,redo log size为0,没有生成REDO日志。rnrnrn一、ORACLE的启动和关闭rn1、在单机环境下rn要想启动或关闭ORACLE系统必须首先切换到ORACLE用户,如下rnsu - oraclernrna、启动ORACLE系统rnoracle>svrmgrlrnSVRMGR>connect internalrnSVRMGR>startuprnSVRMGR>quitrnrnb、关闭ORACLE系统rnoracle>svrmgrlrnSVRMGR>connect internalrnSVRMGR>shutdownrnSVRMGR>quitrnrn启动oracle9i数据库命令:rn$ sqlplus /nologrnrnSQL*Plus: Release 9.2.0.1.0 - Production on Fri Oct 31 13:53:53 2003rnrnCopyright (c) 1982, 2002, Oracle Corporation. All rights reserved.rnrnSQL> connect / as sysdba rnConnected to an idle instance.rnSQL> startup^CrnrnSQL> startuprnORACLE instance started.rnrn--MartriWang@gmail.com 10/05/2007--rncreate pfile='/u01/oracle/dbs/init.ora'rn from spfile='u01/oracle/dbs/Spfile.ora';rncreate Spfile='Spfile_name'rn FROM PFILE='pfile_name';rn rnorapwd file= password= entries=rnrn2、在双机环境下rn要想启动或关闭ORACLE系统必须首先切换到root用户,如下rnsu - rootrnrna、启动ORACLE系统rnhareg -y oraclernrnb、关闭ORACLE系统rnhareg -n oraclernrn--MartriWang@gmail.com 22/05/2007--rnrn--查找、删除重复记录:rn  法一: 用Group by语句 此查找很快的rn  rn  select count(num), max(name) from student --查找表中num列重复的,列出重复的记录数,并列出他的name属性rn  group by numrn  having count(num) >;1 --按num分组后找出表中num列重复,即出现次数大于一次rn  delete from student(上面Select的)rn  这样的话就把所有重复的都删除了。-----慎重rn  rn  法二:当表比较大(例如10万条以上)时,这个方法的效率之差令人无法忍受,需要另想办法:rn  rn  ---- 执行下面SQL语句后就可以显示所有DRAWING和DSNO相同且重复的记录rn  rn  SELECT * FROM EM5_PIPE_PREFABrn  WHERE ROWID!=(SELECT MAX(ROWID) FROM EM5_PIPE_PREFAB D --D相当于First,Secondrn  WHERE EM5_PIPE_PREFAB.DRAWING=D.DRAWING ANDrn  EM5_PIPE_PREFAB.DSNO=D.DSNO);rn  ---- 执行下面SQL语句后就可以刪除所有DRAWING和DSNO相同且重复的记录rn  rn  DELETE FROM EM5_PIPE_PREFABrn  WHERE ROWID!=(SELECT MAX(ROWID) FROM EM5_PIPE_PREFAB Drn  WHERE EM5_PIPE_PREFAB.DRAWING=D.DRAWING ANDrn  EM5_PIPE_PREFAB.DSNO=D.DSNO);rnrnOracle数据库有哪几种启动方式rnrnrn说明:rnrn有以下几种启动方式:rn1、startup nomountrn非安装启动,这种方式启动下可执行:rn重建控制文件、重建数据库rn读取init.ora文件,启动instance,即启动SGA和后台进程,这种启动只需要init.ora文件。rnrn2、startup mount dbnamern安装启动,这种方式启动下可执行:rn数据库日志归档、rn数据库介质恢复、rn使数据文件联机或脱机,rn重新定位数据文件、重做日志文件。rnrn执行“nomount”,然后打开控制文件,确认数据文件和联机日志文件的位置,rn但此时不对数据文件和日志文件进行校验检查。rnrnrn3、startup open dbnamern先执行“nomount”,然后执行“mount”,再打开包括Redo log文件在内的所有数据库文件,rn这种方式下可访问数据库中的数据。rnrnrnrnrnrn [/color] 论坛

没有更多推荐了,返回首页