SitePoint Sponsor

User Tag List

Results 1 to 7 of 7

Thread: DB design - keeping track of revision history

  1. #1
    Barefoot on the Moon! silver trophy
    Force Flow's Avatar
    Join Date
    Jul 2003
    Location
    Northeastern USA
    Posts
    3,659
    Mentioned
    21 Post(s)
    Tagged
    1 Thread(s)

    DB design - keeping track of revision history

    I'm building a database where a portion of it keeps track of revision history of stored data. However, I'm at a sticking point. The example below has been watered down to show the problem area.

    Here's the diagram:


    Here's the SQL:
    Code SQL:
    SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
    SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
    SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL';
     
    CREATE SCHEMA IF NOT EXISTS `mydb` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci ;
    USE `mydb` ;
     
    -- -----------------------------------------------------
    -- Table `mydb`.`entry`
    -- -----------------------------------------------------
    CREATE  TABLE IF NOT EXISTS `mydb`.`entry` (
      `entry_id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT ,
      `history_id` BIGINT UNSIGNED NOT NULL ,
      PRIMARY KEY (`entry_id`) ,
      INDEX `fk_entry_entry_data` (`history_id` ASC) ,
      CONSTRAINT `fk_entry_entry_data`
        FOREIGN KEY (`history_id` )
        REFERENCES `mydb`.`entry_data` (`history_id` )
        ON DELETE NO ACTION
        ON UPDATE NO ACTION)
    ENGINE = InnoDB;
     
     
    -- -----------------------------------------------------
    -- Table `mydb`.`entry_data`
    -- -----------------------------------------------------
    CREATE  TABLE IF NOT EXISTS `mydb`.`entry_data` (
      `history_id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT ,
      `entry_id` BIGINT UNSIGNED NOT NULL ,
      `data1` VARCHAR(45) NULL ,
      `data2` VARCHAR(45) NULL ,
      `data3` VARCHAR(45) NULL ,
      PRIMARY KEY (`history_id`) ,
      INDEX `fk_entry_data_entry1` (`entry_id` ASC) ,
      CONSTRAINT `fk_entry_data_entry1`
        FOREIGN KEY (`entry_id` )
        REFERENCES `mydb`.`entry` (`entry_id` )
        ON DELETE NO ACTION
        ON UPDATE NO ACTION)
    ENGINE = InnoDB;
     
     
    -- -----------------------------------------------------
    -- Table `mydb`.`log`
    -- -----------------------------------------------------
    CREATE  TABLE IF NOT EXISTS `mydb`.`log` (
      `log_id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT ,
      `longIP` VARCHAR(64) NULL ,
      `os` VARCHAR(45) NULL ,
      `browser_agent` VARCHAR(255) NULL ,
      PRIMARY KEY (`log_id`) )
    ENGINE = InnoDB;
     
     
    -- -----------------------------------------------------
    -- Table `mydb`.`entry_logs`
    -- -----------------------------------------------------
    CREATE  TABLE IF NOT EXISTS `mydb`.`entry_logs` (
      `entry_id` BIGINT UNSIGNED NOT NULL ,
      `log_id` BIGINT UNSIGNED NOT NULL ,
      PRIMARY KEY (`entry_id`, `log_id`) ,
      INDEX `fk_entry_logs_log1` (`log_id` ASC) ,
      CONSTRAINT `fk_entry_logs_entry1`
        FOREIGN KEY (`entry_id` )
        REFERENCES `mydb`.`entry` (`entry_id` )
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `fk_entry_logs_log1`
        FOREIGN KEY (`log_id` )
        REFERENCES `mydb`.`log` (`log_id` )
        ON DELETE NO ACTION
        ON UPDATE NO ACTION)
    ENGINE = InnoDB;
     
     
     
    SET SQL_MODE=@OLD_SQL_MODE;
    SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
    SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;

    Basically, in the "entry" table, both IDs *should* be primary keys, in order to have multiple "history_id"'s for each "entry_id". However, when I do that, then I'll have to reference both columns in the "entry_logs" table, when all I need for that is the "entry_id".

    How would I get around needing to reference "entry_id" and "history_id" when all I really need from other tables is just the "entry_id"?
    Visit The Blog | Follow On Twitter
    301tool 1.1.5 - URL redirector & shortener (PHP/MySQL)
    Can be hosted on and utilize your own domain

  2. #2
    SQL Consultant silver trophybronze trophy
    SitePoint Award Recipient r937's Avatar
    Join Date
    Jul 2002
    Location
    Toronto, Canada
    Posts
    38,463
    Mentioned
    35 Post(s)
    Tagged
    1 Thread(s)
    could you please explain your keys on each table? both primary and foreign

    i just can't wrap my head around the entry and entry_data tables referencing each other with foreign keys

    not without help

    r937.com | rudy.ca | Buy my SitePoint book: Simply SQL
    "giving out my real stuffs"

  3. #3
    Barefoot on the Moon! silver trophy
    Force Flow's Avatar
    Join Date
    Jul 2003
    Location
    Northeastern USA
    Posts
    3,659
    Mentioned
    21 Post(s)
    Tagged
    1 Thread(s)


    Does that help?

    entry_id is an auto-incrementing PK of `entry`
    history_id is an auto-incrementing PK of `entry_data`

    The other two tables are there just for reference to show how I'd like to use the "entry_id" as a FK in other tables.


    Now that I think of it, would it be more appropriate to go with a 3-table layout like this instead?

    Visit The Blog | Follow On Twitter
    301tool 1.1.5 - URL redirector & shortener (PHP/MySQL)
    Can be hosted on and utilize your own domain

  4. #4
    SQL Consultant silver trophybronze trophy
    SitePoint Award Recipient r937's Avatar
    Join Date
    Jul 2002
    Location
    Toronto, Canada
    Posts
    38,463
    Mentioned
    35 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by Force Flow View Post
    Now that I think of it, would it be more appropriate to go with a 3-table layout like this instead?
    that makes ~way~ more sense to me

    r937.com | rudy.ca | Buy my SitePoint book: Simply SQL
    "giving out my real stuffs"

  5. #5
    Barefoot on the Moon! silver trophy
    Force Flow's Avatar
    Join Date
    Jul 2003
    Location
    Northeastern USA
    Posts
    3,659
    Mentioned
    21 Post(s)
    Tagged
    1 Thread(s)
    Is it the best approach, though? To me, it seems a bit silly to have a table with only one column in it.
    Visit The Blog | Follow On Twitter
    301tool 1.1.5 - URL redirector & shortener (PHP/MySQL)
    Can be hosted on and utilize your own domain

  6. #6
    SQL Consultant silver trophybronze trophy
    SitePoint Award Recipient r937's Avatar
    Join Date
    Jul 2002
    Location
    Toronto, Canada
    Posts
    38,463
    Mentioned
    35 Post(s)
    Tagged
    1 Thread(s)
    i guess that depends

    you never did explain what any of that stuff means

    what's a history? what's an entry? why ~doesn't~ an entry have any data attributes?
    r937.com | rudy.ca | Buy my SitePoint book: Simply SQL
    "giving out my real stuffs"

  7. #7
    Barefoot on the Moon! silver trophy
    Force Flow's Avatar
    Join Date
    Jul 2003
    Location
    Northeastern USA
    Posts
    3,659
    Mentioned
    21 Post(s)
    Tagged
    1 Thread(s)
    I made the example fairly generic.

    Ok, so there's the "entry_data" table, which has all the data for a particular record. Normally, that would've contained the "entry_id" PK and would've been a table all by itself. However, I wanted to keep a history of revisions of the "entry_data" table. So if a user wanted to see who changed what, or wanted to revert back to an older revision of the data, they could.
    Visit The Blog | Follow On Twitter
    301tool 1.1.5 - URL redirector & shortener (PHP/MySQL)
    Can be hosted on and utilize your own domain

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •