mysql数据库

MySQL 数据库完全入门指南

本文档面向零基础新手,从概念到实操,用大量示例带你掌握 MySQL 的方方面面。


目录

  1. 什么是 MySQL
  2. 安装与启动
  3. 核心概念
  4. 基本操作:数据库
  5. 基本操作:表与数据类型
  6. 增删改查(CRUD)
  7. 条件与排序
  8. 约束
  9. 索引
  10. 多表与连接
  11. 聚合与分组
  12. 子查询
  13. 视图
  14. 常用函数
  15. 用户与权限(入门)
  16. 备份与恢复
  17. 常见问题与最佳实践

1. 什么是 MySQL

1.1 数据库是什么?

数据库就是有结构地存放数据的仓库
可以把它想象成 Excel:有很多“表”,每张表有“列”和“行”,但数据库比 Excel 更强大,能处理海量数据、多人同时访问、保证数据一致性和安全。

1.2 MySQL 是什么?

  • MySQL 是一种关系型数据库管理系统(RDBMS)
  • “关系型”指数据以的形式组织,表与表之间可以通过关系(如主键、外键)关联。
  • 使用 SQL(Structured Query Language,结构化查询语言) 来操作数据。

1.3 为什么学 MySQL?

  • 开源、免费、使用广泛(很多网站、应用的后端都用它)。
  • 语法相对简单,适合入门。
  • 学会 MySQL 后,再学其他数据库(如 PostgreSQL、SQL Server)会容易很多。

2. 安装与启动

2.1 安装 MySQL(Windows 示例)

  1. 打开 MySQL 官网 下载 Windows 安装包。
  2. 运行安装程序,选择 “Developer Default” 或 “Server only”。
  3. 设置 root 用户的密码(务必记住)。
  4. 完成安装。

2.2 启动 MySQL 服务

  • Windows:在“服务”里找到 “MySQL80”(或你的版本),设为“自动”并启动。
  • 命令行启动(以管理员身份打开 CMD):
    net start MySQL80

2.3 登录 MySQL

打开命令行(CMD 或 PowerShell),输入:

mysql -u root -p

按回车后输入你设置的 root 密码,即可进入 MySQL 命令行,看到类似:

mysql>

参数说明:

  • -u root:使用用户名为 root
  • -p:提示输入密码(也可以写成 -p你的密码,但不推荐,会暴露密码)

示例:指定主机和端口

mysql -h 127.0.0.1 -P 3306 -u root -p
  • -h:主机(本机用 127.0.0.1 或 localhost)
  • -P:端口(默认 3306)

3. 核心概念

3.1 层级关系

MySQL 服务器
  └── 数据库(Database)
        └── 表(Table)
              └── 行(Row / 记录)
              └── 列(Column / 字段)
  • 数据库:相当于一个“项目”或“应用”的数据容器,里面有多张表。
  • :类似 Excel 的一张表,有表名和列名。
  • :一条具体的数据记录。
  • :一个属性/字段,如“姓名”“年龄”。

3.2 举例理解

假设我们做一个“学生管理系统”:

  • 数据库school
  • students(学生表)
  • :学号、姓名、性别、年龄、班级
  • :每个学生一条记录
学号 姓名 性别 年龄 班级
001 张三 18 高一1班
002 李四 17 高一2班

4. 基本操作:数据库

4.1 查看已有数据库

SHOW DATABASES;

示例输出可能包含:

  • information_schema(系统库)
  • mysql(系统库)
  • performance_schema(系统库)
  • sys(系统库)
  • 以及你自己创建的库

4.2 创建数据库

CREATE DATABASE 数据库名;

示例:

CREATE DATABASE school;

指定字符集(推荐使用 utf8mb4,支持中文和 emoji):

CREATE DATABASE school DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

4.3 使用(选中)某个数据库

后续的建表、查询等操作都会在这个库里进行。

USE school;

提示:Database changed 表示已切换到 school

4.4 查看当前使用的数据库

SELECT DATABASE();

4.5 删除数据库

注意:删除后数据无法恢复,慎用!

DROP DATABASE 数据库名;

示例:

DROP DATABASE test_db;

5. 基本操作:表与数据类型

5.1 常用数据类型一览

