MySQL习题34连发,挑战高手大咖,你敢来吗?
2024-01-12 04:25:13
MySQL 数据库教程:从入门到精通
如果你正在寻找一份全面的 MySQL 数据库教程,那么你来对地方了。本文将带你踏上学习 MySQL 的旅程,从基本查询到高级数据操作,再到表结构、索引、事务、备份、安全管理和挑战性任务。做好准备,让我们深入 MySQL 数据库的奇妙世界吧!
1. 准备阶段
在开始之前,你需要确保你的电脑已经安装了 MySQL 数据库并设置好数据库环境。创建一个名为 "my_database" 的数据库,并在其中创建一个名为 "users" 的表,包含以下列:
id
(INT, 主键)name
(VARCHAR(255))email
(VARCHAR(255), 唯一索引)created_at
(TIMESTAMP)updated_at
(TIMESTAMP)
2. 基本查询
查询所有用户的名字和邮箱:
SELECT name, email FROM users;
查询id为1的用户的名字和邮箱:
SELECT name, email FROM users WHERE id = 1;
查询名字中包含"John"的用户的名字和邮箱:
SELECT name, email FROM users WHERE name LIKE '%John%';
查询邮箱中包含"@gmail.com"的用户的名字和邮箱:
SELECT name, email FROM users WHERE email LIKE '%@gmail.com%';
查询在2023年1月1日之后创建的用户的名字和邮箱:
SELECT name, email FROM users WHERE created_at > '2023-01-01';
查询在2023年1月1日之前更新的用户的名字和邮箱:
SELECT name, email FROM users WHERE updated_at < '2023-01-01';
3. 高级查询
查询用户表中不同名字的个数:
SELECT COUNT(DISTINCT name) FROM users;
查询用户表中不同邮箱域名的个数:
SELECT COUNT(DISTINCT SUBSTRING_INDEX(email, '@', -1)) FROM users;
查询用户表中创建日期最晚的用户的名字和邮箱:
SELECT name, email FROM users ORDER BY created_at DESC LIMIT 1;
查询用户表中更新日期最早的用户的名字和邮箱:
SELECT name, email FROM users ORDER BY updated_at ASC LIMIT 1;
查询用户表中名字最长的用户的名字和邮箱:
SELECT name, email FROM users ORDER BY LENGTH(name) DESC LIMIT 1;
查询用户表中名字最短的用户的名字和邮箱:
SELECT name, email FROM users ORDER BY LENGTH(name) ASC LIMIT 1;
4. 数据操作
向用户表中插入一条新的记录:
INSERT INTO users (name, email, created_at, updated_at)
VALUES ('Jane Doe', 'jane.doe@example.com', '2023-03-08 12:34:56', '2023-03-08 12:34:56');
更新用户表中id为2的记录,将名字改为"John Smith":
UPDATE users SET name = 'John Smith' WHERE id = 2;
删除用户表中id为3的记录:
DELETE FROM users WHERE id = 3;
5. 表结构和索引
在用户表中添加一个名为"age"的列,类型为INT:
ALTER TABLE users ADD COLUMN age INT;
在用户表中添加一个名为"address"的列,类型为VARCHAR(255):
ALTER TABLE users ADD COLUMN address VARCHAR(255);
在用户表中创建索引,字段为"name":
CREATE INDEX idx_name ON users (name);
在用户表中创建索引,字段为"email":
CREATE INDEX idx_email ON users (email);
在用户表中创建索引,字段为"created_at":
CREATE INDEX idx_created_at ON users (created_at);
6. 事务和备份
启动一个事务,向用户表中插入一条新的记录:
START TRANSACTION;
INSERT INTO users (name, email, created_at, updated_at)
VALUES ('Michael Jones', 'michael.jones@example.com', '2023-03-09 13:45:07', '2023-03-09 13:45:07');
回滚事务:
ROLLBACK;
将用户表备份到一个名为"users_backup.sql"的文件中:
mysqldump my_database users > users_backup.sql
从"users_backup.sql"文件中恢复用户表:
mysql my_database < users_backup.sql
7. 安全和管理
为用户表设置密码,只允许拥有"admin"角色的用户访问该表:
GRANT SELECT, INSERT, UPDATE, DELETE ON my_database.users TO 'admin'@'localhost' IDENTIFIED BY 'password';
创建一个名为"my_user"的新用户,并授予其对用户表的读写权限:
CREATE USER 'my_user'@'localhost' IDENTIFIED BY 'password';
GRANT SELECT, INSERT, UPDATE, DELETE ON my_database.users TO 'my_user'@'localhost';
查看用户表中的所有记录,只显示名字和邮箱列:
SELECT name, email FROM users;
优化用户表,提高查询性能:
OPTIMIZE TABLE users;
分析用户表,获取表的详细统计信息:
ANALYZE TABLE users;
8. 挑战题
设计一个数据库,用于存储在线商店的订单信息,包括订单号、产品名称、数量、单价、总价、客户姓名、客户邮箱、客户地址、订单状态等信息:
CREATE TABLE orders (
order_id INT NOT NULL AUTO_INCREMENT,
product_name VARCHAR(255) NOT NULL,
quantity INT NOT NULL,
unit_price DECIMAL(10, 2) NOT NULL,
total_price DECIMAL(10, 2) NOT NULL,
customer_name VARCHAR(255) NOT NULL,
customer_email VARCHAR(255) NOT NULL,
customer_address VARCHAR(255) NOT NULL,
order_status VARCHAR(255) NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (order_id)
);
实现一个存储过程,用于计算用户表中每个用户的订单总金额:
CREATE PROCEDURE calculate_user_total_order_amount()
BEGIN
DECLARE user_id INT;
DECLARE total_amount DECIMAL(10, 2);
-- 遍历用户表中的每个用户
DECLARE cursor_users CURSOR FOR SELECT id FROM users;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET user_id = NULL;
OPEN cursor_users;
FETCH cursor_users INTO user_id;
WHILE user_id IS NOT NULL DO
-- 计算该用户的订单总金额
SET total_amount = (
SELECT SUM(total_price)
FROM orders
WHERE customer_id = user_id
);
-- 更新用户表的总金额字段
UPDATE users SET total_order_amount = total_amount WHERE id = user_id;
FETCH cursor_users INTO user_id;
END WHILE;
CLOSE cursor_users;
END
实现一个触发器,用于在用户表中插入或更新记录时自动更新"updated_at"列:
CREATE TRIGGER update_updated_at_timestamp
BEFORE INSERT OR UPDATE ON users
FOR EACH ROW
SET updated_at = NOW();
实现一个视图,用于显示用户表中所有用户的名字、邮箱和订单总金额:
CREATE VIEW user_orders_view AS
SELECT
users.name,
users.email,
SUM(orders.total_price) AS total_order_amount
FROM users
LEFT JOIN orders ON users.id = orders.customer_id
GROUP BY users.id;
实现一个自定义函数,用于计算两个日期之间的天数差:
CREATE FUNCTION days_between(start_