powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / FAST REFRESH MV
6 сообщений из 6, страница 1 из 1
FAST REFRESH MV
    #32136920
Trampler
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Народ! Помогите создать материализованное представление с FAST REFRESH.
Это выглядит примерно так:
1. Создаем справочную таблицу
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
CREATE TABLE t_dict
    (id                             NUMBER NOT NULL,
    val1                           NUMBER,
    val2                           NUMBER,
    dict_id                        NUMBER)
/    
ALTER TABLE t_dict
ADD PRIMARY KEY (id)
/
ALTER TABLE t_dict
ADD CONSTRAINT t_dict_fk FOREIGN KEY (dict_id)
REFERENCES t_dict (id)
/

2. Создаем таблицу для хранения данных
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
CREATE TABLE t_data
    (id                             NUMBER NOT NULL,
    dict_id                        NUMBER,
    volume                         NUMBER,
    reg_date                       DATE)
/
ALTER TABLE t_data
ADD PRIMARY KEY (id)
/
ALTER TABLE t_data
ADD CONSTRAINT t_data_fk FOREIGN KEY (dict_id)
REFERENCES t_dict (id)
/

3. Теперь надо создать логи, я сделал это так, возможно это не совсем правильно -
Код: plaintext
1.
2.
3.
4.
5.
6.
create snapshot log on t_dict
with  ROWID,  (val1,val2,dict_id)
/
create snapshot log on t_data
with  ROWID, PRIMARY KEY
/

4. Ну и теперь главное - надо создать материализованное представление (fast refresh), в котором будут содержаться строки из t_data, для которых родительская запись из t_dict (ключ t_data.dict_id) имеет максимальное значение поля val2 среди всех своих "родственников" в двухуровневой иерархии (детей или родителей). Неправильное решение (с т.зр. fast refresh) выглядит так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
create materialized view mv_data
refresh fast
on demand
as
select dt.ROWID dt_rowid,
       dt.id,
       dt.volume,
       dt.reg_date
from t_data dt
where exists(select * from t_dict dc
             where dc.id = dt.dict_id
             and dc.val1 =  0 
             and dc.val2 = (select max(val2) from t_dict
                            where nvl(id,dict_id) = nvl(t.id,t.dict_id)
                            )
              )
/

Как создать MV правильно?

Заранее спасибо.
...
Рейтинг: 0 / 0
FAST REFRESH MV
    #32137073
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Может, зайти с другой стороны? В таблице T_DICT добавить поле, которое заполнять как максимальное значение VAL2 среди детей (каким образом - отдельный разговор)? Необходимо обеспечить уникальность пары (VAL2, DICT_ID). В общем, дополнение к твоему, проверил на Oracle EE 8.1.7.4:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
alter table t_dict add constraint unq_t_dict_val2_id unique (val2, id);
alter table t_dict add max_val2 number;

update t_dict d set
  max_val2 = (
    select nvl(max(val2),  0 ) from t_dict
    where dict_id = d.dict_id
  )
/
alter table t_dict modify val2 not null;
alter table t_dict modify max_val2 not null;
commit;

drop materialized view log on t_dict;
drop materialized view log on t_data;

create materialized view log on t_dict
with rowid, (dict_id, val1, val2, max_val2);
create materialized view log on t_data
with rowid, primary key;


drop materialized view mv_data
/
create materialized view mv_data
refresh fast
on demand
as
select dt.rowid dt_rowid,
       dt.id,
       dt.volume,
       dt.reg_date
from t_data dt
where exists (
  select  1 
  from t_dict dc
  where dc.id = dt.dict_id
    and dc.val1 =  0 
    and dc.val2 = dc.max_val2
  )
/


Это если я правильно понял задачу. Меня смущает только условие:
Код: plaintext
1.
     and dc.val1 =  0 
...
Рейтинг: 0 / 0
FAST REFRESH MV
    #32137075
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сорри, первая строка:

Код: plaintext
1.
alter table t_dict add constraint unq_t_dict_val2_dict_id unique (val2, dict_id);
...
Рейтинг: 0 / 0
FAST REFRESH MV
    #32137427
Trampler
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо, на мой взгляд неплохое решение. Поддерживать max_val2 на мой взгляд можно через триггеры before/after statement и таблицу PL\SQL для хранения DICT_ID измененных строк. Хотя м.б. есть решение лучше?

Про "Необходимо обеспечить уникальность пары (VAL2, DICT_ID)." - можно узнать, зачем это надо для FAST REFRESH? (равно и как ограничения NOT NULL на столбцы), или это касается только хорошего тона программирования?

А насчет условия and dc.val1 = 0 - оно конечно не относится к постановке задачи, но т.к. имеет место, я решил его добавить (смысл - есть фильтр на таблицу-справочник, сам пример тестовый конечно ;)) - для полноты ограничений на MV, так сказать.
...
Рейтинг: 0 / 0
FAST REFRESH MV
    #32137445
Trampler
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Жаль нельзя редактировать свои сообщения, в догонку к предыдущему -

я спрашиваю про уникальный ключ и т.д., т.к. у меня и без этих ограничений создался FAST REFRESH MV
...
Рейтинг: 0 / 0
FAST REFRESH MV
    #32137464
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По поводу уникальности значений - это я пересстарался, признаю. После 21-го часа и не такое померещится;) А насчет ограничения not null на поля val2 и max_val2 ИМХО стоит все-таки подумать, поскольку в снапшоте я указал условие:

Код: plaintext
1.
 and dc.val2 = dc.max_val2


Допустим, у тебя есть единственный ребенок с val2 is null. Вопрос: следует ли показывать ссылки на него как на запись с максимальным значением val2? Если нет, то и ладно. Если да, то при указанном запросе это вроде как не пройдет, надо устраивать разбирательства по поводу учета NULL'ов. Решай сам, что более приемлемо.
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / FAST REFRESH MV
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]