Home All Groups Group Topic Archive Search About

Torn over a normalizing decision

Author
23 Sep 2005 6:34 AM
Earl
I'm still cleaning up this old app with its accompanying database. I've
found an issue that I'm really torn about whether or not to normalize.

I have a field in many of the pricing tables for the pricing method. At this
time, each pricing method simply gets a text entry from the program, i.e.,
"per unit", "per sq. ft." and so forth. But I've went through all of the
tables and discovered there are really only 8 pricing methods. I could
easily normalize this to a "PricingMethods" table, then use a foreign key to
reference the applicable pricing method.

But here's the rub. I've went thru the code, and the net effect of
normalizing this table will simply be to add about 100 JOINS to the SQL
code. Absolutely nothing will be improved -- except for the small amount of
redundant data using an actual text entry versus a FK back to a
PricingMethod table. On the other hand, complexity will certainly rise.

Thoughts, flames, etc. welcome.

Author
23 Sep 2005 6:51 AM
David Portas
It isn't obvious from your narrative why normalization would require you to
replace the PricingMethod column in the pricing tables. Couldn't you just
create PricingMethods and add a foreign key to the existing column? Or add a
CHECK to constrain the column to the 8 possible values? On the other hand if
you mean that there is a transitive dependency involved then there surely
would be a benefit in removing the column altogether.

> I have a field in many of the pricing tables

So why do you have more than one pricing table? There's apparently at least
one common attribute (pricing method) so why isn't there a common table.
Sounds like that's the real design issue.

--
David Portas
SQL Server MVP
--
Author
23 Sep 2005 7:16 AM
Earl
Thanks for your response David.

The pricing program creates a custom-configured item (I'd rather not
disclose that, but the similarity is enough, so let's just say it's a PC).

Separate entities but each have pricing methods. For example, to create a
custom item, the processor costs have different pricing methods depending
upon which manufacturer they come from (for example, Intel has different
pricing methods than AMD ). Ditto for the case, etc.

The CHECK constrain is a good idea :=)

Show quote
"David Portas" <REMOVE_BEFORE_REPLYING_dpor***@acm.org> wrote in message
news:q4udnRuu08PqO67eRVn-1g@giganews.com...
> It isn't obvious from your narrative why normalization would require you
> to replace the PricingMethod column in the pricing tables. Couldn't you
> just create PricingMethods and add a foreign key to the existing column?
> Or add a CHECK to constrain the column to the 8 possible values? On the
> other hand if you mean that there is a transitive dependency involved then
> there surely would be a benefit in removing the column altogether.
>
>> I have a field in many of the pricing tables
>
> So why do you have more than one pricing table? There's apparently at
> least one common attribute (pricing method) so why isn't there a common
> table. Sounds like that's the real design issue.
>
> --
> David Portas
> SQL Server MVP
> --
>
>
Author
23 Sep 2005 7:30 AM
David Portas
None of what you have said explains why there is more than one pricing table
with the same column(s)...

Glad I helped anyway.

--
David Portas
SQL Server MVP
--
Author
23 Sep 2005 8:56 AM
Earl
Well, I'll try again ...

Using our PC analogy, a laptop uses different components than our desktops.
Our desktop doesn't have a screen attached to it for example, but our laptop
will. So if we were to custom-configure a laptop, we will need our pricing
code to access the components that are required for a laptop, but if we are
making a desktop tower, we will want to access those components instead.
It's certainly true that we can create common tables for things like hard
drives and processors.

So our entity structure is:
    Computers

        Laptops
        Desktops
        PDAs
        etc.

            consisting of components:
            Hard drives
            Cases
            Processors
            Screens

screens have various characterisics such as size, whether LCD, pixels, etc.,
but they are based upon first of all, whether the computer is a laptop, so
our table might look like this:
                ScreenID     ComputerTypeID(FK)    ScreenType
ScreenPixels    Cost    PricingMethod

now processors have fans and heat sinks, custom-made by processor size and
manufacturer, so here might be a sample heat sink table:
                HeatSinkID    ProcessorID(FK)    HeatSink    Cost
PricingMethod

Now I see no way -- despite the fact that they both have two common
columns --   that these tables can be combined.


Show quote
"David Portas" <REMOVE_BEFORE_REPLYING_dpor***@acm.org> wrote in message
news:uhroyDBwFHA.2312@TK2MSFTNGP14.phx.gbl...
> None of what you have said explains why there is more than one pricing
> table with the same column(s)...
>
> Glad I helped anyway.
>
> --
> David Portas
> SQL Server MVP
> --
>
>
Author
23 Sep 2005 9:34 AM
David Portas
See the following example. You may or may not need "component_type"
depending on whether part_no is to be unique across all types or not.

Try not to split attributes across tables. Your code will be much
simpler if you keep them in one place only.

CREATE TABLE components (part_no INTEGER NOT NULL PRIMARY KEY,
component_type CHAR(1) NOT NULL CHECK (component_type IN ('S','H' /*
.... */)), cost NUMERIC(10,2) NOT NULL, pricing_method VARCHAR(10) NOT
NULL /* CHECK (pricing_method IN (...)) */, UNIQUE (component_type,
part_no)) ;

CREATE TABLE screens (part_no INTEGER NOT NULL PRIMARY KEY,
component_type CHAR(1) DEFAULT 'D' NOT NULL CHECK (component_type
='S'), screen_pixels INTEGER NOT NULL, FOREIGN KEY (component_type,
part_no) REFERENCES components (component_type, part_no)) ;

CREATE TABLE heat_sinks (part_no INTEGER NOT NULL PRIMARY KEY,
component_type CHAR(1) DEFAULT 'D' NOT NULL CHECK (component_type
='S'), processor_id INTEGER NOT NULL /* REFERENCES processors
(processor_id) */, FOREIGN KEY (component_type, part_no) REFERENCES
components (component_type, part_no)) ;

--
David Portas
SQL Server MVP
--
Author
23 Sep 2005 9:36 AM
David Portas
Oops. My constraints got a bit confused. Here's a correction:

CREATE TABLE components (part_no INTEGER NOT NULL PRIMARY KEY,
component_type CHAR(1) NOT NULL CHECK (component_type IN ('S','H' /*
.... */)), cost NUMERIC(10,2) NOT NULL, pricing_method VARCHAR(10) NOT
NULL /* CHECK (pricing_method IN (...)) */, UNIQUE (component_type,
part_no)) ;

CREATE TABLE screens (part_no INTEGER NOT NULL PRIMARY KEY,
component_type CHAR(1) DEFAULT 'S' NOT NULL CHECK (component_type
='S'), screen_pixels INTEGER NOT NULL, FOREIGN KEY (component_type,
part_no) REFERENCES components (component_type, part_no)) ;

CREATE TABLE heat_sinks (part_no INTEGER NOT NULL PRIMARY KEY,
component_type CHAR(1) DEFAULT 'H' NOT NULL CHECK (component_type
='H'), processor_id INTEGER NOT NULL /* REFERENCES processors
(processor_id) */, FOREIGN KEY (component_type, part_no) REFERENCES
components (component_type, part_no)) ;

--
David Portas
SQL Server MVP
--
Author
23 Sep 2005 8:15 PM
Earl
Thanks much for your insight and advice David. I'm going to mull this over
before I proceed further with my design.

Show quote
"David Portas" <REMOVE_BEFORE_REPLYING_dpor***@acm.org> wrote in message
news:1127468185.689279.63590@f14g2000cwb.googlegroups.com...
> Oops. My constraints got a bit confused. Here's a correction:
>
> CREATE TABLE components (part_no INTEGER NOT NULL PRIMARY KEY,
> component_type CHAR(1) NOT NULL CHECK (component_type IN ('S','H' /*
> ... */)), cost NUMERIC(10,2) NOT NULL, pricing_method VARCHAR(10) NOT
> NULL /* CHECK (pricing_method IN (...)) */, UNIQUE (component_type,
> part_no)) ;
>
> CREATE TABLE screens (part_no INTEGER NOT NULL PRIMARY KEY,
> component_type CHAR(1) DEFAULT 'S' NOT NULL CHECK (component_type
> ='S'), screen_pixels INTEGER NOT NULL, FOREIGN KEY (component_type,
> part_no) REFERENCES components (component_type, part_no)) ;
>
> CREATE TABLE heat_sinks (part_no INTEGER NOT NULL PRIMARY KEY,
> component_type CHAR(1) DEFAULT 'H' NOT NULL CHECK (component_type
> ='H'), processor_id INTEGER NOT NULL /* REFERENCES processors
> (processor_id) */, FOREIGN KEY (component_type, part_no) REFERENCES
> components (component_type, part_no)) ;
>
> --
> David Portas
> SQL Server MVP
> --
>
Author
23 Sep 2005 8:45 PM
Earl
I think what troubles me is the fanout of attributes for the lower level
components. I was only using the PC as an analogy -- in this particular
case, a particular component may have 100 different patterns for a
particular option, with individual pricing for each pattern. So it seems to
me that you have to have a "pattern pricing" table also.

