SV: Inhomogeneous data in a database

2015-04-11 Thread Tommi Helander
Hi Alex,

Without going into details about your data model in general, then in your case 
I would probably create two different navigation tables: one for html and one 
for scripts. Then I would be able to create reliable foreign key constraints. 
Then, if I wanted a convenient way of selecting all kinds of navigation records 
from Perl, I would create a view that combines the different kinds of 
navigation tables and contain the kind of type field and id field that you 
suggested. You see, this would make it possible to assign constraints on the 
underlying data model, without complicating the way it's selected.

On the other hand, I usually work with larger databases and more complex data 
models, so this might be a little overkill in your case. But anyway, this what 
I consider good practice. Others may have different opinions.

Hope this helps!

Best regards,
Tommi

Från: Alex Beckermailto:asb.c...@gmail.com
Skickat: ‎10.‎4.‎2015 23:56
Till: Andrew Solomonmailto:and...@geekuni.com
Kopia: beginners@perl.orgmailto:beginners@perl.org
Ämne: Re: Inhomogeneous data in a database

Hi Andrew,

I'm not interested in ways how to get the data out of the database. I'm
usually using DBIx::CLass because I'm too lazy to write SQL.

To provide you an example of a table and the question I have, I did it
anyway :). This would be the example case:

#!perl

use strict;
use warnings;
use DBI;
use DBD::SQLite;

my $db_file = 'test.sqlite';
unlink $db_file if -e $db_file;

my $dbh = DBI-connect(dbi:SQLite:dbname=$db_file, '', '') or die(Could
not connect to database $db_file);

my @stmts = (
q~CREATE TABLE html_contents (
content_id INTEGER PRIMARY KEY NOT NULL,
title varchar(255) NOT NULL,
html TEXT NOT NULL
);~,
q~CREATE TABLE fancy_scripts (
script_id INTEGER PRIMARY KEY NOT NULL,
perl_module varchar(255) NOT NULL
);~,
q~CREATE TABLE navigation (
navigation_id INTEGER PRIMARY KEY NOT NULL,
position INTEGER UNIQUE NOT NULL,
link_text carchar(45) NOT NULL,
target_type varchar(45) NOT NULL,
target_id INT NOT NULL
);~,
q~INSERT INTO html_contents VALUES (1, Title1, htmlbodyh1Start
Page/h1/body/html)~,
q~INSERT INTO html_contents VALUES (2, Title n, htmlbodyh1This
is Mario!/h1/body/html)~,
q~INSERT INTO fancy_scripts VALUES (1, CMS::FancyScript)~,
q~INSERT INTO fancy_scripts VALUES (2, CMS::Guestbook)~,
q~INSERT INTO navigation VALUES (1, 1, Home, html_contents, 1)~,
q~INSERT INTO navigation VALUES (2, 3, About Me, html_contents, 2)~,
q~INSERT INTO navigation VALUES (3, 2, Contact, fancy_scripts, 1)~,
);

foreach my $sql ( @stmts ) {
$dbh-do($sql) or die(Something bad happened doing SQL:  .
$dbh-errstr);
}

print  done\n;
exit(0);


The issue is:
Usually, when reading articles about database normalization, everyone talks
about putting information into separate tables and referencing them (e.g.
using foreign keys).
I did so. Every information has a dedicated table (except for the
target_type column for the sake of example simplicity).

But the value of the target_id column cannot be defined as a foreign key.
Because it might be an ID of the table fancy_scripts or one of the table
html_contents. I know which table to use depending on the value of
target_type.

I even could create 2 views to denormalize the tables for fast access. One
view would reflect the navigation links for fancy scripts, and one would
reflect the navigation links for html contents.

But: usually, when fetching a navigation structure of some kind, you fetch
*all* the links.

It can be done. I can code it the way I want it to work.
But I'm *not sure* if it is the right thing to do (and no, I don't really
want to start a discussion about TIMTOWTDI, Perl's philosophy, why Pyhton
wuld be better for this approach, or what people think about this
particular sentence in general).

Maybe I can rephrase my inital questions:

 Is there a standard approach for this kind of database table construct?
Is it the right thing to do?

 A coding recommendation?
Is there a best practice?

 Or am I doing it completely wrong?
Should I store the information in another fashion?

Thanks for your answers  best regards,
Alex

2015-04-10 21:51 GMT+02:00 Andrew Solomon and...@geekuni.com:

 Hi Alex

 Maybe you could give us a bit more info on the `html_contents` and
 `fancy_scripts` tables, because my inclination would be just to have a
 simple `contents` table.

 This table would have three fields: (`id,`content_type`, `blob`) where:
 * `content_type` is HTML, CGI or Module (or rather, ids pointing to
 the `target_type` table);
 * `blob` is a base64 encoding of a structure containing both the data
 (HTML, CGI or module) and any metadata such as URL parameters, class
 attributes etc.

 I would then be using DBIx::Class to access the table and have methods on
 the Schema to decode and make use of `blob` appropriately 

Re: Inhomogeneous data in a database

2015-04-11 Thread Andrew Solomon
Hi Alex

Another option: replace `(navigation.target_type, navigation.target_id)`
with `(navigation.html_target_id, navigation.fancyscript_target_id)` only
one of which is defined for any given row, but both of which have foreign
key constraints when they are defined.

In answer to a subset of your questions:

 Is there a standard approach for this kind of database table construct?

Not that I'm aware of.

 Is there a best practice?

I think this discussion responds to that question.

http://dba.stackexchange.com/questions/15388/where-should-you-define-foreign-keys

As you'll see from the responses, the context of an application has a major
influence on the decision made.

I hope that helps!

Andrew


On Sat, Apr 11, 2015 at 8:17 AM, Tommi Helander tommi.helan...@outlook.com
wrote:

  Hi Alex,

 Without going into details about your data model in general, then in your
 case I would probably create two different navigation tables: one for html
 and one for scripts. Then I would be able to create reliable foreign key
 constraints. Then, if I wanted a convenient way of selecting all kinds of
 navigation records from Perl, I would create a view that combines the
 different kinds of navigation tables and contain the kind of type field and
 id field that you suggested. You see, this would make it possible to assign
 constraints on the underlying data model, without complicating the way it's
 selected.

 On the other hand, I usually work with larger databases and more complex
 data models, so this might be a little overkill in your case. But anyway,
 this what I consider good practice. Others may have different opinions.

 Hope this helps!

 Best regards,
 Tommi
  --
 Från: Alex Becker asb.c...@gmail.com
 Skickat: ‎10.‎4.‎2015 23:56
 Till: Andrew Solomon and...@geekuni.com
 Kopia: beginners@perl.org
 Ämne: Re: Inhomogeneous data in a database

Hi Andrew,

  I'm not interested in ways how to get the data out of the database. I'm
 usually using DBIx::CLass because I'm too lazy to write SQL.

  To provide you an example of a table and the question I have, I did it
 anyway :). This would be the example case:

 #!perl

 use strict;
 use warnings;
 use DBI;
 use DBD::SQLite;

 my $db_file = 'test.sqlite';
 unlink $db_file if -e $db_file;

 my $dbh = DBI-connect(dbi:SQLite:dbname=$db_file, '', '') or die(Could
 not connect to database $db_file);

 my @stmts = (
 q~CREATE TABLE html_contents (
 content_id INTEGER PRIMARY KEY NOT NULL,
 title varchar(255) NOT NULL,
 html TEXT NOT NULL
 );~,
 q~CREATE TABLE fancy_scripts (
 script_id INTEGER PRIMARY KEY NOT NULL,
 perl_module varchar(255) NOT NULL
 );~,
 q~CREATE TABLE navigation (
 navigation_id INTEGER PRIMARY KEY NOT NULL,
 position INTEGER UNIQUE NOT NULL,
 link_text carchar(45) NOT NULL,
 target_type varchar(45) NOT NULL,
 target_id INT NOT NULL
 );~,
 q~INSERT INTO html_contents VALUES (1, Title1,
 htmlbodyh1Start Page/h1/body/html)~,
 q~INSERT INTO html_contents VALUES (2, Title n,
 htmlbodyh1This is Mario!/h1/body/html)~,
 q~INSERT INTO fancy_scripts VALUES (1, CMS::FancyScript)~,
 q~INSERT INTO fancy_scripts VALUES (2, CMS::Guestbook)~,
 q~INSERT INTO navigation VALUES (1, 1, Home, html_contents, 1)~,
 q~INSERT INTO navigation VALUES (2, 3, About Me, html_contents,
 2)~,
 q~INSERT INTO navigation VALUES (3, 2, Contact, fancy_scripts, 1)~,
 );

 foreach my $sql ( @stmts ) {
 $dbh-do($sql) or die(Something bad happened doing SQL:  .
 $dbh-errstr);
 }

 print  done\n;
 exit(0);


  The issue is:
  Usually, when reading articles about database normalization, everyone
 talks about putting information into separate tables and referencing them
 (e.g. using foreign keys).
  I did so. Every information has a dedicated table (except for the
 target_type column for the sake of example simplicity).

  But the value of the target_id column cannot be defined as a foreign key.
 Because it might be an ID of the table fancy_scripts or one of the table
 html_contents. I know which table to use depending on the value of
 target_type.

 I even could create 2 views to denormalize the tables for fast access. One
 view would reflect the navigation links for fancy scripts, and one would
 reflect the navigation links for html contents.

 But: usually, when fetching a navigation structure of some kind, you fetch
 *all* the links.

  It can be done. I can code it the way I want it to work.
  But I'm *not sure* if it is the right thing to do (and no, I don't really
 want to start a discussion about TIMTOWTDI, Perl's philosophy, why Pyhton
 wuld be better for this approach, or what people think about this
 particular sentence in general).

  Maybe I can rephrase my inital questions:

  Is there a standard approach for this kind of database table construct?
  Is it the right thing to do?

  A coding recommendation?
 Is 

Need explanation of code

2015-04-11 Thread SSC_perl
Could someone please explain the difference between:

%{$self-{'DATA'}} = () }

and

$self-{'DATA'} = {}

I was told that they are equivalent, but they're not.  One works and 
the other doesn't, so they must be different.  Here's the context:



sub empty_db {
my $self = shift;
if ($self-{'USEDBM'} eq 'sql') {
$self-{'SQL'}-do(DELETE from $self-{'DB'}) or 
$self-{'ERRMSG'} .= $DBI::errstr and return;
}
else { %{$self-{'DATA'}} = () }
#   else { $self-{'DATA'} = {} }  # This does nothing
}



Thanks,
Frank


SurfShopCART 2
http://www.surfshopcart.com/u/demo


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/