gmax has written Database normalization the easier way (which resulted in DBSchema::Normalizer).

Aside from that, you gotta clarify which Normal Form you're going for. Here's how I see it (aiming for 2NF -- sure Movies aren't Episodes, but the intent is clear enough):

my $tables = q~ #A Person is independent of everything else. CREATE TABLE Person ( Id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, Name VARCHAR(255), KEY( Name ), PRIMARY KEY( Id ) ); #An Actor is a Person. #(An Actor plays Roles). CREATE TABLE Actor ( Id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, PersonId INT(11) UNSIGNED NOT NULL REFERENCES Person(Id), KEY( PersonId ), PRIMARY KEY( Id ) ); #A Director is a Person. #A Director directs Movies. #(A Director can also be an Actor). CREATE TABLE Director ( Id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, PersonId INT(11) UNSIGNED NOT NULL REFERENCES Person(Id), MovieId INT(11) UNSIGNED NOT NULL REFERENCES Movie(Id), KEY( MovieId ), KEY( PersonId ), PRIMARY KEY( Id ) ); #Roles are played by Actors. #Roles occur in Movies. #A Role is a Person. CREATE TABLE Role ( Id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, ActorId INT(11) UNSIGNED NOT NULL REFERENCES Actor(Id), MovieId INT(11) UNSIGNED NOT NULL REFERENCES Movie(Id), PersonId INT(11) UNSIGNED NOT NULL REFERENCES Person(Id), KEY( PersonId ), KEY( ActorId ), KEY( MovieId ), PRIMARY KEY( Id ) ); #A movie has a Title. #(A movie may have: Roles, Directors, Actors, Writers). CREATE TABLE Movie ( Id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, Title VARCHAR(255), PRIMARY KEY( Id ) ); ~; use strict; use warnings; use SQL::Translator; my %To = ( POD => 'pod', XML => 'xml', HTML => 'html', Raw => 'Raw', GraphViz => 'png', ClassDBI => 'pm', MySQL => 'sql', SQLite => 'sql', Oracle => 'sql', PostgreSQL => 'sql', Sybase => 'sql', ); for my $to ( sort keys %To ){ print STDERR "Translating to $to ...\n"; my $translator = SQL::Translator->new( debug => 0, # PrINT debug info trace => 0, # PrINT Parse::RecDescent trace no_comments => 1, # Don't include comments in output show_warnings => 1, # PrINT name mutations, conflicts add_drop_table => 1, # Add "drop table" statements data => \$tables, producer_args => { layout => 'dot', node_shape => 'trapezium', #plaintext diamond house }, ); my $output = $translator->translate( from => "MySQL", to => $to, ) or warn "\n\nFATAL ERROR: ", $translator->error and next; my $file = __FILE__ ."_$to.$To{$to}"; open my $fh, '>', $file or warn "Can't clobber $file : $!" && +next; binmode $fh; print {$fh} $output; close $fh; } __END__

Description of Schema

Person

Top
Field Name Data Type Size Default Other Foreign Key
Id INT 11 PRIMARY KEY, NOT NULL
Name VARCHAR 255

Indices

Name Fields
Name

Actor

Top
Field Name Data Type Size Default Other Foreign Key
Id INT 11 PRIMARY KEY, NOT NULL
PersonId INT 11 NOT NULL Person.Id

Indices

Name Fields
PersonId

Director

Top
Field Name Data Type Size Default Other Foreign Key
Id INT 11 PRIMARY KEY, NOT NULL
PersonId INT 11 NOT NULL Person.Id
MovieId INT 11 NOT NULL Movie.Id

Indices

Name Fields
MovieId
PersonId

Role

Top
Field Name Data Type Size Default Other Foreign Key
Id INT 11 PRIMARY KEY, NOT NULL
ActorId INT 11 NOT NULL Actor.Id
MovieId INT 11 NOT NULL Movie.Id
PersonId INT 11 NOT NULL Person.Id

Indices

Name Fields
PersonId
ActorId
MovieId

Movie

Top
Field Name Data Type Size Default Other Foreign Key
Id INT 11 PRIMARY KEY, NOT NULL
Title VARCHAR 255

Created by SQL::Translator

MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
** The third rule of perl club is a statement of fact: pod is sexy.


In reply to Re: Normalisation Question (OT but trust me, perl implementation) by PodMaster
in thread Normalisation Question (OT but trust me, perl implementation) by Cody Pendant

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.