Имеются следующие отношения:
- (№ Корта, Время начала, Клиент, Продолжительность) reserves
- (Название тарифа, Член клуба, № Корта) tariffs
- (Название тарифа, Цена в час) prices
- (Клиент, ФИО, Член клуба) clients
Поскольку где-то нужно иметь однозначный список кортов, добавим сюда так же
- (№ Корта) courts
Дополнительно, поскольку сравнение чисел заведомо быстрее, чем сравнение строк, введем ‘№ Тарифа’, эквивалентный в нашей модели ‘Название тарифа’. Название сохраним там, где оно является первичным ключом (чтобы не повторяться)
Перепишем эти отношения с указанием типов и заодно используем более удобные (для СУБД) названия:
- reserves:
- idCourt :
INT UNSIGNED
- startTime :
DATETIME
- idClient :
INT UNSIGNED
- duration :
TIME
- idCourt :
- tariffs:
- idCourt :
INT UNSIGNED
- isMember :
BOOL
- idPrice :
INT UNSIGNED
- idCourt :
- prices:
- id :
INT UNSIGNED
- name :
VARCHAR(50)
- price :
DECIMAL(14,4)
- id :
- clients:
- id :
INT UNSIGNED
- name :
VARCHAR(200)
- isMember :
BOOL
- id :
- courts:
- id :
INT UNSIGNED
- id :
Жирным обозначены первичные ключи. Курсивом – внешние ключи.
Видно, что таблицы reserves и tariffs ссылаются на другие таблицы, поэтому порядок создания важен: нельзя ссылаться на несуществующие объекты.
CREATE DATABASE IF NOT EXISTS tennis CHARACTER SET UTF8;
USE tennis;
CREATE TABLE courts (
id INT UNSIGNED NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE clients (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
VARCHAR(200) NOT NULL,
name NOT NULL DEFAULT FALSE,
isMember BOOL PRIMARY KEY (id)
);
CREATE TABLE prices (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
VARCHAR(50) NOT NULL,
name DECIMAL(14,4) NOT NULL,
price PRIMARY KEY (id)
);
CREATE TABLE tariffs (
INT UNSIGNED NOT NULL,
idCourt NOT NULL,
isMember BOOL INT UNSIGNED NOT NULL,
idPrice PRIMARY KEY (idCourt, isMember),
INDEX (idCourt),
INDEX (idPrice),
FOREIGN KEY (idCourt)
REFERENCES courts (id)
ON DELETE RESTRICT -- Не позволять удалять корт, если на него завязаны тарифы
ON UPDATE CASCADE,
FOREIGN KEY (idPrice)
REFERENCES prices (id)
ON DELETE CASCADE -- При удалении тарифа, удалять так связь с кортами
ON UPDATE CASCADE
);
CREATE TABLE reserves (
INT UNSIGNED NOT NULL,
idCourt NOT NULL,
startTime DATETIME INT UNSIGNED NOT NULL,
idClient TIME NOT NULL,
duration PRIMARY KEY (idCourt , startTime),
INDEX (idCourt),
INDEX (idClient),
FOREIGN KEY (idCourt)
REFERENCES courts (id)
ON DELETE RESTRICT -- Не позволять удалять корт, если на него завязаны тарифы
ON UPDATE CASCADE,
FOREIGN KEY (idClient)
REFERENCES clients (id)
ON DELETE RESTRICT -- Не позволять удалять клиента, если у него есть резервы
ON UPDATE CASCADE
);