什么是数据库?
数据库是一个逻辑容器,用来存放相关的数据集合。它就像一个大文件夹,里面存放着各种相关的数据文件。
sql
-- 查看当前MySQL实例中的所有数据库
SHOW DATABASES;
-- 创建新的数据库
CREATE DATABASE my_shop
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
-- 切换到指定数据库
USE my_shop;
-- 删除数据库(生产环境谨慎使用!)
-- DROP DATABASE my_shop;
-- 查看当前使用的数据库
SELECT DATABASE();
MySQL自带的系统数据库:
sql
-- 系统数据库,不要随意修改
SHOW DATABASES LIKE '%schema%';
-- information_schema:数据库元数据信息库
-- mysql:用户权限和系统配置
-- performance_schema:性能监控数据
-- sys:系统监控和诊断视图
数据库设计最佳实践:
sql
-- 按业务模块划分数据库
CREATE DATABASE user_center CHARACTER SET utf8mb4; -- 用户中心
CREATE DATABASE order_system CHARACTER SET utf8mb4; -- 订单系统
CREATE DATABASE product_catalog CHARACTER SET utf8mb4; -- 商品目录
CREATE DATABASE finance CHARACTER SET utf8mb4; -- 财务系统
-- 为测试环境创建数据库
CREATE DATABASE my_shop_test CHARACTER SET utf8mb4;
一、数据表(Table):数据的组织框架
表是数据库中实际存储数据的地方,由行(记录)和列(字段)组成。
sql
-- 创建用户表
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) UNIQUE,
age TINYINT UNSIGNED,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB COMMENT='用户基本信息表';
-- 查看数据库中的所有表
SHOW TABLES;
-- 查看表的结构信息
DESCRIBE users;
-- 或者
SHOW COLUMNS FROM users;
-- 查看表的详细创建语句
SHOW CREATE TABLE users;
-- 删除表
-- DROP TABLE users;
表的存储引擎选择:
sql
-- InnoDB(推荐默认使用)
CREATE TABLE innodb_table (
id INT PRIMARY KEY,
name VARCHAR(50)
) ENGINE=InnoDB;
-- MyISAM(适合读多写少的场景)
CREATE TABLE myisam_table (
id INT PRIMARY KEY,
log_text TEXT
) ENGINE=MyISAM;
-- MEMORY(内存表,临时数据)
CREATE TABLE memory_table (
id INT PRIMARY KEY,
session_data VARCHAR(255)
) ENGINE=MEMORY;
表的常见类型和用途:
sql
-- 1. 主表:存储核心业务数据
CREATE TABLE products (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(200) NOT NULL,
price DECIMAL(10,2) NOT NULL,
stock INT DEFAULT 0,
status ENUM('active', 'inactive') DEFAULT 'active'
) COMMENT='商品主表';
-- 2. 关联表:处理多对多关系
CREATE TABLE user_roles (
user_id INT NOT NULL,
role_id INT NOT NULL,
assigned_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (user_id, role_id),
INDEX idx_role_id (role_id)
) COMMENT='用户角色关联表';
-- 3. 日志表:记录操作历史
CREATE TABLE access_logs (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
user_id INT,
action VARCHAR(50) NOT NULL,
ip_address VARCHAR(45),
user_agent TEXT,
log_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_user_time (user_id, log_time),
INDEX idx_action_time (action, log_time)
) COMMENT='访问日志表';
-- 4. 配置表:存储系统配置
CREATE TABLE system_config (
config_key VARCHAR(100) PRIMARY KEY,
config_value TEXT NOT NULL,
config_group VARCHAR(50) DEFAULT 'general',
description VARCHAR(200),
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) COMMENT='系统配置表';
二、字段(Column):数据的详细定义
字段定义了表中每一列数据的类型、约束和特性。
完整的数据类型指南:
sql
CREATE TABLE data_type_demo (
-- 【整数类型】
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, -- 大整数,自增主键
user_id INT UNSIGNED NOT NULL, -- 用户ID
age TINYINT UNSIGNED, -- 年龄,0-255
status TINYINT DEFAULT 1, -- 状态标志
vote_count MEDIUMINT DEFAULT 0, -- 投票数
-- 【字符串类型】
username VARCHAR(50) NOT NULL, -- 用户名,变长字符串
fixed_code CHAR(10), -- 固定长度代码
email VARCHAR(254), -- 邮箱地址
description TEXT, -- 长文本描述
bio LONGTEXT, -- 超长文本
-- 【枚举和集合类型】
gender ENUM('M', 'F', 'U'), -- 性别枚举
tags SET('featured', 'hot', 'new', 'recommend'), -- 标签集合
-- 【时间日期类型】
birthday DATE, -- 出生日期
login_time DATETIME, -- 登录时间
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 创建时间
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
-- 【数值类型】
price DECIMAL(10,2), -- 价格,精确小数
discount FLOAT(5,2), -- 折扣率
rating DOUBLE(3,1), -- 评分
-- 【二进制类型】
avatar BLOB, -- 用户头像
contract MEDIUMBLOB, -- 合同文件
is_active BOOLEAN DEFAULT TRUE, -- 是否激活
-- 【JSON类型(MySQL 5.7+)】
preferences JSON -- 用户偏好设置
);
字段约束详解:
sql
CREATE TABLE constraint_demo (
-- 主键约束
id INT PRIMARY KEY AUTO_INCREMENT,
-- 非空约束
username VARCHAR(50) NOT NULL,
-- 唯一约束
email VARCHAR(100) UNIQUE,
phone VARCHAR(20) UNIQUE,
-- 默认值
status INT DEFAULT 1,
created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
-- 外键约束
department_id INT,
FOREIGN KEY (department_id)
REFERENCES departments(id)
ON DELETE SET NULL
ON UPDATE CASCADE,
-- 检查约束(MySQL 8.0.16+)
age INT CHECK (age >= 0 AND age <= 150),
salary DECIMAL(10,2) CHECK (salary >= 0),
-- 自动更新
updated_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP
);
三、三层结构的完整示例
让我们通过一个电商系统来理解三层结构:
sql
-- 1. 创建数据库
CREATE DATABASE ecommerce
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
USE ecommerce;
-- 2. 创建部门表
CREATE TABLE departments (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL UNIQUE,
manager_id INT,
budget DECIMAL(12,2) DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) COMMENT='部门表';
-- 3. 创建员工表
CREATE TABLE employees (
id INT PRIMARY KEY AUTO_INCREMENT,
employee_no VARCHAR(20) UNIQUE NOT NULL,
first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
phone VARCHAR(20),
salary DECIMAL(10,2) NOT NULL CHECK (salary >= 0),
department_id INT NOT NULL,
hire_date DATE NOT NULL,
birth_date DATE,
address TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
-- 外键约束
FOREIGN KEY (department_id)
REFERENCES departments(id)
ON DELETE RESTRICT
ON UPDATE CASCADE,
-- 索引
INDEX idx_department (department_id),
INDEX idx_name (last_name, first_name),
INDEX idx_hire_date (hire_date)
) COMMENT='员工表';
-- 4. 插入测试数据
INSERT INTO departments (name, budget) VALUES
('技术部', 1000000.00),
('销售部', 800000.00),
('人事部', 500000.00),
('财务部', 600000.00);
INSERT INTO employees (employee_no, first_name, last_name, email, salary, department_id, hire_date) VALUES
('TECH001', '张', '三', 'zhang.san@company.com', 15000.00, 1, '2023-01-15'),
('SALE001', '李', '四', 'li.si@company.com', 12000.00, 2, '2023-02-20'),
('HR001', '王', '五', 'wang.wu@company.com', 10000.00, 3, '2023-03-10');
-- 5. 查询示例
-- 查看所有员工及其部门
SELECT
e.employee_no,
CONCAT(e.last_name, e.first_name) AS full_name,
e.email,
d.name AS department_name,
e.salary
FROM employees e
JOIN departments d ON e.department_id = d.id
WHERE e.salary > 10000
ORDER BY e.salary DESC;
-- 6. 更新数据
UPDATE employees
SET salary = salary * 1.1
WHERE department_id = 1;
-- 7. 删除数据(谨慎操作)
-- DELETE FROM employees WHERE employee_no = 'TECH001';
四、设计最佳实践和规范
1. 命名规范:
sql
-- 正确的命名
CREATE TABLE user_accounts ( -- 表名使用复数形式
user_id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL, -- 字段名清晰明确
email_address VARCHAR(254), -- 使用完整单词
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) COMMENT='用户账户表';
-- 避免的命名方式
CREATE TABLE tbl_usr ( -- 避免使用缩写
usr_id INT, -- 缩写不明确
u_nm VARCHAR(50), -- 难以理解
eml VARCHAR(100) -- 缩写不标准
);
2. 字段设计原则:
sql
CREATE TABLE well_designed_table (
-- 主键设计
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
-- 业务字段
uuid CHAR(36) NOT NULL UNIQUE COMMENT '全局唯一标识',
user_code VARCHAR(20) NOT NULL UNIQUE COMMENT '用户编码',
-- 时间字段
created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
updated_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
deleted_time TIMESTAMP NULL COMMENT '删除时间',
-- 状态字段
record_status TINYINT DEFAULT 1 COMMENT '记录状态:1-正常 0-删除',
-- 索引
INDEX idx_user_code (user_code),
INDEX idx_created_time (created_time)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='设计良好的示例表';
3. 表关系设计模式:
sql
-- 一对一关系(用户和用户详情)
CREATE TABLE users (
user_id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL
);
CREATE TABLE user_profiles (
user_id INT PRIMARY KEY, -- 与users表主键相同
real_name VARCHAR(100),
avatar_url VARCHAR(500),
bio TEXT,
FOREIGN KEY (user_id) REFERENCES users(user_id)
);
-- 一对多关系(部门和员工)
CREATE TABLE departments (
dept_id INT PRIMARY KEY AUTO_INCREMENT,
dept_name VARCHAR(100) NOT NULL
);
CREATE TABLE employees (
emp_id INT PRIMARY KEY AUTO_INCREMENT,
emp_name VARCHAR(100) NOT NULL,
dept_id INT NOT NULL,
FOREIGN KEY (dept_id) REFERENCES departments(dept_id)
ON DELETE CASCADE
ON UPDATE CASCADE,
INDEX idx_dept_id (dept_id)
);
-- 多对多关系(学生和课程)
CREATE TABLE students (
student_id INT PRIMARY KEY AUTO_INCREMENT,
student_name VARCHAR(100) NOT NULL
);
CREATE TABLE courses (
course_id INT PRIMARY KEY AUTO_INCREMENT,
course_name VARCHAR(100) NOT NULL
);
CREATE TABLE student_courses (
student_id INT NOT NULL,
course_id INT NOT NULL,
enrolled_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
score DECIMAL(5,2),
PRIMARY KEY (student_id, course_id),
FOREIGN KEY (student_id) REFERENCES students(student_id),
FOREIGN KEY (course_id) REFERENCES courses(course_id)
);
五、管理和维护操作
常用管理命令:
sql
-- 表操作
-- 重命名字段
ALTER TABLE users CHANGE COLUMN old_name new_name VARCHAR(100);
-- 添加主键
ALTER TABLE users ADD PRIMARY KEY (id);
-- 添加外键
ALTER TABLE orders ADD FOREIGN KEY (user_id) REFERENCES users(id);
-- 重命名表
ALTER TABLE old_table_name RENAME TO new_table_name;
-- 修改表注释
ALTER TABLE users COMMENT = '用户信息表';
-- 添加多个字段
ALTER TABLE users
ADD COLUMN wechat VARCHAR(50) AFTER phone,
ADD COLUMN birthday DATE AFTER wechat;
-- 清空表数据(不可恢复)
TRUNCATE TABLE temp_data;
-- 复制表结构
CREATE TABLE new_table LIKE original_table;
-- 复制表结构和数据
CREATE TABLE new_table AS SELECT * FROM original_table;
信息查询技巧:
sql
-- 查看数据库信息
SELECT * FROM information_schema.SCHEMATA
WHERE SCHEMA_NAME = 'ecommerce';
-- 查看表信息
SELECT * FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'ecommerce';
-- 查看字段信息
SELECT
TABLE_NAME,
COLUMN_NAME,
DATA_TYPE,
IS_NULLABLE,
COLUMN_DEFAULT,
COLUMN_COMMENT
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'ecommerce'
ORDER BY TABLE_NAME, ORDINAL_POSITION;
-- 查看表大小
SELECT
TABLE_NAME AS `Table`,
ROUND((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024, 2) AS `Size (MB)`
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'ecommerce'
ORDER BY (DATA_LENGTH + INDEX_LENGTH) DESC;
六、练习
任务:设计一个博客系统数据库结构
sql
-- 创建数据库
CREATE DATABASE blog_system CHARACTER SET utf8mb4;
USE blog_system;
-- 你的设计代码在这里...
-- 需要创建:用户表、文章表、分类表、标签表、评论表
参考答案:
sql
-- 用户表
CREATE TABLE users (
user_id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) UNIQUE NOT NULL COMMENT '用户名',
email VARCHAR(254) UNIQUE NOT NULL COMMENT '邮箱',
password_hash VARCHAR(255) NOT NULL COMMENT '密码哈希',
display_name VARCHAR(100) COMMENT '显示名称',
avatar_url VARCHAR(500) COMMENT '头像URL',
bio TEXT COMMENT '个人简介',
role ENUM('admin', 'author', 'user') DEFAULT 'user' COMMENT '角色',
is_active BOOLEAN DEFAULT TRUE COMMENT '是否激活',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
) COMMENT='用户表';
-- 分类表
CREATE TABLE categories (
category_id INT PRIMARY KEY AUTO_INCREMENT,
category_name VARCHAR(100) NOT NULL UNIQUE COMMENT '分类名称',
description TEXT COMMENT '分类描述',
parent_id INT DEFAULT NULL COMMENT '父分类ID',
sort_order INT DEFAULT 0 COMMENT '排序',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
FOREIGN KEY (parent_id) REFERENCES categories(category_id)
) COMMENT='文章分类表';
-- 文章表
CREATE TABLE articles (
article_id INT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(200) NOT NULL COMMENT '文章标题',
content LONGTEXT NOT NULL COMMENT '文章内容',
excerpt TEXT COMMENT '文章摘要',
cover_image VARCHAR(500) COMMENT '封面图',
author_id INT NOT NULL COMMENT '作者ID',
category_id INT COMMENT '分类ID',
status ENUM('draft', 'published', 'archived') DEFAULT 'draft' COMMENT '状态',
view_count INT DEFAULT 0 COMMENT '阅读数',
comment_count INT DEFAULT 0 COMMENT '评论数',
like_count INT DEFAULT 0 COMMENT '点赞数',
published_at TIMESTAMP NULL COMMENT '发布时间',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
FOREIGN KEY (author_id) REFERENCES users(user_id),
FOREIGN KEY (category_id) REFERENCES categories(category_id),
INDEX idx_author_status (author_id, status),
INDEX idx_category_status (category_id, status),
INDEX idx_published_at (published_at)
) COMMENT='文章表';
-- 标签表
CREATE TABLE tags (
tag_id INT PRIMARY KEY AUTO_INCREMENT,
tag_name VARCHAR(50) NOT NULL UNIQUE COMMENT '标签名称',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间'
) COMMENT='标签表';
-- 文章标签关联表
CREATE TABLE article_tags (
article_id INT NOT NULL,
tag_id INT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (article_id, tag_id),
FOREIGN KEY (article_id) REFERENCES articles(article_id) ON DELETE CASCADE,
FOREIGN KEY (tag_id) REFERENCES tags(tag_id) ON DELETE CASCADE,
INDEX idx_tag_id (tag_id)
) COMMENT='文章标签关联表';
-- 评论表
CREATE TABLE comments (
comment_id INT PRIMARY KEY AUTO_INCREMENT,
article_id INT NOT NULL COMMENT '文章ID',
user_id INT NOT NULL COMMENT '用户ID',
parent_id INT DEFAULT NULL COMMENT '父评论ID',
content TEXT NOT NULL COMMENT '评论内容',
is_approved BOOLEAN DEFAULT TRUE COMMENT '是否审核通过',
like_count INT DEFAULT 0 COMMENT '点赞数',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
FOREIGN KEY (article_id) REFERENCES articles(article_id) ON DELETE CASCADE,
FOREIGN KEY (user_id) REFERENCES users(user_id),
FOREIGN KEY (parent_id) REFERENCES comments(comment_id) ON DELETE CASCADE,
INDEX idx_article_id (article_id),
INDEX idx_user_id (user_id),
INDEX idx_parent_id (parent_id)
) COMMENT='评论表';
总结
MySQL三层结构核心要点:
- 数据库:数据的逻辑容器,按业务模块划分
- 表:数据的组织框架,定义数据结构
- 字段:数据的详细定义,包括类型和约束
设计关键原则:
- 合理的命名规范
- 恰当的数据类型选择
- 完整的约束定义
- 清晰的表关系设计
- 适当的索引策略
数据库设计就像建筑蓝图------结构合理、规划周到,后续的开发和维护就会事半功倍!