2009-10-29
OUGF Autumn Seminar
Today is the last day to register to OUGF Autumn Seminar 2009 at Vanha ylioppilastalo (The old student house), Helsinki 5.11.2009. Also time for me to put together a presentation about hierarchical storing structures and - queries. To be held there in finnish.
2009-10-28
Coding Dojo
So, the day came to use PL/SQL MapReduce. Sooner than I thought two days ago. The purpose to use it was not parallel execution but the example itself. Today I participated Solita Oy free time activity coding dojo. And the simplest task there was to put together SpellNumbers and count used letters. I used the brute force method to spell all required numbers. I guess others used more sophisticated approaches. Mine is for sure the only SQL implementation today. Did not get to see other implementations and missed Sauna, because I left early to play with my kids.
My implementation euler17.sql
My implementation euler17.sql
2009-10-27
Direct path insert and Data Guard
Christian Antognini describes nicely the direct path insert hints from version 10.2 to 11.2.
Direct path insert works with Data Guard. No undo is generated for direct path insert and redo is generated. No redo is generated if nologgigin is set on the destination table. With Data Guard force logging should be set. Good explanation about this can be found in several discussions in asktom.
Direct path insert works with Data Guard. No undo is generated for direct path insert and redo is generated. No redo is generated if nologgigin is set on the destination table. With Data Guard force logging should be set. Good explanation about this can be found in several discussions in asktom.
2009-10-26
MapReduce
There might come a day to use parallel SQL processing. A good description about Map-Reduce model using Parallel Pipelined Table Functions and parallel operations.
2009-10-08
Not overlapping daily
Attending. First day gone. Looking forward for tommorow. Tanel should you call your seminar Basic Oracle Troubleshooting Seminar as you talk about how a certain c program is executing function by function? Recommended attendance to all who troubleshoot Oracle.
Back to basics. Should it not be basics of a rdbms system to launch a trigger on an event that it is instructed to execute. With Oracle the issue is not so obvious. A certain kind of a compound trigger will not fire when called through jdbc. Metalink -soon to retire- bug no 6785707.
Another reason for my previous post. But was i thinking too complex. There is actually no need to track bitwise the used years. The problem is not O 2^n problem, but O n. As n is the number of distinct possible values in the validity interval. How about changing possible values from yearly to daily.
Not a production ready aproach. Howcome index creation states that no more columns for a table?
A function based index is creating a invisible virtual column to table. A table may have at least 1000 columns.
Well we have 997 first days covered. How a small inserting test is performing with those 997 indexes?
Back to basics. Should it not be basics of a rdbms system to launch a trigger on an event that it is instructed to execute. With Oracle the issue is not so obvious. A certain kind of a compound trigger will not fire when called through jdbc. Metalink -soon to retire- bug no 6785707.
Another reason for my previous post. But was i thinking too complex. There is actually no need to track bitwise the used years. The problem is not O 2^n problem, but O n. As n is the number of distinct possible values in the validity interval. How about changing possible values from yearly to daily.
drop table z cascade constraints purge;
create table z(z number(16) not null
, validfrom date not null
, validtill date not null
, constraint tilld check (trunc(validfrom)=validfrom)
, constraint fromd check (trunc(validtill)=validtill)
, constraint fro2000
check (to_date('20000101','yyyymmdd') < validfrom)
, constraint til2050
check (validtill <= to_date('20500101','yyyymmdd'))
, constraint frotil check (validfrom <= validtill)
);
begin
for i in (
select 'create unique index z'||d||'
on z (case when validfrom <= to_date('''||d||''',''yyyymmdd'')
and to_date('''||d||''',''yyyymmdd'') < validtill
then z
else null
end)' createindex
from
(select level l
, to_char(to_date('20000101','yyyymmdd')+level-1,'yyyymmdd') d
from dual
connect by level<=to_date('20500101','yyyymmdd')-to_date('20000101','yyyymmdd')
)
order by l
)
loop
execute immediate i.createindex;
end loop;
end;
/
begin
*
ERROR at line 1:
ORA-01792: maximum number of columns in a table or view is 1000
ORA-06512: at line 18
Not a production ready aproach. Howcome index creation states that no more columns for a table?
select count(*)
from user_indexes
where table_name = 'Z';
COUNT(*)
----------
997
select count(*)
from user_tab_columns
where table_name = 'Z';
COUNT(*)
----------
3
select count(*)
from user_tab_cols
where table_name = 'Z';
COUNT(*)
----------
1000
A function based index is creating a invisible virtual column to table. A table may have at least 1000 columns.
Well we have 997 first days covered. How a small inserting test is performing with those 997 indexes?
SQL> insert into z
2 values(1,to_date('20010101','yyyymmdd'),to_date('20010102','yyyymmdd'));
1 row created.
Elapsed: 00:00:00.50
SQL>
SQL> insert into z
2 values(1,to_date('20020101','yyyymmdd'),to_date('20020102','yyyymmdd'));
1 row created.
Elapsed: 00:00:00.40
SQL>
SQL> insert into z
2 values(1,to_date('20020102','yyyymmdd'),to_date('20030101','yyyymmdd'));
1 row created.
Elapsed: 00:00:00.42
SQL>
SQL> insert into z
2 values(1,to_date('20020201','yyyymmdd'),to_date('20020202','yyyymmdd'));
insert into z
*
ERROR at line 1:
ORA-00001: unique constraint (RAFU.Z20020201) violated
Elapsed: 00:00:01.50
SQL>
SQL> select * from z;
Z VALIDFRO VALIDTIL
---------- -------- --------
1 20010101 20010102
1 20020101 20020102
1 20020102 20030101
Elapsed: 00:00:01.01
SQL>
SQL> update z
2 set validfrom=to_date('20010101','yyyymmdd')
3 where z=1 and validfrom=to_date('20020101','yyyymmdd');
update z
*
ERROR at line 1:
ORA-00001: unique constraint (RAFU.Z20010101) violated
Elapsed: 00:00:01.15
2009-09-28
Not overlapping
Lets have a validity period in a table and a rule not to have overlapping periods. The correct solution is to have an another table having the concurrency lock and a combound trigger to handle the overlapping check. Or might there be an alternative way? A way that does not force us to rely that all code modifying the table remember to use the concurrency lock table before modifying the periods. Here it comes. A great abuse of the "bad hack" function based indexes. No need for the concurrency table or triggers.
drop table z cascade constraints purge;
create table z(z number(16) not null
, validfrom number(4) not null
, validtill number(4) not null
, constraint fro2000 check (2000 < validfrom)
, constraint til2050 check (validtill <= 2050)
, constraint frotil check (validfrom <= validtill)
);
create or replace function f(fro number,til number)
return number
deterministic
as
n number(16);
begin
n:=0;
for i in fro..(til-1) loop
n:= n + power(2,i-2001);
end loop;
return n;
end;
/
create unique index z1 on z (case when bitand(1,f(validfrom,validtill)) = 1 then z else null end);
create unique index z2 on z (case when bitand(2,f(validfrom,validtill)) = 2 then z else null end);
create unique index z3 on z (case when bitand(4,f(validfrom,validtill)) = 4 then z else null end);
create unique index z4 on z (case when bitand(8,f(validfrom,validtill)) = 8 then z else null end);
create unique index z5 on z (case when bitand(16,f(validfrom,validtill)) = 16 then z else null end);
create unique index z6 on z (case when bitand(32,f(validfrom,validtill)) = 32 then z else null end);
create unique index z7 on z (case when bitand(64,f(validfrom,validtill)) = 64 then z else null end);
create unique index z8 on z (case when bitand(128,f(validfrom,validtill)) = 128 then z else null end);
create unique index z9 on z (case when bitand(256,f(validfrom,validtill)) = 256 then z else null end);
create unique index z10 on z (case when bitand(512,f(validfrom,validtill)) = 512 then z else null end);
--You maybe got the idea. Left out indexes z11-z46 ...
create unique index z47 on z (case when bitand(70368744177664,f(validfrom,validtill)) = 70368744177664 then z else null end);
create unique index z48 on z (case when bitand(140737488355328,f(validfrom,validtill)) = 140737488355328 then z else null end);
create unique index z49 on z (case when bitand(281474976710656,f(validfrom,validtill)) = 281474976710656 then z else null end);
SQL> insert into z values(1,2001,2011);
1 row created.
SQL> insert into z values(1,2011,2011);
1 row created.
SQL> insert into z values(1,2010,2012);
insert into z values(1,2010,2012)
*
ERROR at line 1:
ORA-00001: unique constraint (RAFU.Z10) violated
SQL> insert into z values(2,2049,2050);
1 row created.
SQL> insert into z values(2,2049,2050);
insert into z values(2,2049,2050)
*
ERROR at line 1:
ORA-00001: unique constraint (RAFU.Z49) violated
SQL> insert into z values(2,2010,2012);
1 row created.
SQL> insert into z values(2,2001,2049);
insert into z values(2,2001,2049)
*
ERROR at line 1:
ORA-00001: unique constraint (RAFU.Z10) violated
SQL> insert into z values(2,2014,2017);
1 row created.
2009-09-21
Denormalize safely
For some reason there is a need to denormalize values from p table to c table.
How to ensure that denormalized values are the same that original values in p?
The denormalization.
Make the c_p_2fk deferrable if there is a need to update the denormalized values. To satisfy unindex:
How to ensure that denormalized values are the same that original values in p?
drop table c cascade constraints purge;
drop table p cascade constraints purge;
create table p(p_id number(10) primary key
, p_name varchar2(200) not null);
create table c(c_id number(10) primary key
, p_id constraint c_p_fk references p
, c_value varchar2(200) not null);
The denormalization.
alter table c add (p_name varchar2(200) not null);
alter table p add unique (p_name,p_id);
alter table c add constraint c_p_2fk foreign key(p_name,p_id) references p(p_name,p_id);
Make the c_p_2fk deferrable if there is a need to update the denormalized values. To satisfy unindex:
create index c_p_2fk_idx on c(p_id,p_name);
Subscribe to:
Posts (Atom)
About Me
- Rafu
- I am Timo Raitalaakso. I have been working since 2001 at Solita Oy as a Senior Database Specialist. My main focus is on projects involving Oracle database. Oracle ACE alumni 2012-2018. In this Rafu on db blog I write some interesting issues that evolves from my interaction with databases. Mainly Oracle.