Show quote
"David Portas" <REMOVE_BEFORE_REPLYING_dpor***@acm.org> wrote in message
news:1127468185.689279.63590@f14g2000cwb.googlegroups.com...
> Oops. My constraints got a bit confused. Here's a correction:
>
> CREATE TABLE components (part_no INTEGER NOT NULL PRIMARY KEY,
> component_type CHAR(1) NOT NULL CHECK (component_type IN ('S','H' /*
> ... */)), cost NUMERIC(10,2) NOT NULL, pricing_method VARCHAR(10) NOT
> NULL /* CHECK (pricing_method IN (...)) */, UNIQUE (component_type,
> part_no)) ;
>
> CREATE TABLE screens (part_no INTEGER NOT NULL PRIMARY KEY,
> component_type CHAR(1) DEFAULT 'S' NOT NULL CHECK (component_type
> ='S'), screen_pixels INTEGER NOT NULL, FOREIGN KEY (component_type,
> part_no) REFERENCES components (component_type, part_no)) ;
>
> CREATE TABLE heat_sinks (part_no INTEGER NOT NULL PRIMARY KEY,
> component_type CHAR(1) DEFAULT 'H' NOT NULL CHECK (component_type
> ='H'), processor_id INTEGER NOT NULL /* REFERENCES processors
> (processor_id) */, FOREIGN KEY (component_type, part_no) REFERENCES
> components (component_type, part_no)) ;
>
> --
> David Portas
> SQL Server MVP
> --
>
Author
23 Sep 2005 6:59 AM
Jose G. de Jesus Jr MCP, MCDBA
hi earl,

use an view instead of joins.
have an instead of update,insert and
delete triggers on the view

In that way you can normalize without affecting the front end

--
thanks,

------------------------------------
Jose de Jesus Jr. Mcp,Mcdba
Data Architect
Sykes Asia (Manila philippines)
MCP #2324787


Show quote
"Earl" wrote:

> I'm still cleaning up this old app with its accompanying database. I've
> found an issue that I'm really torn about whether or not to normalize.
>
> I have a field in many of the pricing tables for the pricing method. At this
> time, each pricing method simply gets a text entry from the program, i.e.,
> "per unit", "per sq. ft." and so forth. But I've went through all of the
> tables and discovered there are really only 8 pricing methods. I could
> easily normalize this to a "PricingMethods" table, then use a foreign key to
> reference the applicable pricing method.
>
> But here's the rub. I've went thru the code, and the net effect of
> normalizing this table will simply be to add about 100 JOINS to the SQL
> code. Absolutely nothing will be improved -- except for the small amount of
> redundant data using an actual text entry versus a FK back to a
> PricingMethod table. On the other hand, complexity will certainly rise.
>
> Thoughts, flames, etc. welcome.
>
>
>
Author
23 Sep 2005 7:17 AM
Earl
Thanks Jose, I will look into that approach.

Show quote
"Jose G. de Jesus Jr MCP, MCDBA" <Email me> wrote in message
news:B3535F3E-CB72-4F4B-95A9-6A17E8AF6403@microsoft.com...
> hi earl,
>
> use an view instead of joins.
> have an instead of update,insert and
> delete triggers on the view
>
> In that way you can normalize without affecting the front end
>
> --
> thanks,
>
> ------------------------------------
> Jose de Jesus Jr. Mcp,Mcdba
> Data Architect
> Sykes Asia (Manila philippines)
> MCP #2324787
>
>
> "Earl" wrote:
>
>> I'm still cleaning up this old app with its accompanying database. I've
>> found an issue that I'm really torn about whether or not to normalize.
>>
>> I have a field in many of the pricing tables for the pricing method. At
>> this
>> time, each pricing method simply gets a text entry from the program,
>> i.e.,
>> "per unit", "per sq. ft." and so forth. But I've went through all of the
>> tables and discovered there are really only 8 pricing methods. I could
>> easily normalize this to a "PricingMethods" table, then use a foreign key
>> to
>> reference the applicable pricing method.
>>
>> But here's the rub. I've went thru the code, and the net effect of
>> normalizing this table will simply be to add about 100 JOINS to the SQL
>> code. Absolutely nothing will be improved -- except for the small amount
>> of
>> redundant data using an actual text entry versus a FK back to a
>> PricingMethod table. On the other hand, complexity will certainly rise.
>>
>> Thoughts, flames, etc. welcome.
>>
>>
>>
Author
25 Sep 2005 2:07 AM
--CELKO--
Get a copy of TREES & HIERARCHIES IN SQL and look at some of the parts
explosion models.

AddThis Social Bookmark Button