MySQL 是一个开源的关系型数据库管理系统(RDBMS),由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 使用 SQL(Structured Query Language)作为数据库查询语言,是目前最流行的关系型数据库之一。
| 特点 | 描述 |
|---|
| 开源免费 | 社区版完全免费,源代码开放 |
| 高性能 | 优化的查询算法,高效的存储引擎 |
| 跨平台 | 支持 Windows、Linux、macOS 等多种操作系统 |
| 可扩展 | 支持主从复制、读写分离、分库分表 |
| 安全性 | 提供完善的权限管理和加密机制 |
| 社区活跃 | 拥有庞大的用户群体和丰富的文档资源 |
| 特性 | MySQL | PostgreSQL | Oracle | SQL Server |
|---|
| 开源 | 是 | 是 | 否 | 否 |
| 性能 | 高 | 高 | 极高 | 高 |
| 复杂查询 | 良好 | 优秀 | 优秀 | 优秀 |
| 学习曲线 | 低 | 中 | 高 | 中 |
| 社区支持 | 极强 | 强 | 商业支持 | 商业支持 |
| 适用场景 | Web 应用 | 复杂业务 | 大型企业 | Windows 生态 |
wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
rpm -ivh mysql80-community-release-el7-3.noarch.rpm
yum install mysql-community-server -y
systemctl start mysqld
systemctl enable mysqld
grep 'temporary password' /var/log/mysqld.log
apt update
apt install mysql-server -y
mysql_secure_installation
docker pull mysql:8.0
docker run -d \
--name mysql8 \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=your_password \
-v /data/mysql/data:/var/lib/mysql \
-v /data/mysql/conf:/etc/mysql/conf.d \
mysql:8.0
docker exec -it mysql8 mysql -uroot -p
- 下载 MySQL Installer:https://dev.mysql.com/downloads/installer/
- 运行安装程序,选择 "Custom" 自定义安装
- 选择需要的组件:MySQL Server、MySQL Workbench 等
- 配置 MySQL Server:设置 root 密码、端口等
- 完成安装并启动服务
MySQL 配置文件位置:
- Linux:
/etc/my.cnf 或 /etc/mysql/my.cnf - Windows:
C:\ProgramData\MySQL\MySQL Server 8.0\my.ini
[mysqld]
port = 3306
basedir = /usr/local/mysql
datadir = /var/lib/mysql
socket = /var/lib/mysql/mysql.sock
pid-file = /var/run/mysqld/mysqld.pid
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
max_connections = 500
max_connect_errors = 100
wait_timeout = 28800
interactive_timeout = 28800
innodb_buffer_pool_size = 1G
innodb_log_file_size = 256M
innodb_log_buffer_size = 64M
log_error = /var/log/mysql/error.log
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
log_bin = /var/log/mysql/mysql-bin
binlog_format = ROW
expire_logs_days = 7
[mysql]
default-character-set = utf8mb4
[client]
default-character-set = utf8mb4
port = 3306
socket = /var/lib/mysql/mysql.sock
ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewPassword123!';
CREATE USER 'app_user'@'%' IDENTIFIED BY 'UserPassword123!';
GRANT ALL PRIVILEGES ON mydb.* TO 'app_user'@'%';
FLUSH PRIVILEGES;
SELECT user, host FROM mysql.user;
CREATE DATABASE mydb
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
SHOW DATABASES;
USE mydb;
SELECT DATABASE();
DROP DATABASE IF EXISTS mydb;
CREATE TABLE users (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
username VARCHAR(50) NOT NULL COMMENT '用户名',
email VARCHAR(100) NOT NULL COMMENT '邮箱',
password_hash VARCHAR(255) NOT NULL COMMENT '密码哈希',
status TINYINT DEFAULT 1 COMMENT '状态:0-禁用,1-启用',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (id),
UNIQUE KEY uk_username (username),
UNIQUE KEY uk_email (email),
KEY idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
DESC users;
SHOW CREATE TABLE users;
ALTER TABLE users ADD COLUMN phone VARCHAR(20) COMMENT '手机号';
ALTER TABLE users MODIFY COLUMN phone VARCHAR(15);
ALTER TABLE users DROP COLUMN phone;
ALTER TABLE users RENAME TO user_info;
DROP TABLE IF EXISTS users;
TRUNCATE TABLE users;
INSERT INTO users (username, email, password_hash)
VALUES ('john', 'john@example.com', 'hash_value');
INSERT INTO users (username, email, password_hash) VALUES
('alice', 'alice@example.com', 'hash1'),
('bob', 'bob@example.com', 'hash2'),
('charlie', 'charlie@example.com', 'hash3');
INSERT INTO users (id, username, email, password_hash)
VALUES (1, 'john', 'john_new@example.com', 'new_hash')
ON DUPLICATE KEY UPDATE
email = VALUES(email),
password_hash = VALUES(password_hash);
INSERT IGNORE INTO users (username, email, password_hash)
VALUES ('john', 'john@example.com', 'hash_value');
SELECT * FROM users;
SELECT id, username, email FROM users;
SELECT * FROM users WHERE status = 1;
SELECT * FROM users WHERE username LIKE 'j%';
SELECT * FROM users WHERE id IN (1, 2, 3);
SELECT * FROM users WHERE created_at BETWEEN '2024-01-01' AND '2024-12-31';
SELECT * FROM users ORDER BY created_at DESC;
SELECT * FROM users ORDER BY status ASC, created_at DESC;
SELECT * FROM users LIMIT 10;
SELECT * FROM users LIMIT 10 OFFSET 20;
SELECT COUNT(*) as total FROM users;
SELECT status, COUNT(*) as count FROM users GROUP BY status;
SELECT status, COUNT(*) as count FROM users GROUP BY status HAVING count > 10;
SELECT DISTINCT status FROM users;
UPDATE users SET email = 'new_email@example.com' WHERE id = 1;
UPDATE users SET
email = 'new_email@example.com',
status = 0,
updated_at = NOW()
WHERE id = 1;
UPDATE users SET status = 0 WHERE id IN (1, 2, 3);
UPDATE users SET status = CASE id
WHEN 1 THEN 0
WHEN 2 THEN 1
WHEN 3 THEN 0
END
WHERE id IN (1, 2, 3);
DELETE FROM users WHERE id = 1;
DELETE FROM users WHERE status = 0;
DELETE FROM users;
TRUNCATE TABLE users;
CREATE TABLE orders (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT UNSIGNED NOT NULL,
amount DECIMAL(10, 2) NOT NULL,
status VARCHAR(20) NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
SELECT u.username, o.amount, o.status
FROM users u
INNER JOIN orders o ON u.id = o.user_id;
SELECT u.username, o.amount, o.status
FROM users u
LEFT JOIN orders o ON u.id = o.user_id;
SELECT u.username, o.amount, o.status
FROM users u
RIGHT JOIN orders o ON u.id = o.user_id;
SELECT u.username, o.amount, p.product_name
FROM users u
JOIN orders o ON u.id = o.user_id
JOIN order_items oi ON o.id = oi.order_id
JOIN products p ON oi.product_id = p.id;
SELECT * FROM users
WHERE id IN (SELECT DISTINCT user_id FROM orders);
SELECT avg_amount
FROM (
SELECT user_id, AVG(amount) as avg_amount
FROM orders
GROUP BY user_id
) AS user_avg
WHERE avg_amount > 100;
SELECT * FROM users u
WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);
SELECT username,
(SELECT COUNT(*) FROM orders o WHERE o.user_id = u.id) as order_count
FROM users u;
| 类型 | 字节 | 范围(有符号) | 范围(无符号) | 说明 |
|---|
| TINYINT | 1 | -128 ~ 127 | 0 ~ 255 | 小整数 |
| SMALLINT | 2 | -32768 ~ 32767 | 0 ~ 65535 | 小整数 |
| MEDIUMINT | 3 | -8388608 ~ 8388607 | 0 ~ 16777215 | 中等整数 |
| INT | 4 | -2147483648 ~ 2147483647 | 0 ~ 4294967295 | 整数 |
| BIGINT | 8 | -2^63 ~ 2^63-1 | 0 ~ 2^64-1 | 大整数 |
| FLOAT | 4 | - | - | 单精度浮点 |
| DOUBLE | 8 | - | - | 双精度浮点 |
| DECIMAL(M,D) | 变长 | - | - | 精确小数 |
id BIGINT UNSIGNED AUTO_INCREMENT
age TINYINT UNSIGNED
status TINYINT
price DECIMAL(10, 2)
rate DECIMAL(5, 4)
score FLOAT
| 类型 | 最大长度 | 特点 | 适用场景 |
|---|
| CHAR(N) | 255 字符 | 定长,末尾补空格 | 固定长度:MD5、UUID |
| VARCHAR(N) | 65535 字节 | 变长,存储长度前缀 | 可变长度:姓名、标题 |
| TEXT | 65535 字节 | 大文本,不能有默认值 | 文章内容、描述 |
| MEDIUMTEXT | 16MB | 更大文本 | 大型文档 |
| LONGTEXT | 4GB | 超大文本 | 极少使用 |
username VARCHAR(50)
description VARCHAR(500)
content TEXT
uuid CHAR(36)
md5_hash CHAR(32)
| 类型 | 格式 | 范围 | 存储 | 说明 |
|---|
| DATE | YYYY-MM-DD | 1000-01-01 ~ 9999-12-31 | 3 字节 | 日期 |
| TIME | HH:MM:SS | -838:59:59 ~ 838:59:59 | 3 字节 | 时间 |
| DATETIME | YYYY-MM-DD HH:MM:SS | 1000-01-01 ~ 9999-12-31 | 8 字节 | 日期时间 |
| TIMESTAMP | YYYY-MM-DD HH:MM:SS | 1970-01-01 ~ 2038-01-19 | 4 字节 | 时间戳 |
| YEAR | YYYY | 1901 ~ 2155 | 1 字节 | 年份 |
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
birth_date DATE
start_time TIME
expire_time TIMESTAMP
CREATE TABLE products (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100),
attributes JSON,
tags JSON
);
INSERT INTO products (name, attributes, tags) VALUES
('iPhone', '{"color": "black", "storage": "128GB"}', '["electronics", "phone"]');
SELECT name, attributes->>'$.color' AS color FROM products;
SELECT * FROM products WHERE attributes->'$.storage' = '128GB';
SELECT * FROM products WHERE JSON_CONTAINS(tags, '"electronics"');
UPDATE products SET attributes = JSON_SET(attributes, '$.price', 999) WHERE id = 1;
UPDATE products SET tags = JSON_ARRAY_APPEND(tags, '$', 'new') WHERE id = 1;
CREATE TABLE example (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
email VARCHAR(100) UNIQUE,
username VARCHAR(50) NOT NULL,
status TINYINT DEFAULT 1,
department_id BIGINT,
FOREIGN KEY (department_id) REFERENCES departments(id),
age INT CHECK (age >= 0 AND age <= 150),
);
CREATE INDEX idx_username ON users(username);
CREATE UNIQUE INDEX uk_email ON users(email);
CREATE INDEX idx_name_status ON users(username, status);
SHOW INDEX FROM users;
DROP INDEX idx_username ON users;
ALTER TABLE users DROP INDEX idx_username;
ALTER TABLE users ADD INDEX idx_status(status);
ALTER TABLE users ADD UNIQUE INDEX uk_phone(phone);
SELECT CONCAT('Hello', ' ', 'World');
SELECT CONCAT_WS(',', 'a', 'b', 'c');
SELECT LENGTH('Hello');
SELECT CHAR_LENGTH('你好');
SELECT UPPER('hello'), LOWER('HELLO');
SELECT TRIM(' hello ');
SELECT SUBSTRING('Hello World', 1, 5);
SELECT REPLACE('Hello', 'l', 'L');
SELECT REVERSE('Hello');
SELECT LEFT('Hello', 2), RIGHT('Hello', 2);
SELECT ABS(-10);
SELECT CEIL(4.1), FLOOR(4.9);
SELECT ROUND(4.567, 2);
SELECT TRUNCATE(4.567, 2);
SELECT MOD(10, 3);
SELECT RAND();
SELECT POWER(2, 10);
SELECT SQRT(16);
SELECT NOW();
SELECT CURDATE(), CURTIME();
SELECT DATE('2024-01-15 10:30:00');
SELECT TIME('2024-01-15 10:30:00');
SELECT YEAR(NOW()), MONTH(NOW()), DAY(NOW());
SELECT HOUR(NOW()), MINUTE(NOW()), SECOND(NOW());
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s');
SELECT DATE_ADD(NOW(), INTERVAL 7 DAY);
SELECT DATEDIFF('2024-12-31', '2024-01-01');
SELECT TIMESTAMPDIFF(HOUR, '2024-01-01', NOW());
SELECT UNIX_TIMESTAMP();
SELECT FROM_UNIXTIME(1704067200);
SELECT COUNT(*) FROM users;
SELECT COUNT(DISTINCT status) FROM users;
SELECT SUM(amount) FROM orders;
SELECT AVG(amount) FROM orders;
SELECT MAX(amount), MIN(amount) FROM orders;
SELECT GROUP_CONCAT(username) FROM users;
SELECT GROUP_CONCAT(username ORDER BY id SEPARATOR ', ') FROM users;
SELECT IF(status = 1, '启用', '禁用') as status_text FROM users;
SELECT IFNULL(phone, 'N/A') FROM users;
SELECT COALESCE(phone, email, 'N/A') FROM users;
SELECT
username,
CASE status
WHEN 0 THEN '禁用'
WHEN 1 THEN '启用'
WHEN 2 THEN '待审核'
ELSE '未知'
END as status_text
FROM users;
SELECT
username,
CASE
WHEN age < 18 THEN '未成年'
WHEN age < 60 THEN '成年'
ELSE '老年'
END as age_group
FROM users;
SELECT NULLIF(status, 0) FROM users;
CREATE TABLE t_user (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL COMMENT '用户名',
password VARCHAR(255) NOT NULL COMMENT '密码',
email VARCHAR(100) COMMENT '邮箱',
phone VARCHAR(20) COMMENT '手机号',
avatar VARCHAR(255) COMMENT '头像URL',
status TINYINT DEFAULT 1 COMMENT '状态:0-禁用,1-启用',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uk_username (username),
KEY idx_status (status),
KEY idx_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
CREATE TABLE t_product (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(200) NOT NULL COMMENT '商品名称',
description TEXT COMMENT '商品描述',
price DECIMAL(10, 2) NOT NULL COMMENT '价格',
stock INT UNSIGNED DEFAULT 0 COMMENT '库存',
category_id BIGINT UNSIGNED COMMENT '分类ID',
status TINYINT DEFAULT 1 COMMENT '状态:0-下架,1-上架',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
KEY idx_category (category_id),
KEY idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品表';
CREATE TABLE t_order (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
order_no VARCHAR(32) NOT NULL COMMENT '订单号',
user_id BIGINT UNSIGNED NOT NULL COMMENT '用户ID',
total_amount DECIMAL(12, 2) NOT NULL COMMENT '订单总金额',
status VARCHAR(20) NOT NULL DEFAULT 'pending' COMMENT '订单状态',
payment_time DATETIME COMMENT '支付时间',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uk_order_no (order_no),
KEY idx_user_id (user_id),
KEY idx_status (status),
KEY idx_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表';
CREATE TABLE t_order_item (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
order_id BIGINT UNSIGNED NOT NULL COMMENT '订单ID',
product_id BIGINT UNSIGNED NOT NULL COMMENT '商品ID',
product_name VARCHAR(200) NOT NULL COMMENT '商品名称快照',
price DECIMAL(10, 2) NOT NULL COMMENT '商品单价快照',
quantity INT UNSIGNED NOT NULL COMMENT '购买数量',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
KEY idx_order_id (order_id),
KEY idx_product_id (product_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单明细表';
SELECT
u.id,
u.username,
COUNT(o.id) as order_count,
COALESCE(SUM(o.total_amount), 0) as total_spent
FROM t_user u
LEFT JOIN t_order o ON u.id = o.user_id
GROUP BY u.id, u.username
ORDER BY total_spent DESC;
SELECT
DATE_FORMAT(created_at, '%Y-%m') as month,
COUNT(*) as order_count,
SUM(total_amount) as total_sales
FROM t_order
WHERE status = 'completed'
GROUP BY DATE_FORMAT(created_at, '%Y-%m')
ORDER BY month;
SELECT
p.id,
p.name,
SUM(oi.quantity) as total_sold,
SUM(oi.price * oi.quantity) as total_revenue
FROM t_product p
JOIN t_order_item oi ON p.id = oi.product_id
JOIN t_order o ON oi.order_id = o.id
WHERE o.status = 'completed'
GROUP BY p.id, p.name
ORDER BY total_sold DESC
LIMIT 10;
SELECT
DATE(created_at) as order_date,
COUNT(*) as order_count,
SUM(total_amount) as daily_sales
FROM t_order
WHERE created_at >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)
GROUP BY DATE(created_at)
ORDER BY order_date;