类型 说明 示例
INT 整数 年龄、数量
BIGINT 大整数 雪花 ID
DECIMAL(M,D) 精确小数 金额
FLOAT/DOUBLE 浮点数 成绩、比例
VARCHAR(n) 可变长字符串 姓名、地址
CHAR(n) 定长字符串 固定长度编码
TEXT 长文本 文章内容
DATE 日期 2025-02-26
TIME 时间 14:30:00
DATETIME 日期+时间 2025-02-26 14:30:00
TIMESTAMP 时间戳 自动记录时间

示例:

  • 年龄:INT
  • 姓名:VARCHAR(50)
  • 价格:DECIMAL(10,2)(共 10 位,小数点后 2 位)
  • 生日:DATE
  • 注册时间:DATETIMETIMESTAMP

5.2 创建表

语法:

CREATE TABLE 表名 (
    列名1 数据类型 [约束],
    列名2 数据类型 [约束],
    ...
);

示例:学生表

USE school;

CREATE TABLE students (
    id          INT,              -- 学号
    name        VARCHAR(50),      -- 姓名
    gender      CHAR(1),          -- 性别:男/女
    age         INT,              -- 年龄
    class_name  VARCHAR(20),      -- 班级
    birth_date  DATE              -- 生日
);

示例:商品表(带小数和日期时间)

CREATE TABLE products (
    id          INT,
    name        VARCHAR(100),
    price       DECIMAL(10, 2),   -- 价格,如 99.99
    stock       INT,              -- 库存
    created_at  DATETIME          -- 创建时间
);

5.3 查看表结构

DESC students;

或:

DESCRIBE students;

会显示每列的名称、类型、是否可空、默认值、键信息等。

5.4 查看当前库下所有表

SHOW TABLES;

5.5 修改表(了解)

添加一列:

ALTER TABLE students ADD COLUMN phone VARCHAR(20);

修改列类型:

ALTER TABLE students MODIFY COLUMN name VARCHAR(100);

删除一列:

ALTER TABLE students DROP COLUMN phone;

重命名表:

RENAME TABLE students TO student_info;

5.6 删除表

DROP TABLE 表名;

示例:

DROP TABLE products;

6. 增删改查(CRUD)

CRUD = Create(增)、Read(查)、Update(改)、Delete(删)。

6.1 插入数据(Create / 增)

语法:

INSERT INTO 表名 (列1, 列2, ...) VALUES (值1, 值2, ...);

示例:插入一条学生记录

INSERT INTO students (id, name, gender, age, class_name, birth_date)
VALUES (1, '张三', '男', 18, '高一1班', '2007-05-15');
  • 字符串、日期用单引号括起来。
  • 数字不需要引号。
  • 列的顺序要和值的顺序一致。

一次插入多条:

INSERT INTO students (id, name, gender, age, class_name, birth_date) VALUES
(2, '李四', '女', 17, '高一2班', '2008-03-20'),
(3, '王五', '男', 18, '高一1班', '2007-08-10'),
(4, '赵六', '女', 17, '高一2班', '2008-01-05');

省略列名(不推荐):
若按表定义顺序给全所有列,可省略列名,但可读性差,易错。

INSERT INTO students VALUES (5, '钱七', '男', 18, '高一1班', '2007-11-22');

6.2 查询数据(Read / 查)

查询所有列:

SELECT * FROM students;

* 表示“所有列”。

查询指定列:

SELECT name, age, class_name FROM students;

给列起别名(AS):

SELECT name AS 姓名, age AS 年龄 FROM students;

6.3 更新数据(Update / 改)

语法:

UPDATE 表名 SET 列1=新值1, 列2=新值2 WHERE 条件;

示例:把学号为 1 的学生年龄改为 19

UPDATE students SET age = 19 WHERE id = 1;

示例:把高一1班所有人的年龄都改为 18

UPDATE students SET age = 18 WHERE class_name = '高一1班';

重要: 不加 WHERE 会更新表中所有行,非常危险!例如:

UPDATE students SET age = 18;  -- 所有人的年龄都变成 18!

6.4 删除数据(Delete / 删)

语法:

DELETE FROM 表名 WHERE 条件;

示例:删除学号为 5 的学生

DELETE FROM students WHERE id = 5;

示例:删除高一2班的所有学生

DELETE FROM students WHERE class_name = '高一2班';

重要: 不加 WHERE 会删除表中所有数据

DELETE FROM students;  -- 清空整张表!(表结构还在)

7. 条件与排序

7.1 WHERE 条件

