数据库设计原则

本文详细阐述了数据库命名约定、大小写规范、主键选择、列类型与长度选择、SQL使用约定等最佳实践,旨在优化数据库设计与提高查询效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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的记录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值