07 高效的模式设计

物理结构关系到应用系统的生死存亡, 选择错误的数据结构, 性能达不到要求.

1. 基本设计原则

让数据库实现完整性

测试示例, 使用触发器进行完整性检查, 触发器是当用户执行SQL语句时, 就会判断触发器, 而不是需要等到最后COMMIT的时候才判断, 比如 利用 scott 模式的emp来完成测试:

要求, emp 表每个部门的行数在 3-8行, 目前emp表满足要求,

1. (session 1 删除一些行, 但是满足触发器, 不提交)

2. session 2 删除一些行, 也满足触发器, 提交

3. 这时候, 再提交session 1, 因为提交的时候触发器已经触发了一次了, 这时候就不会再触发.

4. 那么这两次删除的行数, 已经让这个部门剩下的行小于 3 了.

所以, 用触发器来判断完整性是不合适的. 另外, 要看详细的例子, 就看高效设计 第7章 有完整的例子.

为了解决上边的问题, 我们需要使用一个串行化设备来实现, 我们使用 约束来实现完整性.

-- 1 --  增加约束, 并延后确认

alter table dept add emp_count number constraint must_be_between 3 and 8 or emp_count = 0) deferrable initially deferred; 蓝色表示提交的时候再验证

-- 2 -- 初始化 emp_count 值

update dept set emp_count = (select count(*) from emp where emp.deptno = dept.deptno )

-- 3 -- 生效约束

alter table dept modified emp_count not null;

-- 4 -- 需要一个触发器维持 emp_count, 主要是为了确认修改 deptno

create trigger emp_dept_cnt_trigger

after insert or update or delete on emp

for each row

begin

  if (updating and : old.deptno = : new.deptno) then

    return;  -- no change

  end if ;

  if (inserting or updating ) then

    update dept set emp_count = emp_count + 1

    where deptno = :new.deptno;

  end if;

  if (updating or deleting ) then

    update dept set emp_count = emp_count – 1

    where deptno = : old.deptno;

  end if;

end;

另外, 有一些, 可以使用客户端的约束来确认. 即 application 确认. 但是, 这个只能作为补充, 主要还是要利用数据库级的完整性约束.

使用正确的数据类型

包括类型的精度, 都不是随便的, 比如 varcar2(20), varchar2(200), 有人说, 无所谓, 反正是varchar2类型时变动的, 但是有很多软件, 是根据varchar2的精度来设定单元格的宽度的, 显然20宽度 和 200宽度 相差甚远.

2. 表类型

大部分情况是 使用堆表 和 B*树索引.

你可能感兴趣的:(设计)