简体   繁体   中英

How do I track changes and store calculated content in Nermalization?

I'm trying to create a table like this:

lives_with_owner_no from    until   under_the_name
1                   1998    2002    1
3                   2002    NULL    1
2                   1997    NULL    2
3                   1850    NULL    3
3                   1999    NULL    4
2                   2002    2002    4
3                   2002    NULL    5

It's the Nermalization example , which I guess is pretty popular.

Anyway, I think I am just supposed to set up a dependency within MySQL for the from pending a change to the lives_with table or the cat_name table, and then set up a dependency between the until and from column. I figure the owner might want to come and update the cat's info, though, and override the 'from' column, so I have to use PHP? Is there any special way I should do the time stamp on the override (for example, $date = date("Ymd H:i:s"); )? How do I set up the dependency within MySQL?

I also have a column that can be generated by adding other columns together. I guess using the cat example, it would look like:

combined_family_age family_name
75                  Alley
230                 Koneko
132                 Furrdenand
1,004               Whiskers

Should I add via PHP and then input the values with a query, or should I use MySQL to manage the addition? Should I use a special engine for this, like MemoryAll?

I disagree with the nermalization example on two counts.

  1. There is no cat entity in the end. Instead, there is a relation (cat_name_no, cat_name), which in your example has the immediate consequence that you can't tell how many cats named Lara exist. This is an anomaly that can easily be avoided.
  2. The table crams two relations, lives_with_owner and under_the_name into one table. That's not a good idea, especially if the data is temporal, as it creates all kinds of nasty anomalies. Instead, you should use a table for each.

I would design this database as follows:

create table owner (id integer not null primary key, name varchar(255));
create table cat (id integer not null primary key, current_name varchar(255));
create table cat_lives_with (
  cat_id integer references cat(id),
  owner_id integer references owner(id),
  valid_from date,
  valid_to date);
create table cat_has_name (
  cat_id integer references cat(id),
  name varchar(255),
  valid_from date,
  valid_to date);

So you would have data like:

id | name 
 1 | Andrea
 2 | Sarah
 3 | Louise

id | current_name
 1 | Ada
 2 | Shelley

cat_id | owner_id | valid_from | valid_to
     1 |        1 | 1998-02-15 | 2002-08-11
     1 |        3 | 2002-08-12 | 9999-12-31
     2 |        2 | 2002-01-08 | 2001-10-23
     2 |        3 | 2002-10-24 | 9999-12-31

cat_id | name     | valid_from | valid_to
     1 | Ada      | 1998-02-15 | 9999-12-31
     2 | Shelley  | 2002-01-08 | 2001-10-23
     2 | Callisto | 2002-10-24 | 9999-12-31

I would use a finer grained date type than just year (in the nermalization example having 2002-2002 as a range can really lead to messy query syntax), so that you can ask queries like select cat_id from owner where '2000-06-02' between valid_from and valid_to . As for the question of how to deal with temporal data in the general case: there's an excellent book on the subject, "Developing Time-Oriented Database Applications in SQL" by Richard Snodgrass ( free full-text PDF distributed by Richard Snodgrass ), which i believe can even be legally downloaded as pdf, Google will help you with that.

Your other question: you can handle the combined_family_age either in sql externally, or, if that column is needed often, with a view. You shouldn't manage the content manually though, let the database calculate that for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM