|
В данном тексте я попытаюсь изложить те
мелкие ошибки которые делает человек,
впервые создающий схему данных на Oracle. Я не
склонен обвинять несчастного разработчика,
которому удалось таки прорваться через
тома документации, но все же опыт говорит
что "как схему назовете так она и
поплывет"
Create table
Рассмотрим пример:
create table mail_host (
id number(12) primary key,
host varchar2(64) not null,
constraint host_ukey unique (host)
);
| Что хорошо: |
Что плохо: |
| таблица имеет primary key |
Констрейнты стоят но они
не именованы. Oracle даст им свое имя вида
SYS_03485. Когда возникнет такое сообщение -
оно никому ни о чем не будет говорить.
Именуйте констрейнты !
alter table mail_host add constraint mail_host_pk primary key (id)
Констрайнты также принято выносить в
отдельный скрипт |
| расставлена длина данных
(number(12) а не просто number) |
Не указано табличное
пространство.
Необходимо разбить ваши таблицы по
объему данных на 3 больших класса
1) до 100К
2) до 10M
3) До 100M
Создать 3 табличных пространства и
присваивать их таблицам. |
| расставлены constraint'ы |
Для primary key индекс Oracle
создает индекс автоматически или
использует подходящий существующий. Для
foreign констрайнтов Вы должны
сделать это самостоятельно.
Обязательно сделайте это!.
Проверить кто из внешних ключей
неиндексирован можно с помощью скрипта
unindex.sql |
Insert Data
create sequence mail_host_seq start with 1 increment by 1;
insert into mail_host values(mail_host_seq.nextval,'relay1.telekom.ru');
insert into mail_host values(mail_host_seq.nextval,'relay2.telekom.ru');
| Что хорошо: |
Что плохо: |
| Добавление данных
грамотно сделано через собственный
sequence |
Принято выносить
заполнение таблиц у отдельный файл
после создания таблиц, констрайнтов,
индексов. |
Create indexes
Помимо индексов под констрайнты нам
понадобятся и еще индексы.
Определить какие можно будет после
написания запросов к нашему приложению.
Смотрим какие поля наиболее часто встречаются в
предложении "where" и достраиваем...
Не забудем их также распределить по
табличным пространствам отдельно от таблиц
но в соответствии с теми же принципами...
Create API
CREATE OR REPLACE PROCEDURE add_domain_local (
in_domain IN domain_local.domain%TYPE,
in_host_name IN mail_host.host%TYPE) AS
v_count NUMBER;
v_id_host_name mail_host.id%TYPE;
v_id NUMBER;
BEGIN
-- compare exists domain local
select count(id) into v_count from domain_local where
domain=lower(in_domain);
IF v_count > 0 THEN
RAISE_APPLICATION_ERROR(-20000, 'domain: '||lower(in_domain)||' already
exists');
END IF;
-- set id mail host
BEGIN
select id into v_id_host_name from mail_host where host =
lower(in_host_name);
EXCEPTION WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR(-20000, 'Not find mail host
'||lower(in_host_name));
END;
-- insert values
BEGIN
select domain_local_seq.nextval into v_id from dual;
insert into domain_local (id,domain,id_host)
values(v_id,lower(in_domain),v_id_host_name);
insert into job_list (id,name_job,object_id,date_job,lock_appl)
values(job_list_seq.nextval,'add_domain_local',v_id,sysdate,null);
EXCEPTION WHEN others THEN
RAISE_APPLICATION_ERROR(-20000, 'Cant insert to email_routing');
END;
END add_domain_local;
| Что хорошо: |
Что плохо: |
| Все параметры процедуры
и локальные переменные выполнены через
табличные типы данных %TYPE |
Проверка на
существование домена выполняется
подзапросом. Во много пользовательской
среде это ошибка. Нужно просто
поставить уникальный констрайнт. |
| Входящие переменные
имеют отдельный префик "in_" |
Во всех случаях
процедура возвращает один и тот же код
ошибки -20000. Отличаются они только
текстом. Это не правильно. Нужно
выделить уникальные номера ошибок для
всех ситуаций для своего приложения.
Писать в процедуре when others можно
только в исключительных случаях. В
данном случае может не пройти insert либо
в domain_local либо в job_list но мы об этом уже не
узнаем. Лучше обрабатывать ошибки на
клиенте. Если код ошибки > -20000 то это
ошибка oracle и клиенту лучше сказать
чтобы он обратился к администратору.
Если код ошибки в диапазоне от -20999
до -20000 то эту ошибку мы
обрабатывали и поэтому можно показать
текст на экран. Реализация этого на php
см. мой проект ora*php
|
|