如何在同一个表中正确组织历史数据?

时间:2018-05-01 10:34:09

标签: mysql sql database-design database-schema

主要组织和问题

我正在研究football个匹配的数据库,这个数据库按以下结构组织:

Country -> Competition -> Season -> Data

问题的基本问题是我不确定我的数据库架构是否正确。

解释数据结构

主要的“问题”是每个Data按特定季节分组,让我们考虑国家England

Country | Competition    | Season    |
England | Premier League | 2017/2018 |
England | Premier League | 2016/2017 |
England | Premier League | 2015/2016 |
England | Premier League | 2014/2015 |
England | Premier League | 2013/2014 |

你可以看到England有一个名为Premier League的比赛,分为5个赛季。

每个competition分为rounds,竞赛可由单个round组成,但也可由更多rounds组成。

每个round可以分为groups,这取决于竞争的类型,有些比赛不分组。

数据库结构

根据我对数据关系的解释,我配置了一个数据库结构,其中包含下表:

  1. 国家/地区:包含所有可用的国家/地区信息。
  2. 比赛:包含所有比赛详情。
  3. competition_seasons:包含所有比赛季节。
  4. competition_rounds:包含竞赛的所有轮次。
  5. competition_groups:包含所有可参加比赛的小组。
  6. league_ranking:包含参与特定比赛的每支球队的所有排名位置。
  7. 数据库架构是这样的(我没有足够的代表来显示您需要点击链接的图像):

    enter image description here

    数据库代码

    -- -----------------------------------------------------
    -- Table `mydb`.`country`
    -- -----------------------------------------------------
    CREATE TABLE IF NOT EXISTS `mydb`.`country` (
      `id` INT NOT NULL,
      `name` VARCHAR(255) NOT NULL,
      `link` VARCHAR(255) NOT NULL,
      `iso` VARCHAR(45) NOT NULL,
      PRIMARY KEY (`id`))
    ENGINE = InnoDB;
    
    -- -----------------------------------------------------
    -- Table `mydb`.`competition`
    -- -----------------------------------------------------
    CREATE TABLE IF NOT EXISTS `mydb`.`competition` (
      `id` INT NOT NULL,
      `country_id` INT NOT NULL,
      `name` VARCHAR(255) NOT NULL,
      `link` VARCHAR(255) NOT NULL,
      PRIMARY KEY (`id`),
      INDEX `id_idx` (`country_id` ASC),
      CONSTRAINT `FK_country_competition_country_id`
        FOREIGN KEY (`country_id`)
        REFERENCES `mydb`.`country` (`id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION)
    ENGINE = InnoDB;
    
    -- -----------------------------------------------------
    -- Table `mydb`.`competition_seasons`
    -- -----------------------------------------------------
    CREATE TABLE IF NOT EXISTS `mydb`.`competition_seasons` (
      `season_id` INT NOT NULL,
      `competition_id` INT NOT NULL,
      `name` VARCHAR(255) NOT NULL,
      `create_at` DATETIME NULL,
      `update_at` DATETIME NULL,
      INDEX `competition_id_idx` (`competition_id` ASC),
      PRIMARY KEY (`season_id`),
      CONSTRAINT `FK_competition_competition_seasons_competition_id`
        FOREIGN KEY (`competition_id`)
        REFERENCES `mydb`.`competition` (`id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION)
    ENGINE = InnoDB;
    
    -- -----------------------------------------------------
    -- Table `mydb`.`competition_groups`
    -- -----------------------------------------------------
    CREATE TABLE IF NOT EXISTS `mydb`.`competition_groups` (
      `group_id` INT NOT NULL,
      `competition_id` INT NOT NULL,
      `round_id` INT NOT NULL,
      INDEX `group_id_idx` (`group_id` ASC),
      INDEX `competition_id_idx` (`competition_id` ASC),
      INDEX `round_id_idx` (`round_id` ASC),
      CONSTRAINT `FK_group_competition_groups_group_id`
        FOREIGN KEY (`group_id`)
        REFERENCES `mydb`.`group` (`id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `FK_competition_competition_groups_competition_id`
        FOREIGN KEY (`competition_id`)
        REFERENCES `mydb`.`competition` (`id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `FK_round_competition_groups_round_id`
        FOREIGN KEY (`round_id`)
        REFERENCES `mydb`.`round` (`id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION)
    ENGINE = InnoDB;
    
    -- -----------------------------------------------------
    -- Table `mydb`.`competition_rounds`
    -- -----------------------------------------------------
    CREATE TABLE IF NOT EXISTS `mydb`.`competition_rounds` (
      `competition_id` INT NOT NULL,
      `round_id` INT NOT NULL,
      INDEX `competition_id_idx` (`competition_id` ASC),
      INDEX `round_id_idx` (`round_id` ASC),
      CONSTRAINT `FK_competition_competition_rounds_competition_id`
        FOREIGN KEY (`competition_id`)
        REFERENCES `mydb`.`competition` (`id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `FK_round_competition_rounds_round_id`
        FOREIGN KEY (`round_id`)
        REFERENCES `mydb`.`round` (`id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION)
    ENGINE = InnoDB;
    
    -- -----------------------------------------------------
    -- Table `mydb`.`league_ranking`
    -- -----------------------------------------------------
    CREATE TABLE IF NOT EXISTS `mydb`.`league_ranking` (
      `id` INT NOT NULL,
      `position` INT NULL,
      `team_id` INT NULL,
      `season_id` INT NULL,
      `round_id` INT NULL,
      `competition_id` INT NULL,
      `group_id` INT NULL,
      `played_matches` INT NULL,
      `wins` INT NULL,
      `draws` INT NULL,
      `losses` INT NULL,
      `goals_for` INT NULL,
      `goals_against` INT NULL,
      `goals_difference` INT NULL,
      `points` INT NULL,
      PRIMARY KEY (`id`),
      CONSTRAINT `FK_team_league_ranking_teamd_id`
        FOREIGN KEY (`id`)
        REFERENCES `mydb`.`team` (`id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `FK_round_league_ranking_round_id`
        FOREIGN KEY (`id`)
        REFERENCES `mydb`.`round` (`id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `FK_competition_league_ranking_competition_id`
        FOREIGN KEY (`id`)
        REFERENCES `mydb`.`competition` (`id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `FK_group_league_ranking_group_id`
        FOREIGN KEY (`id`)
        REFERENCES `mydb`.`group` (`id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION)
    ENGINE = InnoDB;
    

    我的数据库架构是否适用于商店历史季节?

2 个答案:

答案 0 :(得分:0)

<强>#1。首先,我没有理解&#34; competition_round&#34;表,这里你用两列&#34; competition_id&#34;定义了这个表。和&#34; round_id&#34;。无论如何,你已经定义了&#34; competition_id&#34;和&#34; round_id&#34; in&#34; leage_ranking&#34;表,所以,我建议不要再使用额外的表来存储相同的数据。

<强>#2。正如您所提到的,您希望以历史方式存储数据,那么我假设可能会有更少的事务处理。所以,我建议你对表格进行去标准化。因为当天结束时您将分析数据并对历史数据进行大量数据挖掘,以提供适当的业务预期。

<强>#3。除此之外,根据我的经验,它似乎是一个很好的数据模型。

Refer this link for understanding the database design patterns

答案 1 :(得分:0)

假设

  • 比赛由一轮或多轮组成,
  • 圆形任选地由一个或多个基团组成。

然后我推荐

  • 每个'竞赛'包含一行的一张表。
  • 每个'一轮'包含一行的一个表。它应包含competition_id,它是competition.id的FK。
  • 每个“组”包含一行的一个表。它应包含round_id,它是round.id的FK。

(等)

这些是做“1:many”映射的例子。 (注意“0或更多”和“可选”仅仅是“1:many”的边缘情况,并且不需要额外的努力。)

我说“一张桌子”因为“垂直分割”很少是不必要的。简单地将“竞争”的所有属性放在一个表中。当某些属性(例如'rounds')重复出现时,它就不能放在同一个表中。

(表名competition_rounds虽然描述性,却让我感到困惑。)

一个相关的问题......'竞赛'的所有“回合”是否都在一个国家进行?我在country_id中看到了competition;我想知道它是否应该转移到rounds