Skip to Main Content
  • Questions
  • tables - whats the difference between lookup and master detail.

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, razvan.

Asked: June 12, 2000 - 11:22 am UTC

Last updated: January 02, 2008 - 3:20 pm UTC

Version: 7.3.2

Viewed 10K+ times! This question is

You Asked

hello tom,

please can you explain me what is the difference between
lookup tables and the tables in master detail relation?


thanks a lot
razvan

and Tom said...

A lookup table is generally a "code to a value". For example:

create table lookup ( code int primary key,
value varchar2(255) );

insert into lookup values ( 1, 'Widget' );
insert into lookup values ( 2, 'Gadget' );
insert into lookup values ( 3, 'Thingy' );

I would use the lookup table to convert FROM a code to a value for display.

I would create other tables that have something like:

create table t
( x int primary key,
...
code int references lookup
)
/

and i would write lots of queries that look like:

select t.*, l.value
from t, lookup l
where t.code = l.code
and t.c .....

Here, technically speaking, LOOKUP is the master table and T is a detail table in a master detail relation. We never query "through" lookup though, we always goto lookup from the table T.

A real master detail, EMP and DEPT for example, is more then a lookup. The DEPT table is considered to be the MASTER table and EMP the detail table. DEPT is a table we might typically query FROM to get the details (this is the major difference between a lookup and a master/detail -- we query through the master table to get the details. We do not query through the lookup table to get the details, we query the details and join that to the lookup always).



Rating

  (19 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Difference between lookup and master table

Sean, January 06, 2003 - 5:42 pm UTC

Hi Tom,

I agree with you about the definition of lookup table, but I always thought that dept is a lookup table since we always try to get dept name by this query:

select e.ename, d.dname from emp e, dept d
where e.deptno = d.deptno;

Although sometimes we can get the location of dept:

select d.name, d.loc from dept d where d.deptno= 10;

Is it safe to say that if master table has only two columns, we can call it lookup table? If master table has more than two columns, we don’t call it lookup table.

Best,

Sean


Tom Kyte
January 06, 2003 - 5:50 pm UTC

Depends on your perspective. To me, DEPT is a master table in a parent child relationship. I go from DNAME=SALES to the list of EMPs. It all depends.

A master table is the same as a lookup table when you query from child to parent.
A lookup table is a master table.

No, it is not safe to say anything -- lookup tables can have more then 2 columns (zip code -> state -> region). Masters can have 2 -- no reason they could not.

It is all "semantics", simply use the term that has more meaning.

using rule engine to design lookup tables

Sean, July 01, 2003 - 6:14 pm UTC

Hi Tom,

We are in the process to redesign our database. Currently, there are a lot of lookup tables, such as ref_unit, ref_sample_frequency (more than seventy). In general, each lookup table contains less than 30 records. One of our developers suggested that we should use the principle of rule engine to define the lookup values. Only a few tables are needed to cover all lookup values, which would cut total tables to half.

I could not find any info on the web to explain how to use the principle of rule engine to design relational database though there are a few applications using rule engine.

My questions:
(1) Is the principle of rule engine a good way to design database to store lookup values?
(2) If it is, how?

Thanks so much for your help.

Best,

Sean




Tom Kyte
July 01, 2003 - 7:52 pm UTC

is this like the three laws of robotics? Not sure with the "principle of rule engine" is.

Go Generic ?

Matt, July 02, 2003 - 3:49 am UTC

I know Tom isn't a big fan of generic table designs but in the case of lookups we've found a generic lookup table with a domain column can handle 80% of our needs. We then put views on top of these to give the appearance of the individual lookup table. I think Oracle Designer uses similiar principle with its CG_Ref_Codes table.



Tom Kyte
July 02, 2003 - 8:11 am UTC

so, if you end up with a ton of views -- why not tables?

with tables, fkeys work properly.
with views, they do not.

with tables, hot spots are spread out.
with views, they are not.

with tables, things are "clear" -- a fkey relationship clearly documents which set of domain values are allowed.

with views, they are not.



generic is fine, just understand the downsides. It is always a tradeoff.

Re: Go Generic?

Tony Andrews, July 02, 2003 - 5:32 am UTC

> I know Tom isn't a big fan of generic table designs but in the case of lookups
we've found a generic lookup table with a domain column can handle 80% of our
needs. We then put views on top of these to give the appearance of the
individual lookup table. I think Oracle Designer uses similiar principle with
its CG_Ref_Codes table.

Yes, Designer does that. But what is the point? Here are the cons:
* You can't use foreign keys for integrity, unless you:
(a) include the domain column in all the child tables and
(b) put a check constraint on the domain column in the child tables
* You are forced to use VARCHAR2(quite big) for all code values, to accommodate all cases
* You have to create views to mimic the individual lookup tables
* Either you risk users setting up inappropriate lookup codes, or you build your own datatype/length rules for each domain and apply them in your maintain lookup screen

What are the pros? The only one as far as I know is: you build one fairly complex lookup maintenance screen instead of N trivially simple lookup maintenance screens.

Does that one pro outweigh all the cons? (Rhetorical question!)

Foreign Keys

Matt, July 02, 2003 - 6:39 am UTC

Would you really want foreign keys to all your lookups ? Is that not where the crossover is between Master Detail, and simple lookups. We tend to use check_constraints on the table column, rather than an FK.

The benefits are we don't need to maintain many lookup modules and tables. A single module can handle it. Yes there may be some thought required about implementing datatypes and sizes - but its not rocket science.



Tom Kyte
July 02, 2003 - 8:34 am UTC

ABSOLUTELY - why else have them?
what is the point of the lookup table otherwise?

You need to maintain many lookup VIEWS -- views require just as much "care and feeding" as a small table does.

A single module can still handle multiple tables -- if you can pass in the name of a lookup so you can query "select ... from generic_table where lookup_name = :x", yu can query "select .... from " lookup-table

Re: Go generic?

Tony Andrews, July 02, 2003 - 7:49 am UTC

> Would you really want foreign keys to all your lookups ? Is that not where the crossover is between Master Detail, and simple lookups. We tend to use check_constraints on the table column, rather than an FK.

If you are ONLY using this approach for static domains to provide a user-friendly list for a value that is then subject to a check constraint, then that is fair enough.

Where I work we have the same sort of thing - only without the check constraints! In fact, many of the lookups are non-static: users are free to add new codes at will. The problems are that only the application enforces use of correct codes, and without inspecting the application it can be hard to know which domain a particular column's values are supposed to come from. It's a bit of a mess.

Just to come to Matt's defence

Paul, July 02, 2003 - 9:00 am UTC

Tom,

you said "ABSOLUTELY - why else have them? what is the point of the lookup table otherwise?" when talking about foreign keys.

Well, the other point is to use them for decoding the lookup to something meaningful in a user application.

I work on a DWH system where we deliberately don't enforce the foreign key constraints, as in some of our data feeds the source systems add new codes without bothering to tell us. Ideally, of course, the processes would be in place to ensure we get the codes in advance, but that doesn't happen at the moment. So every now and then, we run an exception report to list the orphan codes and get somebody to investigate and add the lookup data.

But of course the best reason for having a single table containing all codes is that you don't have to draw so many boxes on you ERD ;-)

Paul

Agreed

Matt, July 02, 2003 - 9:30 am UTC

Yep I agree about the tradeoffs - its just easier for us to define a new lookup within the data, rather than having to create a new table for it, especially as we are working within a rigid development environment. In our case we supply a 3rd party app for rollout on site - its good to have a 'bucket' where we can store reference codes without going through a whole design exercise.


Dave, July 02, 2003 - 9:47 am UTC

What an extraordinary way to run a DW. Does your ETL routine not add the new codes for you then? And you really should be declaring FK's, even disable/novalidate/rely ones for the sake of the optimizer.

Tom Kyte
July 02, 2003 - 10:40 am UTC

well -- if they do the novalidate/disable/rely thing AND we rely on them AND they are wrong -- you will get the WRONG answer via query rewrites.....


so, don't do that unless we can really RELY on the underlying data.

lookup tables

Sean, July 02, 2003 - 5:09 pm UTC

Hi Tom,

Our developer said that rule engine is the way to define the rule of how to choose values in lookup tables. It is not really related to lookup table design though these rules will stored in the table. Sorry for the confusion.

I have other question of lookup tables design:
I have unit lookup table

Unit_code(pk) Unit_desc
Kg/Day Kilograms per day
Mg Milligram

Presumably we will not change the value of unit_code. The advantage of not using sequences number here is that it is easy to see the content of child tables.

Another way to design this table is:

Unit_num Unit_code(pk) Unit_desc
1 Kg/Day Kilograms per day
2 Mg Milligram

Since our child tables use a lot lookup tables, we need to join a lot of lookup tables in order to see the contents in the child tables.

Which way is better?

Thanks so much for your help.

Best,

Sean


Tom Kyte
July 03, 2003 - 8:41 am UTC

I've always prefered to let the database do my work, therefore I will still go back to "i'd like a lookup per domain "

Sean, July 03, 2003 - 11:05 am UTC

My question is whether to use meaningless number as primary key or use short_desc as primary key in lookup table assuming we will not update short_desc.

Thanks for your help

Best,





Tom Kyte
July 03, 2003 - 11:22 am UTC

short_desc would be perfectly acceptable -- assuming the primary key is a true primary key and not subject to change.

Dave, August 01, 2003 - 1:31 am UTC

a) While using the lookup table, will there be any difference between the following two queries ?

1)
select t.*, l.value
from t, lookup l
where t.code = l.code and
t.....

2)
select t.*,
select l.value from lookup l where l.code=t.code
from t
where t......

b) What is the best way to implement lookup tables, where there are hardly any changes? Is caching these table a bad idea?

Tom Kyte
August 01, 2003 - 7:52 am UTC

a) benchmark it. probably fairly equivalent. set up a simulation and see.


b) i'm against "caching" as a rule cause it implies you are writing lots of procedural code.

I prefer to do as much in a single sql statement as humanly possible. after that, sure, caching a small set of reference data in a plsql table type is fine if the data is allowed to become stale.

Another lookup table query...

Dave Blake, January 14, 2004 - 5:04 am UTC

Tom,

Wonder if you can answer this one for me.


Which is better a lookup table formed like this.
(PK)
ID NAME
1 cat
2 dog
3 rabbit
4 horse
etc...

or on like this...

(PK)
NAME
cat
dog
rabbit
horse
etc...


Table one Advantages:
When you have to edit a NAME you only do so in one table.

Disadvantages:
When you query the database you always have to query the lookup table to find the NAME.


Table Two Advantages:
You do not have to query the lookup table to get the NAME. (More Optimised?)

Disadvantages:
Editing a name is more difficult because all instances of that name must be located in the database and changed.


Which of these is better in your opinion?
Does creating tables in the second example actually speed up queries at all? (I guess this may depend on the table size.)

Thanks

Dave

Tom Kyte
January 14, 2004 - 3:39 pm UTC

primary keys should be immutable.

if the "name" column can change - your version #1 is right

if the "name" column cannot change ever - version #2 is right

Lookup table vs. Enums at Java Class Level

G Y, October 25, 2006 - 11:25 am UTC

Hi Tom:

Java dev team I am working with has decided not to use lookup tables. Instead, they argued that the Enums at the java class level give them names and that this is much more efficient and less expensive than joining a table to get a short strings. I would appreciaite your input. Thanks.

GY

Tom Kyte
October 25, 2006 - 1:57 pm UTC

how silly.

because of course, theirs is the last application and last application language to ever want to touch this data.

Very "smart" of them...

(not)

lookup tables

A reader, December 18, 2007 - 11:22 pm UTC

Tom:

What would be the biggest disadvantage in your opinion of one huge lookup table for all status codes.

Code, Fieldname, tablename, description


One person argues that since one table have so many codes and requires 10-20 lookup tables, ad hoc users find it very difficult to work with. He claims defining all the codes in one table makes it easy for them to see the description of the code. Do you agree and how do you argue against it for ad hoc queries.

2. Correct me if I am wrong but I see these disadvantages:

1. No Foreign Keys allowed.
2. If one column with set of codes exists in several tables, then you have to repeat the same values in the big lookup table for each. This is duplicated data while if you have one small table you can link all of those columns to it and know what the value is. Correct.

3. I am not sure about this but would not there be a problem in looking up two codes in one table from the lookup table when you do the join.

4. The one table solution is not scalable. E.g if you need an expiration status on some codes or trying to find states that belong to USA.

thanks
Tom Kyte
December 19, 2007 - 10:01 am UTC

ad hoc users should use views then - shouldn't they.


The problems - one table, no correct datatypes - you'd use a string, of a fixed size - regardless - for all lookups.

You would not have referential integrity - because the primary key of your lookup table would be (code, fieldname,tablename) and I doubt you would put code,fieldname,tablename in your fact tables would you. so data integrity = NOT THERE (please don't tell me the application will do it, the application cannot do it without locking tables and tell me the last time you saw a program with the lock table command in it....)

You would negatively affect the optimizer, especially if some table/fields had LOTS of entries and others did not.



And you know, you'd end up having to join to this single table over and over. Let us go back to the original "argument"


...
One person argues that since one table have so many codes and requires 10-20
lookup tables, ad hoc users find it very difficult to work with.
.......


Let's see, they would have to

select a.description, b.description, c.description, t.*
  from T, lookup A, lookup B, lookup C
 where t.field1 = a.code and a.fieldname = 'FIELD1' and a.tablename = 'T'
   and t.field2 = b.code and b.fieldname = 'FIELD2' and b.tablename = 'T'
   and t.field3 = c.code and c.fieldname = 'FIELD2' and c.tablename = 'T'


and for some reason they believe that is EASIER, more understandable, better for these poor ad-hoc users than:


select a.description, b.description, c.description, t.*
  from t, field1_lookup a, field2_lookup b, field3_lookup c
 where t.field1 = a.code 
   and t.field2 = b.code 
   and t.field3 = c.code;


I'm not so sure I agree it would be easier - the end user would still have to know

a) fieldname (duh)
b) tablename (duh duh - they are quering the table!)

and heck, they'd even have METADATA (eg: the data dictionary) to tell them WHAT TO DO - so their little ad-hoc query tools would probably actually form the JOIN (if you use separate tables) whereas if you use a single table, these tools would form BAD JOINS if ANY


Meaning: I see no advatanges, I see only glaring disadvantages - and the perceived advantage stated by this person is actually a huge disadvantage.



lookup

A reader, December 19, 2007 - 9:33 pm UTC

Tom:

very convincing facts. You sure convinced everyone.

Did you mean to define the codes in Oracle data dictionary? What view would the ad hoc user use for that?

Do you always let ad hoc users use views instead of tables?
Tom Kyte
December 20, 2007 - 9:58 am UTC

look at the data dictionary - they use VIEWS that present the end user (us) with meaningful stuff.

we query all_objects

we do not query the myriad of tables, that are joined in arcane manners with many tables.

we query all_objects - which uses JOINS and many times decode's to resolve lookups.


You present to ad-hoc users, which are typically not the most SQL proficient people, end user layers which provide them a good, documented start.

codes

A reader, December 20, 2007 - 6:20 pm UTC

Tom:

OK we will use views. But ad hoc is supposed to let a user create any query he wishes. How do you know what Views to create. DO you create a view per table or per several tables or you have to collect ad hoc requirements before creating anything.

Also, if TABLE_T has many coded columns, how do you show ad hoc users the meaning of each code using a view. Do you define it in the column description and then use some kind of view to display it or you join TABLE_T with all the lookup tables to present the actual description instead of the code.

Thanks
Tom Kyte
December 21, 2007 - 2:42 pm UTC

you don't have to use views.

But then your ad-hoc users will have to join themselves

*NO MATTER WHAT*

one lookup or not.

I say with many lookups, their life is better
with a single lookup - their life is miserable.


You present to the end user something that would make their life better. You tell me if you are going to create a view per table or several tables - what will satisfy their needs best.


I don't get your last paragraph. What do you mean "show ad hoc users the meaning of each code using a view"

Let me turn that around on you - how would you do this (whatever this is) without a view?


Look at the data dictionary - it does this, it gives somewhat descriptive values in columns - when you query all_tab_columns - you see datatype names, NOT data type codes (we store codes, you see names). You see table_names, not OBJ# (we use a number, you don't). You see column_names - not .... you get the picture.

what do your end users want, if you don't know, you need to talk to them and find that out.

ad hoc

A reader, December 28, 2007 - 9:52 pm UTC

Tom:

What i meant by how to show them codes if you have a table:

Table_T
--------
Order_No
Order_Status_Code
customer_type_code

Each column has a set of coded values. How would the user know what each code means. Do I create a view to join this with a lookup table or you define the codes in the data dictionary.
Tom Kyte
January 01, 2008 - 5:27 pm UTC

you do whatever you want to present the data to whomever needs it in the format that works best for them?

I don't know what "defining codes in the data dictionary" means.


But, if you have a code in order_status_code like 'A', 'B', 'C' and that really means "Open", "closed", "back ordered", you would either

a) join to pick that up from the lookup table
b) use decode/case to present that information in a VIEW (we do that in our dictionary views - we have big decodes on lookups that are not volatile - so we don't have to join, the view just decodes the status)

master

A reader, January 02, 2008 - 1:08 pm UTC

Tom:

Yes, the only issue with decode over a join is that if you added/deleted a code or changed a description. You have to edit all the statements/views.

I was thinking to add the code descriptions in the "Column defintion" as a metadata. User can do the whatever he wants. is that bad idea?
Tom Kyte
January 02, 2008 - 3:20 pm UTC

that is sort of obvious - but works in the case where you use a check constraint nicely - and can work just as nicely in any controlled environment where you maintain your code table and your views using source code control/some configuration management tool. It is just an option, and the side effect is rather obvious.

Do what you want that best accomplishes your goal - a lookup table, a decode, a case statement, a check constraint - you make the call.