SwimDB

compet - соревнования

CREATE TABLE compet (
  compid    MEDIUMINT     UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  compname  VARCHAR(70)            NOT NULL,         /* название */
  dates     VARCHAR(70)            NOT NULL,         /* 2019-05-31,2019-06-01,2019-06-02 */
  course    ENUM('S','L','?')      NOT NULL DEFAULT '?',
  cityid    SMALLINT           DEFAULT NULL,         /* id город */
  poolid    SMALLINT           DEFAULT NULL,         /* id бас. */
  extra     VARCHAR(50)        DEFAULT NULL          /* необходимые примечания */
--
) ENGINE=MyISAM;

prot - протоколы

CREATE TABLE prot (
  resid    INT       UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  compid   MEDIUMINT UNSIGNED              NOT NULL DEFAULT '0', /* NULL, например, временно для заграничных */
  course   ENUM('S','L','?')               NOT NULL DEFAULT '?',
  gender   ENUM('M','W')                   NOT NULL,
  stroke   ENUM('FR','FL','BA','BR','IM')  NOT NULL,
  dist     ENUM('50','100','200','400','800','1500') NOT NULL,
  ord      SMALLINT UNSIGNED               NOT NULL DEFAULT '0',   /* место */
  status   ENUM(`,'DNS','EXH','DSQ')      NOT NULL DEFAULT `,
  result   VARCHAR(8)                      NOT NULL DEFAULT '',    /* время, text */
  timing   ENUM('A','S','H','?')          NOT NULL DEFAULT '?',    /* хронометраж: A - автоматический, S - полуавтоматический, H - ручной */
  swrid    SMALLINT UNSIGNED               NOT NULL DEFAULT '0',
  year     YEAR(4)                         NOT NULL DEFAULT '0000',
  lname    VARCHAR(30)                     NOT NULL,               /* фамилия (lastname) */
  fname    VARCHAR(30)                     NOT NULL,               /* имя (firstname) */
  datest   DATE                            NOT NULL DEFAULT '0000-01-01',  /* по дням или дате соревн. */
--
  KEY idx_comp (compid),                      /* выборка всех результатов одного соревнования */
  KEY idx_swr  (swrid),                       /* выборка результатов на разных дистанциях пловца(ов) */
  KEY idx_name (lname, fname),                /* в протоколах, это более важный индекс, чем по swrid */
  KEY idx_dist (stroke, dist, gender, course) /* выборка результатов для одной дистанции с разных соревновнований */
) ENGINE=MyISAM;

res - результаты

CREATE TABLE res (
  resid    INT       UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  compid   MEDIUMINT UNSIGNED              NOT NULL,
  course   ENUM('S','L','?')               NOT NULL DEFAULT '?',
  gender   ENUM('M','W')                   NOT NULL,
  stroke   ENUM('FR','FL','BA','BR','IM')  NOT NULL,
  dist     ENUM('50','100','200','400','800','1500') NOT NULL,
  swrid    SMALLINT UNSIGNED               NOT NULL DEFAULT '0',
  mstime   MEDIUMINT UNSIGNED              NOT NULL DEFAULT '0',  /* время, мс */
  timing   ENUM('A','S','H','?')          NOT NULL DEFAULT '?',   /* хронометраж: A - автоматический, S - полуавтоматический, H - ручной */
  datest   DATE DEFAULT NULL,                                     /* временно м.б. NULL т.к. есть дата соревнований */
--
  KEY idx_comp (compid)                        /* выборка всех результатов одного соревнования */
  KEY idx_swr  (swrid)                         /* выборка результатов на разных дистанциях пловца(ов) */
  KEY idx_dist (stroke, dist, gender, course)  /* выборка результатов для одной дистанции с разных соревновнований */
) ENGINE=MyISAM;

course и gender дублируются в других таблицах, но здесь присутствуют для удобства и быстроты выборок

Таблица результаты и др. информация из протокола. для естафет - надо другую таблицу

CREATE TABLE res (
  id       int          unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
  compid   mediumint(7) unsigned NOT NULL,             /* id соревнования (см. выше) */
  dat      date                  NOT NULL,
  part     enum('am','pm')       DEFAULT NULL,         /* раздел - утро/вечер, если NULL - то не имеет значения */
  course   enum('S','L')         NOT NULL,             /* вода - короткая/длинная */
  gender   enum('M','F')         NOT NULL,
  stroke   enum('FR','FL','BA','BR','IM') NOT NULL,
  dist     smallint(5)  unsigned NOT NULL,             /* дистанция, м */
  swrid    smallint(5)  unsigned DEFAULT NULL,         /* id пловца, если не найден - NULL */
  year     smallint(5)  unsigned DEFAULT NULL,         /* год рождения по протоколу! ??? */
  mstime   mediumint(8) unsigned DEFAULT NULL,         /* время, мс; NULL - дисквалификация/не_стартовал */
  ord      smallint(3)  unsigned DEFAULT NULL,         /* занятое место (по протоколу!), если NULL - см. причину в state */
  state    tinyint      unsigned DEFAULT NULL,         /* NULL - Ок, 0 - EXH, 1 - DNS, 2...N - DSQ */
  rank1    varchar(8)            DEFAULT NULL,         /* разряд до, по протоколу, если есть */
  rank2    varchar(8)            DEFAULT NULL,         /* разряд после, по протоколу, если есть */
  name     varchar(40)           DEFAULT NULL,         /* фамилия имя пловца, на всякий случай,*/
  city     varchar(40)           DEFAULT NULL,         /* город */
  club     varchar(40)           DEFAULT NULL,         /* клуб */
  fst      enum('У','О','Д','ЗС') DEFAULT NULL,        /* спортивне товариство */
  coaches  varchar(40)           DEFAULT NULL,         /* тренеры, по протоколу, если есть */
  extra    varchar(40)           DEFAULT NULL,         /* необходимые примечания, например, если есть сомнения в имени */
--
  KEY key_compet  (compid,gender,stroke,dist),         /* выборка по дистанциям для одного соревнования */
  KEY key_bestime (course,gender,stroke,dist,mstime),  /* поиск наилучшего времени всех соревнований */
  KEY key_swrtime (swrid)                              /* поиск результатов пловца */
) ENGINE=MyISAM;

FEATURES:

Строка с записью результата должна содержать:

а также, очевидно

res - future

Вся информация о заплыве пловца (на будущее, когда и организация и проведение будет через БД).

DROP TABLE IF EXISTS heat;
CREATE TABLE heat (
  id       int unsigned  NOT NULL AUTO_INCREMENT PRIMARY KEY, /* не , тк не ищем id, только для правок */
  compid   smallint(5)  unsigned NOT NULL,             /* id соревнования 2222 */
  course   enum('S','L')         NOT NULL DEFAULT 'S', /* вода - короткая/длинная */
  gender   enum('M','F','X')     NOT NULL,
  stroke   enum('FR','FL','BA','BR','IM') NOT NULL,
  dist     smallint(5)  unsigned NOT NULL,             /* дистанция, м */

  day      tinyint      unsigned NOT NULL DEFAULT '0', /* день соревнований, первый - 0 */
 ?part     enum('am','pm')       NOT NULL DEFAULT 'am',/* раздел - утро/вечер */
  eventid  tinyint      unsigned NOT NULL DEFAULT '0', /* событие в списке дня (напр, #2. 100м в/ст муж) */
  type     enum('qua','sem','fin') NOT NULL DEFAULT 'fin', /* предвар., полуфин., финальные */
  heat     tinyint      unsigned NOT NULL DEFAULT '0', /* номер заплыва для дистанции */
  lane     tinyint      unsigned NOT NULL DEFAULT '0', /* номер дорожки в заплыве */
  swrid    smallint(5)  unsigned NOT NULL DEFAULT '0', /* id пловца, команды, если эстафета */
  /* name     varchar(40)           NOT NULL,          /* временное поле - фамилия имя пловца */,
  /* msqual   mediumint(8) unsigned NOT NULL DEFAULT '0', /* время квалификации или предварительное */
  rankbef  tinyint      unsigned NOT NULL DEFAULT '0', /* rank before */
  mstime   mediumint(8)          NOT NULL DEFAULT '0', /* время, мс */
  timing   ENUM('A','S','H','?') NOT NULL DEFAULT '?', /* хронометраж: A - автоматический, S - полуавтоматический, H - ручной */
  rankaft  tinyint      unsigned NOT NULL DEFAULT '0', /* rank after */
  ordheat  tinyint               NOT NULL DEFAULT '0', /* занятое место в заплыве */
  ordevent tinyint               NOT NULL DEFAULT '0', /* общее занятое место на дистанции */
  dateup   timestamp             NOT NULL DEFAULT CURRENT_TIMESTAMP, /* время внесения записи */
--
  /* UNIQUE unq (compid,day,part,stroke,dist,swrid), * course заложен в compid, gender в swrid */
  KEY key_bestime (course,gender,stroke,dist,mstime), /* поиск наилучшего времени всех соревнований */
  KEY key_swrtime (swrid,mstime),                    /* поиск результатов пловца */
  KEY key_order   (compid,eventid,ordevent)          /* в порядке завоеванных мест */
) ENGINE=MyISAM;

Привязка к г/р в соревнованиях не нужны?

:idea: что, если

рейтинг после соревнований - один, только по времени, кто как проплыл и взрослые и дети. Но этот рейтинг можно перестроить по заданным годам (какие угодно, возможно даже М + Ж). Это прикольно, ни у кого такого рейтинга нет! И подстегнет некоторых - если девчонки будут выше пацанов (в разрядах, понятно, надо учитывать пол)

Это решает проблему, когда проводятся одни соревнования для различных годов участников 1999-2000, 2001-2002, 2003-2004

Зачем несколько протоколов? Протокол один. Интересует - рейтинг относительно годов участников - указываем год - получаем перестроенный протокол.

построение:

records - рекорды

Для построения рейтингов, информации о лучших результатах пловца на различных дистанциях…

После внесения результатов в rec надо запускать скрипт, который будет обновлять/добавлять личные рекорды пловцов в эту таблицу.

DB simple

CREATE TABLE compet (
  compid    SMALLINT      UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  compname  VARCHAR(70)            NOT NULL,         /* название */
  datstart  DATE                   NOT NULL,
  datfinish DATE                   NOT NULL,
  course    ENUM('S','L','?')      NOT NULL DEFAULT '?',
  cityid    SMALLINT           DEFAULT NULL,         /* id город */
  poolid    SMALLINT           DEFAULT NULL,         /* id бас. */
  extra     VARCHAR(50)        DEFAULT NULL,         /* необходимые примечания */
--
) ENGINE=MyISAM;

:warning: желательно, чтобы данные ENUM имели одинаковое кол-во симв., что удобно для правки и просмотра

CREATE TABLE res (
  resid    INT      UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  compid   SMALLINT UNSIGNED               NOT NULL,
  course   ENUM('S','L','?')               NOT NULL DEFAULT '?',
  gender   ENUM('M','W')                   NOT NULL,
  stroke   ENUM('FR','FL','BA','BR','IM')  NOT NULL,
  dist     ENUM('050','100','200','400','800','150') NOT NULL,
  swrid    SMALLINT UNSIGNED               NOT NULL DEFAULT '0',
  mstime   MEDIUMINT UNSIGNED              NOT NULL DEFAULT '0',  /* время, мс */
  timing   ENUM('A','S','H','?')           NOT NULL DEFAULT '?',  /* хронометраж: A - автоматический, S - полуавтоматический, H - ручной */
  datest   DATE DEFAULT NULL, /* временно м.б. NULL т.к. есть дата соревнований */
--
  KEY idx_comp (compid)                        /* выборка всех результатов одного соревнования */
  KEY idx_swr  (swrid)                         /* выборка результатов на разных дистанциях пловца(ов) */
  KEY idx_dist (stroke, dist, gender, course)  /* выборка результатов для одной дистанции с разных соревновнований */
) ENGINE=MyISAM;

course и gender дублируются в других таблицах, но здесь присутствуют для удобства и быстроты выборок

rank - нормативные нормы

Т.к. предполагает частое обращение - тип MEMORY (стр. 132).

Очищается при перезагрузке MySQL, поэтому, проверять взятием контрольного значения с заполнением, в случае очистки.

rank (memory)

Аналогична rank_st, за исключением:

ENGINE=MEMORY;

создается программно.

:warning: Хеш-индекс хорошо подходит для точной выборки из таблиц MEMORY. Это стандартный тип индекса для таблиц MEMORY. При выполнении сравнений по диапазону значений в таблицах MEMORY необходимо воспользоваться индексом с двоичным деревом. Для этого в объявлении индекса нужно добавить ключевое слово USING BTREE

PRIMARY KEY USING BTREE(id)

Принимайте во внимание соответствие типа индекса типу операции сравнения

rank_st (st - stable)

CREATE TABLE rank_st (
  id     smallint(5)  unsigned NOT NULL PRIMARY KEY,
  rid    tinyint      unsigned NOT NULL,
  course enum('S','L')         NOT NULL,
  gender enum('M','W')         NOT NULL,
  stroke enum('FR','FL','BA','BR','IM') NOT NULL,
  dist   smallint(5)  unsigned NOT NULL,
  mstime mediumint(8) unsigned NOT NULL,
  timing   ENUM('A','S','H','?') NOT NULL DEFAULT '?',  /* хронометраж: A - автоматический, S - полуавтоматический, H - ручной */

--
  KEY key_main (course,gender,stroke,dist,mstime)
) ENGINE=MyISAM;


LOCK TABLES rank_st WRITE;

INSERT INTO rank_st VALUES
(  1, 7, 'S', 'W','FRE',  50,  27000),
(  2, 6, 'S', 'W','FRE',  50,  28000),
(  3, 5, 'S', 'W','FRE',  50,  30500),
(  4, 4, 'S', 'W','FRE',  50,  34000),
(  5, 3, 'S', 'W','FRE',  50,  38000),

...

(412, 7, 'L', 'M','IMD', 400, 282000),
(413, 6, 'L', 'M','IMD', 400, 298000),
(414, 5, 'L', 'M','IMD', 400, 321000),
(415, 4, 'L', 'M','IMD', 400, 357000),
(416, 3, 'L', 'M','IMD', 400, 403000);

UNLOCK TABLES;

полная версия

short 100m FREE 1:01.08 II 2016-03-14
long 100m FREE 1:02.45 II 2015-11-29

select rid, course, stroke, dist, mstime from rank where id=234;

rid course stroke dist mstime
2 L FRE 200 211000

swrranks

История разрядов пловцов.

Можем узнать разряд пловца на конкретной дистанции, когда был установлен лучший разряд - есть действительный.

CREATE TABLE rank_st (
  id     int  unsigned NOT NULL PRIMARY KEY AUTOINCREMENT,
  datecr /* дата установления */
  rid    tinyint      unsigned NOT NULL, /* rank id*/
  course enum('S','L')         NOT NULL, /**/
  gender enum('M','W')         NOT NULL,
  dist   smallint(5)  unsigned NOT NULL,
  stroke enum('FR','FL','BA','BR','IM') NOT NULL,
  mstime mediumint(8) unsigned NOT NULL,
--
  KEY key_main (course,gender,stroke,dist,mstime)
) ENGINE=MyISAM;