命名应该使用富有含义的英文词汇,要避免使用缩写,多个单词组成的,中间下划线分隔
除数据库名称长度为1-8个字符,其余为1-30个字符
命名只能使用英文字母,数字和下划线
避免使用Oracle的保留字如level,关键字如type
各表之间相关列名尽量同名
数据库的命名:网上数据库命名为OLPS(Online Process System)+站点名的2-4个字符,后台数据库命名为"BOPS"+站点名的2-4个字符
INDEX命名:table_name+column_name+ind,各个部分以下划线分隔,多单词组成的column name,取前几个单词首字母,加末单词组成column_name;如sample表 member_id上的index:sample_mid_ind
约束命名:
CHECK约束:_c结束,table_name+column_name+_c
UNIQUE约束:_u结束,table_name+column_name+_u
主键约束:_pk结束,table_name+_pk
外键约束:以f链接外表与主表,table_name_f_primary_table_name
SEQUENCE命名:seq_+table_name
存储过程命名:
包括过程,函数,包,触发器。过程以_p结束,函数以_f结束,包以_k结束,触发器则以触发器类型为前缀
触发器前缀的约定:
第一个字母是B或A,表示为before或after
第二、三、四个字母是I(插入)、U(更新)、D(删除)或他们的任意子集
触发器前缀的约定:
如在member表中,在修改service_trace内容后,修改sample的约束可以命名为:au_member_service_trace
变量的命名约定:本地变量以v_为前缀,参数以p_为前缀,可以待_I(输入),_O(输出),_IO(输入输出)表示参数的输入输出类型
布尔类型的列命名为is+描述,如member表上表示为enabled的会员的列命名为is_enabled
冗余的表类,以X_为前缀
应用系统中所用的临时表,以T_为前缀
命名长度超过30时,可以缩写列名,有"_"分隔的符合列明可分别取首字母,保留最后一个全称
不能有"_TMP","_TEMP"为前/后缀
2.大小写
属于oracle关键字大写,表名、列名等小写
3.主键的选择
选择主键,应避免使用有意义的列,尽量使用SEQUENCE
以下场景可以使用对象的属性做主键
能唯一确定对象的
有not null约束,如复合主键,至少还有一个属性不为空
对主键无更新操作
使用对象属性做主键可以大大提高性能
4.列类型的选择
用CHAR(1)代替布尔值
尽量使用VARCHAR2代替CHAR类型
VARCHAR(2)最多可表示4000字符
DATE精确到秒,而非天
ORACLE只有NUMBER一种数值类型,使用时需给定长度
当列被用在搜索条件中,同时在列上建有index的,应考虑设置为not null
5.列长度的选择
应根据实际情况的需要选择列的长度,有对应web页面的,与页面长度保持一致
6.使用SQL的约定
避免在循环中使用SQL
避免使用数据库的类型自动转换功能
select * from category where id='123'; --id为number类型
如果想利用某字段上的index,应避免对该字段应用类似like '%KEY_WORD%' 或 '_KEY_WORD'等为条件搜索
in,exists操作的选择:子查询得出的结果集记录少,主查询中的表较大又有索引使用in,反之外表记录少,子查询的表中又有索引时使用exists
not in 与not exists操作的选择:not in 只有当子查询中,select关键字后的字段有not null约束时才可用,如果主查询的表大,子查询的表小且记录多,则使用not in;如果主表查询记录少,子查询记录多并有索引,可以用not exists
7,where字句的连接顺序
oracle采用自下而上的顺序解析sql,根据这个原理那些可以过滤掉大量记录的条件必须写在where字句的末尾
8.select语句中避免使用*
oracle在解析的过程中,会将*依次转化为所有的列名,这个工作是通过查询数据字典完成的,这意味着需要消耗更多的时间
9.计算记录的条数
count(*)比count(1)稍快,如果可以通过索引列检索,对索引列的计数是最高效的,如count(emp_no)
10.使用where替换having字句
避免使用having字句,having只会在检索出所有的记录后才对结果集进行过滤,这个时候需要排序,总计等操作,如果可以通过where字句限制这些记录数,就会减少开销
低效的sql:
select region, avg(log_size)
from location
group by region
having region region != 'SYDNEY' and region != 'PERTH';
高效的sql:
select region, avg(log_size)
from location
where region region != 'SYDNEY'
and region != 'PERTH'
group by region;
12.避免在索引列上使用计算
where字句中,如果索引列是函数的一部分,优化器将不使用索引而使用全表扫描,如
select * from dept where sal*12 >10000 --低效!
select * from dept where sal > 10000/12 --高效!
13.避免在索引列上使用not
和在索引列上使用函数是同样的道理,oracle遇到not,会停止使用索引而转向全表扫描
select * from dept where dept_code not = 0; --低效!没用到索引
select * from dept where dept_code > 0; --高效!使用了索引
14.用>=替代>
如果DEPTNO上有一个索引:
select * from emp where deptno >= 4; --高效!
select * from emp where deptno > 3; --低效!
原因在于第一个sql当前DBMS会字节跳转到deptno=4的记录而后者首先定位到deptno=3的记录并向前扫描到第一个大于3的记录