Как правильно организовать исторические данные в одной таблице? - PullRequest
0 голосов
/ 01 мая 2018

Основная организация и проблема

Я работаю над базой данных 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: содержит все рейтинговые позиции каждой команды, участвующей в конкретном соревновании.

Схема базы данных такая (у меня недостаточно представителя для отображения нужного вам изображения, нажмите на ссылку):

введите описание изображения здесь

Код базы данных

-- -----------------------------------------------------
-- 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 голосов
/ 15 мая 2018

Предполагая

  • Соревнование состоит из 1 или более туров,
  • Раунд необязательно состоит из 1 или более групп.

Тогда я рекомендую

  • Одна таблица, содержащая по одной строке на «соревнование».
  • Одна таблица, содержащая одну строку за «раунд». Он должен содержать competition_id, то есть от FK до competition.id.
  • Одна таблица, содержащая по одной строке на каждую группу. Он должен содержать round_id от FK до round.id.

(Etc.)

Это примеры выполнения отображений "1: много". (Обратите внимание, что «0 или более» и «необязательно» являются просто крайними случаями «1: многие» и не требуют дополнительных усилий.)

Я говорю «одна таблица», потому что «вертикальное разделение» редко бывает ненужным. Просто поместите все атрибуты «соревнования» в одну таблицу. Когда какой-либо атрибут (например, «раунды») повторяется, он не может быть помещен в одну таблицу.

(Название таблицы competition_rounds, хотя и описательное, сбивало меня с толку.)

Смежный вопрос ... Играются ли все «раунды» «соревнования» в одной стране? Я вижу country_id в competition; Интересно, стоит ли его перемещать в rounds?

0 голосов
/ 03 мая 2018

# 1. Прежде всего, я не понял использования таблицы «Competition_round», здесь вы определили эту таблицу с двумя столбцами «Competition_id» и «Round_id». В любом случае, вы определили "Competition_id" и "round_id" в таблице "leage_ranking", поэтому я предлагаю не использовать дополнительную таблицу для повторного хранения тех же данных.

# 2. Как вы упомянули, вы хотите хранить данные исторически, тогда я предполагаю, что транзакций будет меньше или не будет. Итак, я предлагаю вам нормализовать таблицу. Потому что в конце дня вы будете анализировать данные и выполнять большой объем интеллектуального анализа исторических данных, чтобы обеспечить соответствующие бизнес-ожидания.

# 3. Помимо этого, по моему опыту, это хорошая модель данных.

См. Эту ссылку для понимания шаблонов проектирования базы данных

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...