Thread: Approaches for Lookup values (codes) in OLTP application
I am considering how best to handle the issue of attribute encoding for an OLTP application conversion. The existing system, which does not employ a relational DBMS in the commonly accepted sense, uses a "system_table" to validate system codes. This dataset uses concatenated fields to form a unique key. The fields are "table_name", "table_column_name", and "value_as_char". The conversion project framework is Ruby on Rails which embeds the practice of arbitrary integer primary keys assigned by sequencers rather than so-called "natural" keys or predicates that define the unique portion of the table-row. My questions revolve around how best to implement this in postgresql given the expectations of Rails. Is it best that I create a table with the three key columns and an additional id then have a unique index on the three values but store the id in the referential row? Do I store the code value in the referential row and use the implied table_name, table_column_name and stored value to preform a lookup on the system_table? Is there another approach that I am not aware of that is superior to both of these? Comments most welcome. -- *** E-Mail is NOT a SECURE channel *** James B. Byrne mailto:ByrneJB@Harte-Lyne.ca Harte & Lyne Limited http://www.harte-lyne.ca 9 Brockley Drive vox: +1 905 561 1241 Hamilton, Ontario fax: +1 905 561 0757 Canada L8E 3C3
James B. Byrne wrote: > I am considering how best to handle the issue of attribute encoding for an > OLTP application conversion. [snip] > The conversion project framework is Ruby on Rails which embeds the practice of > arbitrary integer primary keys assigned by sequencers rather than so-called > "natural" keys or predicates that define the unique portion of the table-row. I'm not a Rails guy, but everything I've read about it suggests if you're going to gain any advantage from it, then you should follow its way of doing things. That means not converting anything, but rather writing a rails app that does the same as your current app (if I'm making myself clear). -- Richard Huxton Archonet Ltd
On Fri, February 15, 2008 12:38, Richard Huxton wrote: > > I'm not a Rails guy, but everything I've read about it suggests if > you're going to gain any advantage from it, then you should follow its > way of doing things. That means not converting anything, but rather > writing a rails app that does the same as your current app (if I'm > making myself clear). Rails is "Opinionated" software but it will allow non-arbitrary keys. I realize that I am not expressing myself well but this is in large measure due to transitioning from a non-RBMS environment to relational technology and having at the same time move from a host based application to a web-based n-tier application. So, I tend to get muddled from time to time. To restate my original query in more straight-forward terms: What is considered appropriate RBMS practice to deal with encoded information which has to be validated on input? One always has the option of just putting a table of values into the application itself, but I have not found much to recommend in this approach. I can over-ride Rails assumptions and force a primary key formed by multiple columns which will have a unique index automatically created for the previously described "system_values_table". My question still hinges upon what to put into the referential table, a foreign key lookup or just the encoded value and let the application do the reference checking? Consider the example of ISO 3166 country codes. There are at least two ways to handle this: 1. Have a table just for country codes and have the code the primary key 2. Have a systems value table having a code prefix column and the code value concatenated into a key (table_prefix = "country_codes" + table_value ="CA" for example) For something externally provided and widely used like country codes then option one is attractive and possibly the most sensible and robust solution. But consider things like transaction status codes. Perhaps an invoice transaction has five possible codes and a credit-note has only three, but one of those three is not valid for invoices. Where does one put such things? What is the generally accepted best practice? Does one construct a separate code table for every transaction type? Is it good practice to have a transaction_type table, a code_table, and a transaction_code_union table and lookup against the union? This is perhaps a very minor and basic issue for this list's audience, but I am going to live with these decisions a very long time and I would prefer to have some idea of what is considered appropriate RBMS treatment for application validation data as opposed to business state data. -- *** E-Mail is NOT a SECURE channel *** James B. Byrne mailto:ByrneJB@Harte-Lyne.ca Harte & Lyne Limited http://www.harte-lyne.ca 9 Brockley Drive vox: +1 905 561 1241 Hamilton, Ontario fax: +1 905 561 0757 Canada L8E 3C3
On Fri, Feb 15, 2008 at 12:12 PM, James B. Byrne <byrnejb@harte-lyne.ca> wrote: > > I can over-ride Rails assumptions and force a primary key formed by multiple > columns which will have a unique index automatically created for the > previously described "system_values_table". My question still hinges upon > what to put into the referential table, a foreign key lookup or just the > encoded value and let the application do the reference checking? > > Consider the example of ISO 3166 country codes. There are at least two ways > to handle this: > > 1. Have a table just for country codes and have the code the primary key > > 2. Have a systems value table having a code prefix column and the code value > concatenated into a key > (table_prefix = "country_codes" + table_value ="CA" for example) Generally speaking, I tend towards using the real value as the key and foreign key in lookup tables, but occasionally using an artificial numeric key is a better choice. If you'll generally always need to know the actual value, you should use it, because then it will be stored in the main table as well. But, if you access that value only 1 time for every 100 accesses, it will likely be faster to have it be on the other end of an int value, which usually takes up less space. > For something externally provided and widely used like country codes then > option one is attractive and possibly the most sensible and robust solution. > But consider things like transaction status codes. Perhaps an invoice > transaction has five possible codes and a credit-note has only three, but one > of those three is not valid for invoices. Where does one put such things? You could use a simple multi-part check constraint for that, or, if it needs to be more fluid than that, you could use some kind of multi-key table that points to a valid tx type list on a 1 to many basis, and when you insert you FK check the two values against that table.
On Feb 15, 2008, at 1:43 PM, Scott Marlowe wrote: > Generally speaking, I tend towards using the real value as the key and > foreign key in lookup tables, but occasionally using an artificial > numeric key is a better choice. Something to consider here... any table that will have either a lot of rows or a lot of "type" fields will likely be better off with a phantom key (such as a serial) rather than storing text values in the base table. As an example, we have a 500G database at work that currently doesn't use any phantom keys for this kind of thing. I recently estimated that if I normalized every field where doing so would save more than 1MB it would reduce the size of the database by 142GB. Granted, about half of that is in a somewhat unusual table that logs emails (a lot of the emails have the same text, so the gain there is from normalizing that), but even discounting that 75G is nothing to sneeze at in an OLTP database. -- Decibel!, aka Jim C. Nasby, Database Architect decibel@decibel.org Give your computer some brain candy! www.distributed.net Team #1828