KTG, Может, я неправильно задачу понял. Я себе так ситуацию и простое решение представлял:
--drop table orders;
--drop table clients;
create table clients(ClientNum number primary key,
Status varchar2(40));
create table orders(OrderNum number primary key,
OrderSum number not null,
OrderClient number references clients(ClientNum),
Status varchar2(40));
insert into clients
select level,
'ok'
from dual
connect by level < 1001;
insert into orders
select level OrderNum,
trunc(dbms_random.value * 10000) orderSum,
trunc(dbms_random.value*1000) + 1 OrderClient,
case when dbms_random.value < 0.1 then 'otkaz' else 'ok' end Status
from dual
connect by level < 100001;
commit;
/
declare
achtungs dbms_sql.Number_Table;
procedure setClientStatus(clientNum in number, status in varchar2) is
begin
dbms_output.put_line(clientNum||' is '||status);
end;
begin
for r in (select * from orders where status = 'otkaz' and rownum < 1000) loop
if not achtungs.exists(r.orderclient) then
case
when r.ordersum < 1000 then
setClientStatus(r.orderclient, 'ok');
when r.ordersum >= 1000 and r.ordersum < 5000 then
setClientStatus(r.orderclient, 'not really ok');
when r.ordersum >= 5000 then
achtungs(r.orderclient) := 1;
setClientStatus(r.orderclient, 'achtung');
end case;
else
dbms_output.put_line('order of achtung '||r.orderclient||' detected');
end if;
end loop;
end;
Именовать ограничения можно, чтобы проще было администрировать их, например, дропнуть. Именовать всё подряд смысла не вижу. Not null редко именуют.
При попытке вставить null в not null поле будет сгенерировано исключение. Для этого не нужен триггер. Хотя, и в триггере при желании тоже можно отловить эту ситуацию как раз указанным вами способом. Ну и проверку заполненности полей дублируют в GUI как правило, чтобы выдавать разумные сообщения пользователю до получения исключения из БД.
netrox, получается, сейчас пользователь ждёт вечность, пока прогрузится страница со всей таблицей из БД? Что если выбрать по 5-10 записей, которые стартуют с каждой из букв и передать при старте страницы, а когда пользователь начинает писать, отобразить эту начальную подсказку и отправить запрос в БД на получение более конкретизированной выборки с количеством записей на несколько порядков меньше? При 50 тыс записей, если данные селективны, выборка из БД может занимать сильно меньше, чем работа с сетью и рендер тяжёлых страниц.
Boris Korobkov, идея работы с одной БД и единой структурой под много пользователей (сайтоконструктора например) — это настолько распространённый сценарий, что крупные БД под это дело спициальные опции сделали вроде упоминавшегося row level security у Postgres или private database у Oracle. Там проверка id пользователя автоматически в каждый селект в неявном виде вставляется. Никакого большого риска забыть это проверить нет. Но можно и на коленках реализовать своё. Тогда да, нужно не забывать.
sim3x, к счастью, с такими хардкорными проблемами сталкиваться не приходилось. Для небольшого проекта столкнуться с необходимостью патчить зрелую БД шансов очень мало, и немного шансов, что в таком проекте окажутся специалисты должного уровня. В крупных проектах такие ситуации бывают, поэтому там и опенсорс чаще используют, да и специалисты с большей вероятностью найдутся. Только вот решения от Oracle скорее всего на более раннем этапе безудержного роста забракуются по причине дороговизны.
Dark_Dante, вот этой информации про 150 млн записей, индексирование всех полей, тормозящий запрос и не хватает в вашем исходном вопросе. И здесь исследование начинают обычно с проверки планов выполнения запросов. Обычно здесь-то и выясняются причины проблем. Без планов запросов можно много теорий наплодить. Например, в случае двух таблиц данных и одной таблицы связей, как на рисунке, всё может тормозить, если все 150 млн брендов сидят в одной группе, и вы пытаетесь запросом вытащить все бренды из этой группы. Даже если всё индексировано - тут индексы не помогли бы.
Может, вам вообще нужно в сторону фасетного поиска смотреть.
Многие БД умеют вытаскивать дерево одним рекурсивным запросом или запросом со специализированным синтаксисом (иерархическим). Итоговое представление - обычная таблица. Например, в выборке может получиться набор строк такого вида: answer_id, parent_id, root_id, level.
На мой взгляд, для этой задачи хорошо подходят проекты вроде библиотек, катологизаторов и проч. Например, можно написать генеалогическое приложение: тут и серверная часть (м.б. даже веб-морда), и десктопная, и мобильная может потребоваться, причём, в любой последовательности, там и БД, и сеть, и графика
Максим Тимофеев: будет по одной строке для каждого варианта из salon_product. Поскольку в итоговой выборке отображаются только столбцы из product, то в ней действительно могут быть дубликаты строк, разбросанные в причудливом порядке.
Максим Тимофеев: видимо, вместо конструкции case, в которой вы сейчас выполняете сравнение вида val = null, результат которого неопределён, и поэтому всегда срабатывает ветвь else.
Можно, конечно, поменять case
case when salon_products.sort is null then 50000 else ...