比较运算符: =, !=<>, >, <, >=, <=

SELECT * FROM students WHERE age >= 18;
SELECT * FROM students WHERE class_name = '高一1班';
SELECT * FROM students WHERE id != 3;

逻辑运算符: AND, OR, NOT

-- 年龄≥18 且 在高一1班
SELECT * FROM students WHERE age >= 18 AND class_name = '高一1班';

-- 姓名为张三 或 姓名为李四
SELECT * FROM students WHERE name = '张三' OR name = '李四';

-- 不在高一2班
SELECT * FROM students WHERE NOT (class_name = '高一2班');

范围: BETWEEN ... AND ...IN (...)

-- 年龄在 17 到 18 之间(包含 17 和 18)
SELECT * FROM students WHERE age BETWEEN 17 AND 18;

-- 学号在 1, 2, 3 之中
SELECT * FROM students WHERE id IN (1, 2, 3);

空值判断: IS NULL, IS NOT NULL

SELECT * FROM students WHERE phone IS NULL;
SELECT * FROM students WHERE phone IS NOT NULL;

模糊匹配: LIKE

  • %:任意多个字符(包括 0 个)
  • _:任意一个字符
-- 姓张的学生
SELECT * FROM students WHERE name LIKE '张%';

-- 名字包含「三」
SELECT * FROM students WHERE name LIKE '%三%';

-- 姓名为 3 个字
SELECT * FROM students WHERE name LIKE '___';

7.2 排序 ORDER BY

语法:

SELECT ... FROM 表名 ORDER BY 列名 [ASC|DESC];
  • ASC:升序(默认)
  • DESC:降序

示例:按年龄升序

SELECT * FROM students ORDER BY age ASC;

示例:按年龄降序,年龄相同按学号升序

SELECT * FROM students ORDER BY age DESC, id ASC;

7.3 限制条数 LIMIT

语法: LIMIT 数量LIMIT 跳过条数, 取几条

-- 只取前 3 条
SELECT * FROM students ORDER BY id LIMIT 3;

-- 跳过前 2 条,取接下来 3 条(常用于分页)
SELECT * FROM students ORDER BY id LIMIT 2, 3;

8. 约束

约束用于保证数据的正确性和完整性。

8.1 主键(PRIMARY KEY)

  • 唯一标识一行,不能重复不能为 NULL
  • 一张表通常有一个主键(可以是单列或组合多列)。

示例:

CREATE TABLE users (
    id INT PRIMARY KEY,
    username VARCHAR(50),
    password VARCHAR(100)
);

8.2 自增(AUTO_INCREMENT)

常与主键配合:插入时不写 id,数据库自动从 1 递增。

CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50),
    password VARCHAR(100)
);

INSERT INTO users (username, password) VALUES ('zhangsan', '123456');
INSERT INTO users (username, password) VALUES ('lisi', 'abcdef');
-- id 会自动为 1, 2, ...

8.3 非空(NOT NULL)

该列不能为空。

CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL,
    password VARCHAR(100) NOT NULL
);

8.4 唯一(UNIQUE)

该列的值不能重复(可以有多个 NULL,视数据库而定)。

CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL UNIQUE,
    email VARCHAR(100) UNIQUE
);

8.5 默认值(DEFAULT)

插入时不写该列,则使用默认值。

