dbTalk Databases Forums  

using constants

comp.databases.oracle.misc comp.databases.oracle.misc


Discuss using constants in the comp.databases.oracle.misc forum.



Reply
 
Thread Tools Display Modes
  #1  
Old   
Marten Lehmann
 
Posts: n/a

Default using constants - 11-29-2007 , 09:44 AM






Hello,

currently, we are using strings like "pending" or "finished" in some
tables to specify the state of certain jobs stored in these tables.
These values are self-explaining. These columns are indexed, of course.

But I guess, lookups of jobs with certain states would be much faster,
if the states would be stored is integer values, e.g. pending = 1,
finished = 2 and so on. However, these values wouldn't be
self-explaining any more.

As long as I'm working with Java, I could defined constants within a
class, so instead of integer values, I could use constants like
State.PENDING or State.FINISHED.

Is it possible to create such constants directly in Oracle, so I can use
them within SQL-queries like

select * from jobs where state = State.PENDING

?

Regards
Marten

Reply With Quote
  #2  
Old   
fitzjarrell@cox.net
 
Posts: n/a

Default Re: using constants - 11-29-2007 , 10:10 AM






Comments embedded.
On Nov 29, 9:44 am, Marten Lehmann <lehmannmap... (AT) cnm (DOT) de> wrote:
Quote:
Hello,

currently, we are using strings like "pending" or "finished" in some
tables to specify the state of certain jobs stored in these tables.
These values are self-explaining. These columns are indexed, of course.

But I guess, lookups of jobs with certain states would be much faster,
if the states would be stored is integer values, e.g. pending = 1,
finished = 2 and so on.
Why would you think that? The values are indexed, and it doesn't
matter to Oracle, really, whether those data values are varchar2 or
number, they all point back to rowids. I can't understand why you'd
expect indexing numbers to be faster than indexing varchar2s.

Quote:
However, these values wouldn't be
self-explaining any more.

So why even think of using them? Possibly this is a holdover from SQL
Server/Sybase experiences with enumerated data?

Quote:
As long as I'm working with Java, I could defined constants within a
class, so instead of integer values, I could use constants like
State.PENDING or State.FINISHED.
Again, using the enumerated data type (which Oracle doesn't have).

Quote:
Is it possible to create such constants directly in Oracle, so I can use
them within SQL-queries like

select * from jobs where state = State.PENDING

?

Certainly it's possible, by creating two additional columns in your
table named, oddly enough, PENDING and FINISHED and populating them
via a trigger based upon your existing state strings:

create or replace trigger job_enum_state
before insert or update on jobs
for each row
begin
if :new.state = 'pending' then
:new.pending := 1;
:new.finished := 0;
elsif :new.state = 'finished' then
:new.pending := 0;
:new.finished := 1;
elsif ld.state = 'pending' then
:new.pending := 1;
:new.finished := 0;
elsif ld.state = 'finished' then
:new.pending := 0;
:new.finished := 1;
end if;
end;
/

SQL> create table jobs (jobid number, state varchar2(12), pending
number, finished number);

Table created.

SQL> create or replace trigger job_enum_state
2 before insert or update on jobs
3 for each row
4 begin
5 if :new.state = 'pending' then
6 :new.pending := 1;
7 :new.finished := 0;
8 elsif :new.state = 'finished' then
9 :new.pending := 0;
10 :new.finished := 1;
11 elsif ld.state = 'pending' then
12 :new.pending := 1;
13 :new.finished := 0;
14 elsif ld.state = 'finished' then
15 :new.pending := 0;
16 :new.finished := 1;
17 end if;
18 end;
19 /

Trigger created.

SQL> insert into jobs (jobid, state) values (1, 'pending');

1 row created.

SQL> insert into jobs (jobid, state) values (2, 'finished');

1 row created.

SQL> select * from jobs;

JOBID STATE PENDING FINISHED
---------- ------------ ---------- ----------
1 pending 1 0
2 finished 0 1

SQL> update jobs set state = 'finished' where jobid = 1;

1 row updated.

SQL> select * from jobs;

JOBID STATE PENDING FINISHED
---------- ------------ ---------- ----------
1 finished 0 1
2 finished 0 1

SQL>


Quote:
Regards
Marten
Others may offer more elegant solutions.


David Fitzjarrell


Reply With Quote
  #3  
Old   
DA Morgan
 
Posts: n/a

Default Re: using constants - 11-29-2007 , 10:15 AM



Marten Lehmann wrote:
Quote:
Hello,

currently, we are using strings like "pending" or "finished" in some
tables to specify the state of certain jobs stored in these tables.
These values are self-explaining. These columns are indexed, of course.

But I guess, lookups of jobs with certain states would be much faster,
if the states would be stored is integer values, e.g. pending = 1,
finished = 2 and so on. However, these values wouldn't be
self-explaining any more.

As long as I'm working with Java, I could defined constants within a
class, so instead of integer values, I could use constants like
State.PENDING or State.FINISHED.

Is it possible to create such constants directly in Oracle, so I can use
them within SQL-queries like

select * from jobs where state = State.PENDING

?

Regards
Marten
The chance of you having enough activity on these tables to be able to
measure the difference between your strings and an integer is remarkably
close to zero.

But, as with all things, test and see. My guess is any difference you
find will be measured in milliseconds.
--
Daniel A. Morgan
Oracle Ace Director & Instructor
University of Washington
damorgan@x.washington.edu (replace x with u to respond)
Puget Sound Oracle Users Group
www.psoug.org


Reply With Quote
  #4  
Old   
Brian Tkatch
 
Posts: n/a

Default Re: using constants - 11-29-2007 , 11:33 AM



On Thu, 29 Nov 2007 16:44:20 +0100, Marten Lehmann
<lehmannmapson (AT) cnm (DOT) de> wrote:

Quote:
Hello,

currently, we are using strings like "pending" or "finished" in some
tables to specify the state of certain jobs stored in these tables.
These values are self-explaining. These columns are indexed, of course.

But I guess, lookups of jobs with certain states would be much faster,
if the states would be stored is integer values, e.g. pending = 1,
finished = 2 and so on. However, these values wouldn't be
self-explaining any more.

As long as I'm working with Java, I could defined constants within a
class, so instead of integer values, I could use constants like
State.PENDING or State.FINISHED.

Is it possible to create such constants directly in Oracle, so I can use
them within SQL-queries like

select * from jobs where state = State.PENDING

?

Regards
Marten
If you do switch to numbers, a VIEW can be used that automatically
changes the numbers to words, either with a CASE expression, or by
joining to a TABLE that defiunes them. Then, the search could be
directly on the words.

To your first question, as others have said, it is not likely to make
a difference. If the word defines a well known state, and the name
will never change, it is just fine. A lookup table may be nice, but
that depends on the way it is used.

B.


Reply With Quote
  #5  
Old   
Robert Klemme
 
Posts: n/a

Default Re: using constants - 11-29-2007 , 12:07 PM



On 29.11.2007 17:15, DA Morgan wrote:

Quote:
The chance of you having enough activity on these tables to be able to
measure the difference between your strings and an integer is remarkably
close to zero.
LOL - The wording is just gorgeous. :-)

Thanks for making my day, David!

robert


Reply With Quote
  #6  
Old   
Robert Klemme
 
Posts: n/a

Default Re: using constants - 11-29-2007 , 12:09 PM



On 29.11.2007 18:33, Brian Tkatch wrote:
Quote:
On Thu, 29 Nov 2007 16:44:20 +0100, Marten Lehmann
lehmannmapson (AT) cnm (DOT) de> wrote:

Hello,

currently, we are using strings like "pending" or "finished" in some
tables to specify the state of certain jobs stored in these tables.
These values are self-explaining. These columns are indexed, of course.

But I guess, lookups of jobs with certain states would be much faster,
if the states would be stored is integer values, e.g. pending = 1,
finished = 2 and so on. However, these values wouldn't be
self-explaining any more.

As long as I'm working with Java, I could defined constants within a
class, so instead of integer values, I could use constants like
State.PENDING or State.FINISHED.

Is it possible to create such constants directly in Oracle, so I can use
them within SQL-queries like

select * from jobs where state = State.PENDING

?

Regards
Marten

If you do switch to numbers, a VIEW can be used that automatically
changes the numbers to words, either with a CASE expression, or by
joining to a TABLE that defiunes them. Then, the search could be
directly on the words.
You are sure this is faster? How would introducing one more layer of
indirection make this faster? Am I missing something?

Cheers

robert


Reply With Quote
  #7  
Old   
Malcolm Dew-Jones
 
Posts: n/a

Default Re: using constants - 11-29-2007 , 01:39 PM



Marten Lehmann (lehmannmapson (AT) cnm (DOT) de) wrote:
: Hello,

: currently, we are using strings like "pending" or "finished" in some
: tables to specify the state of certain jobs stored in these tables.
: These values are self-explaining. These columns are indexed, of course.

: But I guess, lookups of jobs with certain states would be much faster,
: if the states would be stored is integer values, e.g. pending = 1,
: finished = 2 and so on. However, these values wouldn't be
: self-explaining any more.

: As long as I'm working with Java, I could defined constants within a
: class, so instead of integer values, I could use constants like
: State.PENDING or State.FINISHED.

: Is it possible to create such constants directly in Oracle, so I can use
: them within SQL-queries like

: select * from jobs where state = State.PENDING

create package states_pkg as
function pending return number ;
end states_pkg;

create package body states_pkg as
function pending return number is begin return 1; end pending;
end states_pkg;



select * from jobs where state = States_pkg.PENDING


I wouldn't assume it is faster.

I like to do this, even with readable string values, because a function
can be checked at compile time whereas strings are not

select * from jobs where state = 'Pending' -- whoops!



Reply With Quote
  #8  
Old   
Marten Lehmann
 
Posts: n/a

Default Re: using constants - 11-29-2007 , 04:19 PM



Hello,

Quote:
To your first question, as others have said, it is not likely to make
a difference. If the word defines a well known state, and the name
will never change, it is just fine. A lookup table may be nice, but
that depends on the way it is used.
would you say the same is true for joins? What would be faster,

this one?

domains
-------
name (pk)
....

records
-------
id (pk)
name (fk)
....

for a query like

select * from domains d, records r where d.name = r.name and d.name =
'whatever'

or this one:

domains
-------
id (pk)
name (unique)
....

records
-------
id (pk)
domain_id (fk)
....

for a query like

select * from domains d, records r where d.id = r.domain_id and d.name =
'whatever'

Mathematically it should be faster to compare two 4 byte non-zero
integer values than two at least 8 byte strings. But the first solution
is more elegant and intuitive.

Regards
Marten


Reply With Quote
  #9  
Old   
Brian Tkatch
 
Posts: n/a

Default Re: using constants - 11-30-2007 , 08:18 AM



On Thu, 29 Nov 2007 19:09:05 +0100, Robert Klemme
<shortcutter (AT) googlemail (DOT) com> wrote:

Quote:
On 29.11.2007 18:33, Brian Tkatch wrote:
On Thu, 29 Nov 2007 16:44:20 +0100, Marten Lehmann
lehmannmapson (AT) cnm (DOT) de> wrote:

Hello,

currently, we are using strings like "pending" or "finished" in some
tables to specify the state of certain jobs stored in these tables.
These values are self-explaining. These columns are indexed, of course.

But I guess, lookups of jobs with certain states would be much faster,
if the states would be stored is integer values, e.g. pending = 1,
finished = 2 and so on. However, these values wouldn't be
self-explaining any more.

As long as I'm working with Java, I could defined constants within a
class, so instead of integer values, I could use constants like
State.PENDING or State.FINISHED.

Is it possible to create such constants directly in Oracle, so I can use
them within SQL-queries like

select * from jobs where state = State.PENDING

?

Regards
Marten

If you do switch to numbers, a VIEW can be used that automatically
changes the numbers to words, either with a CASE expression, or by
joining to a TABLE that defiunes them. Then, the search could be
directly on the words.

You are sure this is faster? How would introducing one more layer of
indirection make this faster? Am I missing something?
I was addressing his actual question "Is it possible to create such
constants directly in Oracle...". I answered that a VIEW could do it.
Not that it would be faster, however.

B.


Quote:
Cheers

robert

Reply With Quote
  #10  
Old   
Brian Tkatch
 
Posts: n/a

Default Re: using constants - 11-30-2007 , 08:24 AM



On Thu, 29 Nov 2007 23:19:08 +0100, Marten Lehmann
<lehmannmapson (AT) cnm (DOT) de> wrote:

Quote:
Hello,

To your first question, as others have said, it is not likely to make
a difference. If the word defines a well known state, and the name
will never change, it is just fine. A lookup table may be nice, but
that depends on the way it is used.

would you say the same is true for joins? What would be faster,

this one?

domains
-------
name (pk)
...

records
-------
id (pk)
name (fk)
...

for a query like

select * from domains d, records r where d.name = r.name and d.name =
'whatever'

or this one:

domains
-------
id (pk)
name (unique)
...

records
-------
id (pk)
domain_id (fk)
...

for a query like

select * from domains d, records r where d.id = r.domain_id and d.name =
'whatever'

Mathematically it should be faster to compare two 4 byte non-zero
integer values than two at least 8 byte strings. But the first solution
is more elegant and intuitive.
If you are asking what would be faster in a "real life" situation, as
others have pointed out, it is unlikely to make a noticeable
difference (that you would care about). If you are speaking
academically, perhaps it is faster, but i simply do not know enough to
answer that question.

As for your queries, as i am sure you know, the first query does a
redundant join, unless you are checking for existence of the record in
the domain TABLE. Though, perhaps an EXISTS would be clearer and
faster in that case.

Personally, i like the second case better. Because names change (or
split), ids do not. And anything that can change, should not be used
as the PK.

B.


Quote:
Regards
Marten

Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.3
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.