Решение задания 1
Лучший способ для хранения информации о поле - использовать справочную таблицу возможных значений. Можно расширять таблицу по мере необходимости в новых значениях пола. Таким образом, в будущем получится избежать возможных проблем с определением гендерной принадлежности и, например, с процессом по смене пола. Также все-таки лучше не использовать null-значения для пола - можно указать в качестве дефолтного значение не определенного пола из справочника.
Дату рождения лучше хранить в формате DATE, например, 1970-01-01.
Если хранить дату рождения в формате TIMESTAMP (unixtime), то стоит учитывать, что TIMESTAMP имеет диапазон от «1970-01-01 00:00:01» до «2038-01-19 03:14:07» (UTC), поэтому в большинстве случаев он не подходит для даты рождения.
Можно использовать DATETIME, но тогда появляется необходимость со стороны пользователя заполнять также время рождения (что, как мне кажется, избыточно). Если такой необходимости нет - нужно использовать DATE.
Также вышеперечисленные типы данных используют различное количество памяти для хранения значений:
+------------+----------+
| DATE: | 3 bytes |
| TIMESTAMP: | 4 bytes |
| DATETIME: | 8 bytes |
+------------+----------+
CREATE TABLE db.`user` (
id INT auto_increment NOT NULL,
name varchar(100) NOT NULL,
gender_id INT DEFAULT 0 NOT NULL,
birthdate DATE NOT NULL,
CONSTRAINT user_PK PRIMARY KEY (id)
)
ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_general_ci;
CREATE TABLE db.gender (
id INT auto_increment NOT NULL,
name varchar(100) NOT NULL,
description varchar(100) NULL,
CONSTRAINT gender_PK PRIMARY KEY (id)
)
ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_general_ci;
CREATE TABLE db.phone_number (
id INT auto_increment NOT NULL,
`number` varchar(255) NOT NULL,
user_id INT NOT NULL,
CONSTRAINT phone_number_PK PRIMARY KEY (id),
)
ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_general_ci;
ALTER TABLE db.`user` ADD CONSTRAINT user_FK FOREIGN KEY (gender_id) REFERENCES db.gender(id);
ALTER TABLE db.`phone_number` ADD CONSTRAINT phone_number_FK FOREIGN KEY (user_id) REFERENCES db.`user`(id);
INSERT INTO db.gender (name,description)
VALUES ('unknown','Не определено'),
VALUES ('male','Мужчина'),
VALUES ('female','Женщина');
INSERT INTO db.`user` (name,gender_id,birthdate)
VALUES ('Yvonne Mcdowell',3,'1979-10-09'),
VALUES ('Lareina Harrington',3,'2001-03-22'),
VALUES ('Carl Espinoza',2,'1999-01-01'),
VALUES ('Mallory Buck',3,'2002-12-02'),
VALUES ('Althea Morton',3,'2001-09-17'),
VALUES ('Shannon Fry',3,'1992-07-12'),
VALUES ('Chaim Rogers',2,'2002-11-11'),
VALUES ('Rachel Payne',3,'2001-08-13'),
VALUES ('Matthew Casey',2,'2000-10-25'),
VALUES ('Baxter Thornton',2,'1998-06-09');
INSERT INTO db.phone_number (`number`,user_id)
VALUES ('(667) 281-8687',1),
VALUES ('1-922-306-2043',2),
VALUES ('1-232-249-6217',3),
VALUES ('1-604-197-3522',4),
VALUES ('(279) 852-2417',5),
VALUES ('(218) 766-7412',6),
VALUES ('(502) 213-6740',7),
VALUES ('1-344-205-3086',8),
VALUES ('1-380-420-6513',9),
VALUES ('(782) 347-5271',10),
VALUES ('(876) 626-2755',4),
VALUES ('(846) 528-8542',8),
VALUES ('1-422-658-7136',2),
VALUES ('1-168-395-6412',4),
VALUES ('(451) 437-3685',5),
VALUES ('1-222-623-1235',2),
VALUES ('1-713-424-7400',3);
Запрос, возвращающий имя и число указанных телефонных номеров девушек в возрасте от 18 до 22 лет, выглядит следующим образом:
SELECT u.`name`, count(pn.`id`) AS `amount of phone numbers` FROM testovoe.`user` u
JOIN testovoe.`phone_number` pn ON pn.`user_id` = u.`id`
WHERE u.`gender_id` = 3 AND TIMESTAMPDIFF(YEAR, u.`birthdate`, CURDATE()) BETWEEN 18 AND 22
GROUP BY pn.`user_id`;
Результат:
+--------------------+-------------------------+
| name | amount of phone numbers |
+--------------------+-------------------------+
| Lareina Harrington | 3 |
| Mallory Buck | 3 |
| Althea Morton | 2 |
| Rachel Payne | 2 |
+--------------------+-------------------------+
4 rows in set (0.001 sec)