CREATE TABLE articles (
    id INT PRIMARY KEY AUTO_INCREMENT,
    title VARCHAR(200),
    view_count INT DEFAULT 0,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

8.6 外键(FOREIGN KEY)——了解即可

外键表示“这一列引用另一张表的主键”,用来保证引用关系正确。

示例:订单表引用用户表

CREATE TABLE orders (
    id INT PRIMARY KEY AUTO_INCREMENT,
    user_id INT,
    amount DECIMAL(10,2),
    FOREIGN KEY (user_id) REFERENCES users(id)
);

8.7 综合示例:带约束的学生表

CREATE TABLE students (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL,
    gender CHAR(1) DEFAULT '男',
    age INT,
    class_name VARCHAR(20),
    birth_date DATE,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

9. 索引

索引可以加快查询,但会占用空间,并可能减慢写入。适合在经常用来查询、排序、分组的列上建索引。

9.1 创建索引

建表时创建:

CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL,
    email VARCHAR(100),
    INDEX idx_username (username),
    INDEX idx_email (email)
);

对已有表创建:

CREATE INDEX idx_name ON students (name);
CREATE INDEX idx_class_age ON students (class_name, age);

9.2 查看索引

SHOW INDEX FROM students;

9.3 删除索引

DROP INDEX idx_name ON students;

10. 多表与连接

实际项目中通常有多张表,通过“关系”连在一起查询。

10.1 示例:学生表 + 成绩表

学生表(已有):
id, name, class_name

成绩表 scores:

CREATE TABLE scores (
    id INT PRIMARY KEY AUTO_INCREMENT,
    student_id INT,           -- 对应 students.id
    subject VARCHAR(50),      -- 科目
    score DECIMAL(5,2)        -- 分数
);

INSERT INTO scores (student_id, subject, score) VALUES
(1, '语文', 85),
(1, '数学', 92),
(2, '语文', 78),
(2, '数学', 88);

10.2 内连接(INNER JOIN)

只保留两表都匹配上的行。

语法:

SELECT 列...
FROM 表1
INNER JOIN 表2 ON 表1.某列 = 表2.某列
[WHERE ...];

示例:查每个学生的姓名和每科成绩

SELECT s.name, sc.subject, sc.score
FROM students s
INNER JOIN scores sc ON s.id = sc.student_id;

这里用别名 ssc 简化书写。

10.3 左连接(LEFT JOIN)

以左表为准,右表没有匹配时,右表列显示为 NULL。

SELECT s.name, sc.subject, sc.score
FROM students s
LEFT JOIN scores sc ON s.id = sc.student_id;

这样没有成绩的学生也会出现,成绩列是 NULL。

10.4 右连接(RIGHT JOIN)

以右表为准,左表没有匹配时,左表列显示为 NULL。实际中多用 LEFT JOIN,右连接可用“左右表互换 + LEFT JOIN”代替。


11. 聚合与分组

11.1 聚合函数

函数 说明 示例
COUNT 计数 人数、条数
SUM 求和 总成绩、总金额
AVG 平均值 平均分
MAX 最大值 最高分
MIN 最小值 最低分

示例:

-- 学生总人数
SELECT COUNT(*) FROM students;

-- 某表某列非 NULL 的个数
SELECT COUNT(phone) FROM students;

-- 年龄总和、平均年龄、最大最小年龄
SELECT SUM(age), AVG(age), MAX(age), MIN(age) FROM students;

11.2 分组 GROUP BY

按某一列(或几列)分组,再对每组做聚合。

语法:

SELECT 分组列, 聚合函数(...)
FROM 表名
GROUP BY 分组列
[HAVING 条件];

示例:每个班级的人数

SELECT class_name, COUNT(*) AS 人数
FROM students
GROUP BY class_name;

示例:每个班级的平均年龄

SELECT class_name, AVG(age) AS 平均年龄
FROM students
GROUP BY class_name;

11.3 HAVING

WHERE 在分组前过滤行,HAVING 在分组后过滤“组”。

示例:人数大于 2 的班级

SELECT class_name, COUNT(*) AS 人数
FROM students
GROUP BY class_name
HAVING COUNT(*) > 2;

12. 子查询

子查询就是“查询里再套一个查询”,内层查询的结果可以给外层用。

12.1 在 WHERE 里用子查询

示例:查年龄大于平均年龄的学生

SELECT * FROM students
WHERE age > (SELECT AVG(age) FROM students);

示例:查有成绩记录的学生

SELECT * FROM students
WHERE id IN (SELECT student_id FROM scores);

12.2 在 FROM 里用子查询(派生表)

SELECT t.class_name, t.人数
FROM (
    SELECT class_name, COUNT(*) AS 人数
    FROM students
    GROUP BY class_name
) t
WHERE t.人数 >= 1;

13. 视图

视图是一张“虚拟表”,本质是一条保存好的 SELECT。
好处:简化复杂查询、控制可见列,不存数据,数据仍来自基表。

13.1 创建视图

CREATE VIEW v_student_score AS
SELECT s.id, s.name, s.class_name, sc.subject, sc.score
FROM students s
LEFT JOIN scores sc ON s.id = sc.student_id;

13.2 使用视图

像表一样查询:

SELECT * FROM v_student_score WHERE class_name = '高一1班';

13.3 删除视图

DROP VIEW v_student_score;

14. 常用函数

14.1 字符串

SELECT CONCAT('Hello, ', name) FROM students;           -- 拼接
SELECT LENGTH(name) FROM students;                       -- 长度(字节)
SELECT CHAR_LENGTH(name) FROM students;                 -- 字符数
SELECT UPPER(name), LOWER(name) FROM students;          -- 大小写
SELECT TRIM('  abc  ');                                 -- 去首尾空格
SELECT SUBSTRING(name, 1, 2) FROM students;             -- 截取

14.2 数值

SELECT ROUND(3.14159, 2);   -- 四舍五入,保留 2 位 → 3.14
SELECT CEIL(3.2);           -- 向上取整 → 4
SELECT FLOOR(3.8);          -- 向下取整 → 3
SELECT ABS(-10);            -- 绝对值 → 10

14.3 日期时间

SELECT NOW();                    -- 当前日期时间
SELECT CURDATE();                -- 当前日期
SELECT CURTIME();                -- 当前时间
SELECT YEAR(birth_date) FROM students;
SELECT MONTH(birth_date), DAY(birth_date) FROM students;
SELECT DATEDIFF(NOW(), birth_date) FROM students;  -- 相差天数

15. 用户与权限(入门)

15.1 创建用户

CREATE USER 'xiaoming'@'localhost' IDENTIFIED BY 'password123';
  • 'xiaoming'@'localhost':用户 xiaoming 只能从本机登录。
  • 若允许从任意主机登录:'xiaoming'@'%'(生产环境慎用)。

15.2 授权

-- 把 school 库的所有权限给 xiaoming
GRANT ALL PRIVILEGES ON school.* TO 'xiaoming'@'localhost';

-- 只给查询权限
GRANT SELECT ON school.* TO 'xiaoming'@'localhost';

-- 生效
FLUSH PRIVILEGES;

15.3 收回权限

REVOKE ALL PRIVILEGES ON school.* FROM 'xiaoming'@'localhost';

15.4 删除用户

DROP USER 'xiaoming'@'localhost';

16. 备份与恢复

16.1 备份(导出)

系统命令行(不要先登录 mysql)执行:

mysqldump -u root -p school > school_backup.sql

会提示输入 root 密码,然后当前目录下生成 school_backup.sql,包含建表语句和数据。

备份所有数据库:

mysqldump -u root -p --all-databases > all_backup.sql

16.2 恢复(导入)

先有数据库(若没有:CREATE DATABASE school;),再导入:

mysql -u root -p school < school_backup.sql

17. 常见问题与最佳实践

17.1 常见错误

  • 忘记 WHERE:UPDATE/DELETE 时一定要检查是否写了 WHERE,避免误改/误删全表。
  • 字符串引号:字符串、日期必须用单引号,数字不要加引号。
  • 中文乱码:建库建表时用 utf8mb4,连接时也指定 charset=utf8mb4

17.2 最佳实践(简要)

  1. 命名:表名、列名用英文或拼音,见名知意;主键常用 id
  2. 主键:每张表尽量有主键,常用自增 INT 或 BIGINT。
  3. 敏感信息:密码等不要明文存储,要加密(如 bcrypt)。
  4. 索引:常查、常排序的列可建索引,不要无脑给所有列建索引。
  5. 备份:重要数据定期用 mysqldump 备份。
  6. SQL 注入:应用层不要拼接 SQL,要用预编译(Prepared Statement)传参。

17.3 学习顺序建议

  1. 库 → 表 → 增删改查 → WHERE、ORDER BY、LIMIT
  2. 约束(主键、非空、默认、唯一)
  3. 聚合与 GROUP BY
  4. 多表 JOIN
  5. 子查询、视图
  6. 索引、用户权限、备份恢复

附录:常用命令速查

操作 命令示例
登录 mysql -u root -p
看库 SHOW DATABASES;
建库 CREATE DATABASE 库名;
用库 USE 库名;
看表 SHOW TABLES;
看表结构 DESC 表名;
建表 CREATE TABLE 表名 (列定义...);
插数据 INSERT INTO 表名 (列...) VALUES (值...);
查数据 SELECT 列 FROM 表 [WHERE] [ORDER BY] [LIMIT];
改数据 UPDATE 表 SET 列=值 WHERE 条件;
删数据 DELETE FROM 表 WHERE 条件;
退出 EXIT;QUIT;

祝你学习顺利!有问题多查文档、多写示例,动手练几遍就会越来越熟。

发表评论