返回

MySQL习题34连发,挑战高手大咖,你敢来吗?

后端

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_