数据库设计原则

来源:互联网 发布:linux rpm 路径 编辑:程序博客网 时间:2024/05/19 14:56
1.命名约定
  命名应该使用富有含义的英文词汇,要避免使用缩写,多个单词组成的,中间下划线分隔
  除数据库名称长度为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的记录

原创粉丝点击