MySQL详解

一、数据库概述

1、什么是数据库?

  • **定义**:数据库(Database, DB)是按照数据结构来组织、存储和管理数据的仓库,用于高效存储、检索和管理大量结构化或非结构化数据。

  • **核心目标**:解决数据冗余、数据不一致性问题,确保数据的安全性、完整性和可访问性

2、数据库管理系统(DBMS)

  • **定义**:数据库管理系统是用于管理数据库的软件系统,负责数据的存储、查询、更新、删除等操作,并提供事务管理、权限控制、备份恢复等功能。

  • 常见 DBMS:

  • **关系型数据库**:MySQL、PostgreSQL、Oracle、SQL Server。

  • **非关系型数据库(NoSQL)**:MongoDB、Redis、Cassandra。

3、数据库分类

数据库主要分为**关系型数据库**和 ** 非关系型数据库(NoSQL)** 两大类,两者在数据模型、适用场景上有显著差异。

```

姓名 年纪 地址 性别 出生

张三 18 china man 1990

张三

```

**关系型数据库(SQL)**

  • **数据模型**:基于二维表格(关系表),通过行(记录)和列(字段)存储数据,表间通过主键、外键建立关联。

  • 特点:

  • 结构化强,数据一致性高。

  • 支持复杂查询(如 JOIN、子查询),适合事务性场景(如金融交易、订单系统)。

  • 遵循 ACID 特性(原子性、一致性、隔离性、持久性)。

  • **典型应用**:企业 ERP 系统、银行核心系统、电商订单管理。

** 非关系型数据库(NoSQL)**

  • **数据模型**:采用键值对、文档、列族、图结构等非表格模型存储数据。

  • 特点:

  • 灵活可扩展,适合处理海量非结构化数据(如日志、图片、JSON 文档)。

  • 读写性能高,支持分布式架构。

  • 弱化 ACID,强调 BASE 特性(基本可用、软状态、最终一致性)。

  • 细分类型及示例:

  • **键值存储**:Redis(用于缓存、会话管理)。

  • **文档存储**:MongoDB(用于内容管理、用户数据存储)。

  • **列族存储**:HBase(用于海量数据实时查询,如日志分析)。

  • **图存储**:Neo4j(用于社交网络、推荐系统中的关系分析)。

  • **典型应用**:互联网用户行为分析、实时推荐系统、物联网设备数据存储。

4、结构化查询语言(SQL)

结构化查询语言(SQL)是用于管理和操作关系型数据库的标准编程语言,广泛应用于数据存储、查询、更新和管理。以下是对 SQL 的详细解析:

**. 定义与作用**

  • **SQL(Structured Query Language)**:是一种专门设计用于与数据库通信的编程语言,用于执行数据操作(如查询、插入、更新)和数据库管理(如创建表、修改结构、权限控制)。

  • 核心功能:

  • 数据查询(SELECT):从数据库中检索数据。

  • 数据操作(INSERT、UPDATE、DELETE):增删改数据。

  • 数据定义(CREATE、ALTER、DROP):创建、修改、删除数据库对象(如表、索引)。

  • 数据控制(GRANT、REVOKE):管理用户权限。

**SQL 与数据库的关系**

  • SQL 是一种语言标准,而数据库(如 MySQL、PostgreSQL、Oracle)是实现 SQL 标准的软件系统。不同数据库对 SQL 的支持略有差异,但核心语法一致。

二、MySQL入门

```

MySQL是一个c/s架构的软件

c/s: client (客户端)------> server 服务端 代表应用:QQ 迅雷 企业微信

b/s: browser (浏览器) ----> server 服务端

密码:qwe123 输入的时候要是英文状态,然后必须是小写。

```

MySQL 是全球最流行的开源关系型数据库管理系统(RDBMS),由瑞典 MySQL AB 公司开发,后被 Oracle 收购。它以高性能、可靠性和易用性著称,广泛应用于 Web 应用、企业系统和中小型数据存储场景。以下是对 MySQL 的深度解析:

1、核心特性

开源与跨平台

  • **开源许可证**:采用 GPL(通用公共许可证),允许免费使用和修改,但商业应用需购买商业许可证。

  • **跨平台支持**:支持 Linux、Windows、macOS、Solaris 等主流操作系统。

** 存储引擎**

MySQL 支持多种存储引擎,每个引擎有不同特性,最常用的是:

  • **InnoDB**(默认):支持事务、外键、行级锁和崩溃恢复,适合高并发和写密集型场景。

  • **MyISAM**:不支持事务和外键,读写性能高,但不适合高并发事务场景。

  • **Memory**:数据存储在内存中,查询极快,适合临时数据或缓存。

  • **Archive**:只支持 INSERT 和 SELECT,压缩率高,适合历史数据归档。

**高性能与扩展性**

  • **索引优化**:支持 B-Tree、哈希索引,优化查询效率。

  • **复制(Replication)**:主从复制、主主复制,实现读写分离和高可用性。

  • **分区(Partitioning)**:水平分割大表,提升查询性能。

**安全与权限管理**

  • **用户认证**:基于用户名、主机和密码的访问控制。

  • **细粒度权限**:支持 GRANT/REVOKE 对数据库、表、列级别的权限控制。

  • **加密功能**:支持 SSL/TLS 加密传输,以及数据静态加密(TDE)。

2、MySQL链接

安装 MySQL 后,你可以通过以下几种方式连接到 MySQL 服务端:

  • 1、使用命令行客户端连接

  • 2、使用图形化工具连接

常用 MySQL 图形化管理工具:

使用MySQL命令行链接

```

mysql -u your_username -p

```

**参数说明:**

  • `-u` 参数用于指定用户名。

  • `-p` 参数表示需要输入密码。

指定主机和端口连接(适用于远程连接):

```

mysql -h 主机名或IP地址 -P 端口号 -u 用户名 -p

```

例如:

```

mysql -h 127.0.0.1 -P 3306 -u root -p

```

3、简单的SQL语句

列出所有可用的数据库:

```

SHOW DATABASES;

```

选择要使用的数据库:

```

USE your_database;

```

列出所选数据库中的所有表:

```

SHOW TABLES;

```

退出 **mysql>** 命令提示窗口可以使用 **exit** 命令,如下所示:

```

mysql> EXIT;

Bye

```

或者使用:

```

mysql> QUIT;

```

或者按下 **Ctrl + D**(在 Unix/Linux 系统中)。

4、创建数据库

我们可以在登陆 MySQL 服务后,使用 **create** 命令创建数据库,语法如下:

```

CREATE DATABASE 数据库名;

```

以下命令简单的演示了创建数据库的过程,数据名为 helloworld:

```

root@host\]# mysql -u root -p Enter password:\*\*\*\*\*\* # 登录后进入终端 mysql\> create DATABASE helloworld; \`\`\` 建数据库的基本语法如下: \`\`\` CREATE DATABASE \[IF NOT EXISTS\] database_name \[CHARACTER SET charset_name

COLLATE collation_name\]; \`\`\` 如果你希望在创建数据库时指定一些选项,可以使用 CREATE DATABASE 语句的其他参数,例如,你可以指定字符集和排序规则: \`\`\` CREATE DATABASE mydatabase CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; \`\`\` 如果数据库已经存在,执行 CREATE DATABASE 将导致错误。 为了避免这种情况,你可以在 CREATE DATABASE 语句中添加 IF NOT EXISTS 子句: \`\`\` CREATE DATABASE IF NOT EXISTS mydatabase; \`\`\` ###### 5、删除数据库 使用普通用户登陆 MySQL 服务器,你可能需要特定的权限来创建或者删除 MySQL 数据库,所以我们这边使用 root 用户登录,root 用户拥有最高权限。 在删除数据库过程中,务必要十分谨慎,因为在执行删除命令后,所有数据将会消失。 \*\*drop 命令删除数据库\*\* drop 命令格式: \`\`\` DROP DATABASE \; -- 直接删除数据库,不检查是否存在 或 DROP DATABASE \[IF EXISTS\] \; \`\`\` \*\*参数说明:\*\* - \`IF EXISTS\` 是一个可选的子句,表示如果数据库存在才执行删除操作,避免因为数据库不存在而引发错误。 - \`database_name\` 是你要删除的数据库的名称。 例如删除名为 helloworld 的数据库: \`\`\` -- 直接删除数据库,不检查是否存在 mysql\> DROP DATABASE helloworld; -- 删除数据库,如果存在的话 DROP DATABASE IF EXISTS helloworld; \`\`\` \*\*注意:\*\* 在执行删除数据库操作前,请确保你确实想要删除数据库及其所有数据,因为该操作是不可逆的。为了避免误操作,通常建议在执行删除之前备份数据库。 ###### \*\*6、创建数据表\*\* \*\*语法\*\* 以下为创建 MySQL 数据表的 SQL 通用语法: \`\`\` CREATE TABLE table_name ( column1 datatype, column2 datatype, ... ); create table goods( name varchar(50), price decimal(10, 2), description varchar(500), address varchar(100) )charset=utf8; create table goods()charset=utf8; 添加数据: INSERT INTO table_name (column1, column2, column3, ...) VALUES (value1, value2, value3, ...); insert into goods(name,price,description,address) values("小米 suv7", 10000.01, "are you ok", "beijing"); insert into goods(name,price,description,address) values("小米 Ultra", 100000.01, "are you ok", "beijing"); \`\`\` \*\*参数说明:\*\* - \`table_name\` 是你要创建的表的名称。 - \`column1\`, \`column2\`, ... 是表中的列名。 - \`datatype\` 是每个列的数据类型。 以下是一个具体的实例,创建一个用户表 \*\*users\*\*: \`\`\` CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL, email VARCHAR(100) NOT NULL, birthdate DATE, is_active BOOLEAN DEFAULT TRUE ); \`\`\` 实例解析: - \`id\`: 用户 id,整数类型,自增长,作为主键。 - \`username\`: 用户名,变长字符串,不允许为空。 - \`email\`: 用户邮箱,变长字符串,不允许为空。 - \`birthdate\`: 用户的生日,日期类型。 - \`is_active\`: 用户是否已经激活,布尔类型,默认值为 true。 ###### 7、删除数据表 语法 以下为删除 MySQL 数据表的通用语法: \`\`\` DROP TABLE table_name; -- 直接删除表,不检查是否存在 \`\`\` 或 \`\`\` DROP TABLE \[IF EXISTS\] table_name; -- 会检查是否存在,如果存在则删除 \`\`\` \*\*参数说明:\*\* - \`table_name\` 是要删除的表的名称。 - \`IF EXISTS\` 是一个可选的子句,表示如果表存在才执行删除操作,避免因为表不存在而引发错误。 \`\`\` -- 删除表,如果存在的话 DROP TABLE IF EXISTS mytable; -- 直接删除表,不检查是否存在 DROP TABLE mytable; \`\`\` ###### 8、插入数据 语法 以下为向MySQL数据表插入数据通用的 \*\*INSERT INTO\*\* SQL语法: \`\`\` INSERT INTO table_name (column1, column2, column3, ...) VALUES (value1, value2, value3, ...); \`\`\` \*\*参数说明:\*\* - \`table_name\` 是你要插入数据的表的名称。 - \`column1\`, \`column2\`, \`column3\`, ... 是表中的列名。 - \`value1\`, \`value2\`, \`value3\`, ... 是要插入的具体数值。 如果数据是字符型,必须使用单引号 \*\*'\*\* 或者双引号 \*\*"\*\*,如: 'value1', "value1"。 一个简单的实例,插入了一行数据到名为 users 的表中: \`\`\` INSERT INTO users (username, email, birthdate, is_active) VALUES ('test', 'test@google.com', '1990-01-01', true); \`\`\` - \`username\`: 用户名,字符串类型。 - \`email\`: 邮箱地址,字符串类型。 - \`birthdate\`: 用户生日, 日期类型。 - \`is_active\`: 是否已激活,布尔类型。 如果你要插入所有列的数据,可以省略列名: \`\`\` INSERT INTO users VALUES (NULL,'test', 'test@google.com', '1990-01-01', true); \`\`\` 这里,\*\*NULL\*\* 是用于自增长列的占位符,表示系统将为 \*\*id\*\* 列生成一个唯一的值。 如果你要插入多行数据,可以在 VALUES 子句中指定多组数值: \`\`\` INSERT INTO users (username, email, birthdate, is_active) VALUES ('test1', 'test1@google.com', '1985-07-10', true), ('test2', 'test2@google.com', '1988-11-25', false), ('test3', 'test3@google.com', '1993-05-03', true); \`\`\` 以上代码将在 users 表中插入三行数据。 查询数据: 语法: \`\`\` SELECT COLUMN1,COLUMN2...... FROM TABLE_NAME; 显示指定字段 SELECT \* FROM TABLE_NAME; 显示所有字段 \`\`\` 修改数据: 语法: \`\`\` UPDATE TABLE_NAME SET COLUMN=VALUE; 将某一列里面的所有数据都更新 UPDATE TABLE_NAME SET COLUMN=VALUE WHERE 条件; \`\`\` ###### 9、表结构修改 1. 添加列 \`\`\` ALTER TABLE 表名 ADD COLUMN 列名 数据类型 \[约束条件\] \[AFTER 现有列名\|FIRST\]; \`\`\` 示例: \`\`\` -- 在users表的email列后添加age列 ALTER TABLE users ADD COLUMN age INT NOT NULL DEFAULT 0 AFTER email; -- 添加多列 ALTER TABLE users ADD COLUMN phone VARCHAR(20), ADD COLUMN address VARCHAR(100); \`\`\` 2. 删除列 \`\`\` ALTER TABLE 表名 DROP COLUMN 列名; \`\`\` 示例: \`\`\` ALTER TABLE users DROP COLUMN age; \`\`\` 3. 修改列定义 \`\`\` ALTER TABLE 表名 MODIFY COLUMN 列名 新数据类型 \[新约束条件\]; \`\`\` 示例: \`\`\` -- 修改username长度并添加唯一约束 ALTER TABLE users MODIFY COLUMN username VARCHAR(50) UNIQUE; -- 修改列默认值 ALTER TABLE users MODIFY COLUMN status TINYINT DEFAULT 1; \`\`\` 4. 重命名列 \`\`\` ALTER TABLE 表名 CHANGE COLUMN 旧列名 新列名 数据类型 \[约束条件\]; \`\`\` 示例: \`\`\` ALTER TABLE users CHANGE COLUMN reg_date register_date DATETIME; \`\`\` ### 三、MySQL数据类型 MySQL 中定义数据字段的类型对你数据库的优化是非常重要的。 MySQL 支持多种类型,大致可以分为三类:数值、日期/时间和字符串(字符)类型。 ###### 1、数值类型 MySQL 支持所有标准 SQL 数值数据类型。 这些类型包括严格数值数据类型(INTEGER、SMALLINT、DECIMAL 和 NUMERIC),以及近似数值数据类型(FLOAT、REAL 和 DOUBLE PRECISION)。 关键字INT是INTEGER的同义词,关键字DEC是DECIMAL的同义词。 BIT数据类型保存位字段值,并且支持 MyISAM、MEMORY、InnoDB 和 BDB表。 作为 SQL 标准的扩展,MySQL 也支持整数类型 TINYINT、MEDIUMINT 和 BIGINT。下面的表显示了需要的每个整数类型的存储和范围。 \| 类型 \| 大小 \| 范围(有符号) \| 范围(无符号) \| 用途 \| \| :----------- \| :--------------------------------------- \| :----------------------------------------------------------- \| :----------------------------------------------------------- \| :-------------- \| \| TINYINT \| 1 Bytes \| (-128,127) \| (0,255) \| 小整数值 \| \| SMALLINT \| 2 Bytes \| (-32 768,32 767) \| (0,65 535) \| 大整数值 \| \| MEDIUMINT \| 3 Bytes \| (-8 388 608,8 388 607) \| (0,16 777 215) \| 大整数值 \| \| INT或INTEGER \| 4 Bytes \| (-2 147 483 648,2 147 483 647) \| (0,4 294 967 295) \| 大整数值 \| \| BIGINT \| 8 Bytes \| (-9,223,372,036,854,775,808,9 223 372 036 854 775 807) \| (0,18 446 744 073 709 551 615) \| 极大整数值 \| \| FLOAT \| 4 Bytes \| (-3.402 823 466 E+38,-1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38) \| 0,(1.175 494 351 E-38,3.402 823 466 E+38) \| 单精度 浮点数值 \| \| DOUBLE \| 8 Bytes \| (-1.797 693 134 862 315 7 E+308,-2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) \| 0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) \| 双精度 浮点数值 \| \| DECIMAL \| 对DECIMAL(M,D) ,如果M\>D,为M+2否则为D+2 \| 依赖于M和D的值 \| 依赖于M和D的值 \| 小数值 \| \`\`\` create table demo1( name varchar(50), age tinyint unsigned ); create table demo2( name varchar(50), age int ); create table demo3( goods_name varchar(50), price decimal(10, 2) ); \`\`\` ###### 2、日期和时间类型 表示时间值的日期和时间类型为DATETIME、DATE、TIMESTAMP、TIME和YEAR。 每个时间类型有一个有效值范围和一个"零"值,当指定不合法的MySQL不能表示的值时使用"零"值。 TIMESTAMP类型有专有的自动更新特性,将在后面描述。 \| 类型 \| 大小 ( bytes) \| 范围 \| 格式 \| 用途 \| \| :-------- \| :------------ \| :----------------------------------------------------------- \| :------------------ \| :----------------------- \| \| DATE \| 3 \| 1000-01-01/9999-12-31 \| YYYY-MM-DD \| 日期值 \| \| TIME \| 3 \| '-838:59:59'/'838:59:59' \| HH:MM:SS \| 时间值或持续时间 \| \| YEAR \| 1 \| 1901/2155 \| YYYY \| 年份值 \| \| DATETIME \| 8 \| '1000-01-01 00:00:00' 到 '9999-12-31 23:59:59' \| YYYY-MM-DD hh:mm:ss \| 混合日期和时间值 \| \| TIMESTAMP \| 4 \| '1970-01-01 00:00:01' UTC 到 '2038-01-19 03:14:07' UTC结束时间是第 \*\*2147483647\*\* 秒,北京时间 \*\*2038-1-19 11:14:07\*\*,格林尼治时间 2038年1月19日 凌晨 03:14:07 \| YYYY-MM-DD hh:mm:ss \| 混合日期和时间值,时间戳 \| \`\`\` create table demo4( title varchar(100), add_time DATE ); create table demo5( title varchar(100), add_time year ); \`\`\` ###### 3、字符串类型 字符串类型指CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET。该节描述了这些类型如何工作以及如何在查询中使用这些类型。 \| 类型 \| 大小 \| 用途 \| \| :--------- \| :-------------------- \| :------------------------------ \| \| CHAR \| 0-255 bytes \| 定长字符串 \| \| VARCHAR \| 0-65535 bytes \| 变长字符串 \| \| TINYBLOB \| 0-255 bytes \| 不超过 255 个字符的二进制字符串 \| \| TINYTEXT \| 0-255 bytes \| 短文本字符串 \| \| BLOB \| 0-65 535 bytes \| 二进制形式的长文本数据 \| \| TEXT \| 0-65 535 bytes \| 长文本数据 \| \| MEDIUMBLOB \| 0-16 777 215 bytes \| 二进制形式的中等长度文本数据 \| \| MEDIUMTEXT \| 0-16 777 215 bytes \| 中等长度文本数据 \| \| LONGBLOB \| 0-4 294 967 295 bytes \| 二进制形式的极大文本数据 \| \| LONGTEXT \| 0-4 294 967 295 bytes \| 极大文本数据 \| \*\*注意\*\*:char(n) 和 varchar(n) 中括号中 n 代表字符的个数,并不代表字节个数,比如 CHAR(30) 就可以存储 30 个字符。 CHAR 和 VARCHAR 类型类似,但它们保存和检索的方式不同。它们的最大长度和是否尾部空格被保留等方面也不同。在存储或检索过程中不进行大小写转换。 BINARY 和 VARBINARY 类似于 CHAR 和 VARCHAR,不同的是它们包含二进制字符串而不要非二进制字符串。也就是说,它们包含字节字符串而不是字符字符串。这说明它们没有字符集,并且排序和比较基于列值字节的数值值。 BLOB 是一个二进制大对象,可以容纳可变数量的数据。有 4 种 BLOB 类型:TINYBLOB、BLOB、MEDIUMBLOB 和 LONGBLOB。它们区别在于可容纳存储范围不同。 有 4 种 TEXT 类型:TINYTEXT、TEXT、MEDIUMTEXT 和 LONGTEXT。对应的这 4 种 BLOB 类型,可存储的最大长度不同,可根据实际情况选择。 \`\`\` create table demo1( name char(10) ); create table demo2( title varchar(100) ); create table demo3( content LONGTEXT ); \`\`\` ### 四、字段约束 在数据库中,字段约束(也称为列约束)是一种规则,用于限制可以存储在表字段中的数据类型、范围或格式。它们确保数据的完整性和一致性,防止无效或不符合业务规则的数据进入数据库。 ###### 1、非空约束(not null) \*\*作用\*\*:字段必须包含值,插入 \`NULL\` 会报错。 示例: \`\`\` CREATE TABLE users ( name VARCHAR(50) NOT NULL, -- 姓名不能为空 email VARCHAR(50), ); \`\`\` ###### 2、唯一约束(\*\*UNIQUE\*\*) 作用:字段值必须唯一,但可以为 \`NULL\`(多个 \`NULL\` 被视为相同)。 示例: \`\`\` CREATE TABLE users2 ( email VARCHAR(50) UNIQUE -- 邮箱不能重复 ); \`\`\` ###### 3、主键约束(\*\*PRIMARY KEY\*\*) 作用:唯一标识表中的记录,隐含 \`NOT NULL + UNIQUE\`。 示例: \`\`\` CREATE TABLE products ( product_id INT PRIMARY KEY, -- 单字段主键 name VARCHAR(50) ); -- 复合主键(多个字段组合唯一) CREATE TABLE order_items ( order_id INT, product_id INT, PRIMARY KEY (order_id, product_id) ); create table wenzhang2( id int AUTO_INCREMENT primary key, title varchar(200) UNIQUE not null, author varchar(50) not null, address varchar(100) not null, add_time datetime not null, content longtext not null ); insert into wenzhang(id,title, author,address,add_time,content) values(1, "python 从入门到精通", "zhangsan", "beijing", "2025-5-23 20:59:01", "python nice!") insert into wenzhang2(title,author,address,add_time,content) values("python 从入门到精通", "zhangsan", "beijing", "2025-5-23 20:59:01", "python nice!"); \`\`\` ###### 4、默认约束(\*\*DEFAULT\*\*) 作用:当插入数据未提供值时,自动使用默认值。 \`\`\` CREATE TABLE logs ( id INT PRIMARY KEY, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- 默认当前时间 ); create table demo5( name varchar(50) not null, age int not null ); \`\`\` ###### 5、自动增长(AUTO_INCREMENT) 在 MySQL 中,\`AUTO_INCREMENT\` 是一种特殊的字段属性,用于为表中的记录生成唯一的自增数值。它通常与主键(PRIMARY KEY)一起使用,确保每条记录都有一个唯一标识. \*\*创建表时指定 \`AUTO_INCREMENT\`\*\* \`\`\` CREATE TABLE users ( id INT PRIMARY KEY AUTO_INCREMENT, -- 自增主键 name VARCHAR(50) NOT NULL, email VARCHAR(50) UNIQUE ); \`\`\` - 无需手动插入 \`id\` 值,MySQL 会自动生成下一个可用的整数。 - 初始值默认为 \`1\`,每次插入新记录时递增 \`1\`。 \*\*起始值与步长\*\* - \*\*起始值\*\*:默认从 \`1\` 开始,可通过 \`ALTER TABLE\` 修改: \`\`\` ALTER TABLE users AUTO_INCREMENT = 100; -- 下一个插入的id为100 \`\`\` - \*\*步长\*\*:通常为 \`1\`,不支持直接设置步长(由 MySQL 内部控制)。 \*\*处理删除操作\*\* 若删除某条记录,自增序列不会回退。例如: \`\`\` DELETE FROM users WHERE id = 2; -- 删除id=2的记录 INSERT INTO users (name, email) VALUES ('Charlie', 'charlie@example.com'); -- 新记录的id=3(而非2) \`\`\` \*\*手动插入自增字段\*\* 可以手动指定 \`id\` 值,但需确保不与现有值冲突: \`\`\` INSERT INTO users (id, name, email) VALUES (10, 'David', 'david@example.com'); -- 强制使用id=10,下一个自动生成的id为11 \`\`\` ###### 6、注释(comment) 在 MySQL 中,注释(\*\*COMMENT\*\*)是一种用于为表、列(字段)、存储过程等数据库对象添加说明文字的机制。它不会影响数据库的功能,但能帮助开发者理解表结构和数据含义。 \*\*列(字段)注释\*\* 为表中的字段添加描述性信息,便于后续维护。 \`\`\` CREATE TABLE usersss ( id INT PRIMARY KEY AUTO_INCREMENT COMMENT '用户ID,自增主键', name VARCHAR(50) NOT NULL COMMENT '用户姓名', email VARCHAR(50) UNIQUE COMMENT '用户邮箱,唯一标识' ); \`\`\` 查看列注释: \`\`\` SHOW FULL COLUMNS FROM users; \`\`\` \*\*表注释\*\* 为整个表添加说明,解释其用途和数据范围。 \`\`\` CREATE TABLE products ( product_id INT PRIMARY KEY, name VARCHAR(50) ) COMMENT = '存储所有商品的基础信息,包括名称、价格等'; \`\`\` 查看表注释: \`\`\` SHOW CREATE TABLE products; \`\`\` ### 五、数据表关系 在 MySQL 中,表关系(Table Relationships)用于建立不同数据表之间的关联,使数据能够以结构化方式组织和查询。常见的表关系包括\*\*一对一\*\*、\*\*一对多\*\*和\*\*多对多\*\*,这些关系通过外键实现。 ###### 1、 \*\*一对一关系(One-to-One)\*\* \*\*特点\*\* - \*\*一个记录仅对应另一个表中的一个记录\*\*:例如,一个用户(User)只有一个详细资料(Profile)。 - \*\*实现方式\*\*:在任意一方添加唯一外键,指向另一方的主键。 \`\`\`sql -- 用户表 CREATE TABLE users ( user_id INT PRIMARY KEY, username VARCHAR(50) ); -- 资料表 CREATE TABLE profiles ( profile_id INT PRIMARY KEY, address VARCHAR(100), user_id INT UNIQUE, -- 唯一外键,关联users表的user_id ); create table student( id int unsigned auto_increment comment "主键", name varchar(50) not null comment "学生的名字", age tinyint unsigned not null comment "学生的年纪", sex tinyint unsigned not null default 1 comment "1代表男,0代表女", primary key(id) ); create table student_profile( height tinyint unsigned not null comment "学生的身高", id_num char(18) unique not null comment "学生的身份证号码", student_id int unsigned not null comment "存储学生的id" ); 张三 18 1 182 23412341234123412341234 \`\`\` ###### 2、\*\*一对多关系(One-to-Many)\*\* \*\*特点\*\* - \*\*一个记录对应多个记录\*\*:例如,一个部门(Department)可以有多个员工(Employee)。 - \*\*实现方式\*\*:在 "多" 的一方表中添加外键,指向 "一" 的一方的主键。 \`\`\`sql -- 部门表(一) CREATE TABLE departments ( dept_id INT PRIMARY KEY, dept_name VARCHAR(50) ); -- 员工表(多) CREATE TABLE employees ( emp_id INT PRIMARY KEY, emp_name VARCHAR(50), dept_id INT, -- 外键,关联departments表的dept_id ); -------------------------------------------------------------- create table department( id int unsigned auto_increment comment "主键", dept_name varchar(50) not null comment "部门的名称", leader varchar(50) not null comment "部门领导", information text not null comment "部门介绍", primary key(id) ); insert into department(dept_name, leader, information) values("人事部", "zhangsan", "adfadsadfadsfsaddf"); insert into department(dept_name, leader, information) values("财务部", "lisi", "adfadsadfadsfsaddf"); create table employees( id int unsigned auto_increment comment "主键", name varchar(50) not null comment "员工的名称", salary int unsigned not null comment "员工的工资", department_id int unsigned not null comment "部门的id", primary key(id) ); insert into employees(name, salary, department_id) values("小红", 8000, 1); insert into employees(name, salary, department_id) values("小花", 9000, 1); \`\`\` ###### 3、\*\*多对多关系(Many-to-Many)\*\* \*\*特点\*\* - \*\*多个记录对应多个记录\*\*:例如,一个学生(Student)可以选修多门课程(Course),一门课程也可以被多个学生选修。 - \*\*实现方式\*\*:通过创建中间表(关联表),将多对多拆分为两个一对多关系。 \`\`\`sql -- 学生表 CREATE TABLE students ( student_id INT PRIMARY KEY, student_name VARCHAR(50) ); -- 课程表 CREATE TABLE courses ( course_id INT PRIMARY KEY, course_name VARCHAR(50) ); -- 中间表(关联表) CREATE TABLE student_courses ( student_id INT, course_id INT, ); 学生管理系统: create table student2( id int unsigned auto_increment comment "主键", name varchar(50) not null comment "学生的名称", age tinyint unsigned not null comment "学生的年纪", sex tinyint unsigned not null default 1 comment "1代表男,0代表女", courses varchar(500) not null comment "学习选择的课程", primary key(id) ); insert into student2(name,age,sex, courses) values( "小红", 18, 1, "1\|2\|3" ); ================================== 优化版 ======================================= create table student3( id int unsigned auto_increment comment "主键", name varchar(50) not null comment "学生的名称", age tinyint unsigned not null comment "学生的年纪", sex tinyint unsigned not null default 1 comment "1代表男,0代表女", primary key(id) ); insert into student3(name,age,sex, courses) values( "小红", 18, 1 ); insert into student3(name,age,sex, courses) values( "小花", 18, 0 ); 小红id: 1 小花id: 2 create table student_course( student_id int unsigned not null comment "学生id", course_id int unsigned not null comment "课程id", ); insert into student_course(student_id, course_id) values(1, 1); 小红 计算机组成原理 insert into student_course(student_id, course_id) values(1, 2); 小红 操作系统 insert into student_course(student_id, course_id) values(1, 3); 小红 数据库理论 insert into student_course(student_id, course_id) values(2, 2); 小花 操作系统 insert into student_course(student_id, course_id) values(2, 3); 小花 数据库理论 create table course( id int unsigned auto_increment comment "主键", course_name varchar(50) not null comment "课程的名称", course_count int unsigned not null comment "课时", primary key(id) ); insert into course(course_name, course_count) values("计算机组成原理", 150); 1 insert into course(course_name, course_count) values("操作系统", 140); 2 insert into course(course_name, course_count) values("数据库理论", 30); 3 \`\`\` ### 六、查询 ###### 1. 条件 使用where子句对表中的数据筛选,结果为true的行会出现在结果集中 - 语法如下: \`\`\`sql select \* from 表名 where 条件; 例: select \* from students where id=1; create table student( id int unsigned auto_increment comment "主键", name varchar(50) not null comment "学生的名称", age tinyint unsigned not null comment "学生的年纪", gender tinyint unsigned not null default 1 comment "学生的性别,1代表男,0代表女", height tinyint unsigned not null comment "学生的身高", address varchar(500) not null comment "地址", primary key(id) ); insert into student(name,age,gender,height,address) values("小红", 18, 0, 182, "北京"); insert into student(name,age,gender,height,address) values("小花", 19, 0, 170, "长沙"); insert into student(name,age,gender,height,address) values("小绿", 20, 1, 160, "深圳"); insert into student(name,age,gender,height,address) values("小明", 30, 0, 182, "上海"); insert into student(name,age,gender,height,address) values("大明", 40, 1, 190, "新疆"); insert into student(name,age,gender,height,address) values("二明", 35, 1, 187, "西藏"); insert into student(name,age,gender,height,address) values("小蓝", 16, 0, 150, "长沙"); insert into student(name,age,gender,height,address) values("小紫", 16, 0, 150, "长沙"); insert into student(name,age,gender,height,address) values("大牛", 16, 1, 150, "上海"); insert into student(name,age,gender,height,address) values("如花", 16, 3, 150, "上海"); insert into student(name,age,gender,height,address) values("凤姐", 25, 0, 150, "上海"); \`\`\` - where后面支持多种运算符,进行条件的处理 - 比较运算符 - 逻辑运算符 - 模糊查询 - 范围查询 - 空判断 比较运算符 - 等于: = - 大于: \> - 大于等于: \>= - 小于: \< - 小于等于: \<= - 不等于: != 或 \<\> 例1:查询编号大于3的学生 \`\`\`sql select \* from students where id \> 3; \`\`\` 例2:查询编号不大于4的学生 \`\`\`sql select \* from students where id \<= 4; \`\`\` 例3:查询姓名不是"黄蓉"的学生 \`\`\`sql select \* from students where name != '黄蓉'; \`\`\` 例4:查询没被删除的学生 \`\`\`sql select \* from students where is_delete=0; \`\`\` 逻辑运算符 - and - or - not 例5:查询编号大于3的女同学 \`\`\`sql select \* from students where id \> 3 and gender=0; \`\`\` 例6:查询编号小于4或没被删除的学生 \`\`\`sql select \* from students where id \< 4 or is_delete=0; \`\`\` 模糊查询 - like - %表示任意多个任意字符 - % - _表示一个任意字符 例7:查询姓黄的学生 \`\`\`sql select \* from students where name like '黄%'; \`\`\` 例8:查询姓黄并且"名"是一个字的学生 \`\`\`sql select \* from students where name like '黄_'; \`\`\` 例9:查询姓黄或叫靖的学生 \`\`\`sql select \* from students where name like '黄%' or name like '%靖'; \`\`\` 范围查询 - in表示在一个非连续的范围内 例10:查询编号是1或3或8的学生 \`\`\`sql select \* from students where id in(1,3,8); \`\`\` - between ... and ...表示在一个连续的范围内 例11:查询编号为3至8的学生 \`\`\`sql select \* from students where id between 3 and 8; \`\`\` 例12:查询编号是3至8的男生 \`\`\`sql select \* from students where (id between 3 and 8) and gender=1; \`\`\` 空判断 - 注意:null与''是不同的 - 判空is null 例13:查询没有填写身高的学生 \`\`\`sql select \* from students where height is null; \`\`\` - 判非空is not null 例14:查询填写了身高的学生 \`\`\`sql select \* from students where height is not null; \`\`\` 例15:查询填写了身高的男生 \`\`\`sql select \* from students where height is not null and gender=1; \`\`\` 优先级 - 优先级由高到低的顺序为:小括号,not,比较运算符,逻辑运算符 - and比or先运算,如果同时出现并希望先算or,需要结合()使用 ###### 2. 排序 为了方便查看数据,可以对数据进行排序 语法: \`\`\`sql select \* from 表名 order by 列1 asc\|desc \[,列2 asc\|desc,...

```

说明

  • 将行数据按照列1进行排序,如果某些行列1的值相同时,则按照列2排序,以此类推

  • 默认按照列值从小到大排列(asc)

  • asc从小到大排列,即升序

  • desc从大到小排序,即降序

例1:查询未删除男生信息,按学号降序

```sql

select * from students where gender=1 and is_delete=0 order by id desc;

```

例2:显示所有的学生信息,先按照年龄从大-->小排序,当年龄相同时 按照身高从高-->矮排序

```sql

select * from students order by age desc,height desc;

```

3. 聚合函数

为了快速得到统计数据,经常会用到如下5个聚合函数

总数

  • count(*)表示计算总行数,括号中写星与列名,结果是相同的

例1:查询学生总数

```sql

select count(*) from students;

```

最大值

  • max(列)表示求此列的最大值

例2:查询女生的编号最大值

```sql

select max(id) from students where gender=2;

```

最小值

  • min(列)表示求此列的最小值

例3:查询未删除的学生最小编号

```sql

select min(id) from students where is_delete=0;

```

求和

  • sum(列)表示求此列的和

例4:查询男生的总年龄

```sql

select sum(age) from students where gender=1;

-- 平均年龄

select sum(age)/count(*) from students where gender=1;

```

平均值

  • avg(列)表示求此列的平均值

例5:查询未删除女生的编号平均值

```sql

select avg(id) from students where is_delete=0 and gender=2;

```

4. 分组

group by

  1. group by的含义:将查询结果按照1个或多个字段进行分组,字段值相同的为一组

  2. group by可用于单个字段分组,也可用于多个字段分组

```

gender count members

1 20 小红,小花,小紫....

0 30 大明,二明

```

group by + group_concat()

  1. group_concat(字段名)可以作为一个输出字段来使用,

  2. 表示分组之后,根据分组结果,使用group_concat()来放置每一组的某字段的值的集合

```sql

select gender from students group by gender;

+--------+

| gender |

+--------+

| 男 |

| 女 |

| 中性 |

| 保密 |

+--------+

select gender,group_concat(name) from students group by gender;

+--------+-----------------------------------------------------------+

| gender | group_concat(name) |

+--------+-----------------------------------------------------------+

| 男 | 彭于晏,刘德华,周杰伦,程坤,郭靖 |

| 女 | 小明,小月月,黄蓉,王祖贤,刘亦菲,静香,周杰 |

| 中性 | 金星 |

| 保密 | 凤姐 |

+--------+-----------------------------------------------------------+

select gender,group_concat(id) from students group by gender;

+--------+------------------+

| gender | group_concat(id) |

+--------+------------------+

| 男 | 3,4,8,9,14 |

| 女 | 1,2,5,7,10,12,13 |

| 中性 | 11 |

| 保密 | 6 |

+--------+------------------+

```

group by + 集合函数

  1. 通过group_concat()的启发,我们既然可以统计出每个分组的某字段的值的集合,那么我们也可以通过集合函数来对这个`值的集合`做一些操作

```sql

select gender,group_concat(age) from students group by gender;

+--------+----------------------+

| gender | group_concat(age) |

+--------+----------------------+

| 男 | 29,59,36,27,12 |

| 女 | 18,18,38,18,25,12,34 |

| 中性 | 33 |

| 保密 | 28 |

+--------+----------------------+

分别统计性别为男/女的人年龄平均值

select gender,avg(age) from students group by gender;

+--------+----------+

| gender | avg(age) |

+--------+----------+

| 男 | 32.6000 |

| 女 | 23.2857 |

| 中性 | 33.0000 |

| 保密 | 28.0000 |

+--------+----------+

分别统计性别为男/女的人的个数

select gender,count(*) from students group by gender;

+--------+----------+

| gender | count(*) |

+--------+----------+

| 男 | 5 |

| 女 | 7 |

| 中性 | 1 |

| 保密 | 1 |

+--------+----------+

gender avg_age

1 20

0 18

```

group by + having

  1. having 条件表达式:用来分组查询后指定一些条件来输出查询结果

  2. having作用和where一样,但having只能用于group by

```sql

select gender,count(*) from students group by gender having count(*)>2;

+--------+----------+

| gender | count(*) |

+--------+----------+

| 男 | 5 |

| 女 | 7 |

+--------+----------+

```

5. 获取部分行

当数据量过大时,在一页中查看数据是一件非常麻烦的事情

语法

```sql

select * from 表名 limit start,count

```

说明

  • 从start开始,获取count条数据

例1:查询前3行男生信息

```sql

select * from students where gender=1 limit 0,3;

```

示例:分页

  • 已知:每页显示m条数据,当前显示第n页

  • 求总页数:此段逻辑后面会在python中实现

  • 查询总条数p1

  • 使用p1除以m得到p2

  • 如果整除则p2为总数页

  • 如果不整除则p2+1为总页数

  • 求第n页的数据

```sql

select * from students where is_delete=0 limit (n-1)*m,m

```

6. 连接查询

当查询结果的列来源于多张表时,需要将多张表连接成一个大的数据集,再选择合适的列返回

mysql支持三种类型的连接查询,分别为:

  • 内连接查询:查询的结果为两个表匹配到的数据

  • 右连接查询:查询的结果为两个表匹配到的数据,右表特有的数据,对于左表中不存在的数据使用null填充

  • 左连接查询:查询的结果为两个表匹配到的数据,左表特有的数据,对于右表中不存在的数据使用null填充

```

需求:查询数据库获取小红的工资和部门信息。

select * from employees where id = 1;

select employees.id,employees.name,employees.salary,department.dept_name from employees

join department

on department.id = employees.department_id

where employees.id = 1;

select employees.id,employees.name,employees.salary,department.dept_name from employees

right join department

on department.id = employees.department_id

where employees.id = 1;

select employees.id,employees.name,employees.salary,department.dept_name from employees

left join department

on department.id = employees.department_id

where employees.id = 1;

select employees.id,employees.name,employees.salary,department.dept_name from employees join department

on department.id = employees.department_id

where employees.id = 3;

```

语法

```sql

select * from 表1 inner或left或right join 表2 on 表1.列 = 表2.列

```

例1:使用内连接查询班级表与学生表

```sql

select * from students inner join classes on students.cls_id = classes.id;

```

例2:使用左连接查询班级表与学生表

  • 此处使用了as为表起别名,目的是编写简单

```sql

select * from students as s left join classes as c on s.cls_id = c.id;

```

例3:使用右连接查询班级表与学生表

```sql

select * from students as s right join classes as c on s.cls_id = c.id;

```

例4:查询学生姓名及班级名称

```sql

select s.name,c.name from students as s inner join classes as c on s.cls_id = c.id;

```

七、Python操作MySQL

1. 安装 pymysql

```bash

pip install pymysql

```

2. 连接数据库

```python

import pymysql

连接数据库

conn = pymysql.connect(

host='localhost', # 主机名

user='your_username', # 用户名

password='your_password', # 密码

database='your_database', # 数据库名

charset='utf8mb4', # 字符集

cursorclass=pymysql.cursors.DictCursor # 返回字典格式的结果

)

try:

创建游标对象

with conn.cursor() as cursor:

执行 SQL 查询

sql = "SELECT VERSION()"

cursor.execute(sql)

获取单条数据

result = cursor.fetchone()

print(f"数据库版本: {result}")

finally:

关闭数据库连接

conn.close()

```

3. 创建表

```python

try:

with conn.cursor() as cursor:

创建 users 表

sql = """

CREATE TABLE IF NOT EXISTS users (

id INT PRIMARY KEY AUTO_INCREMENT,

name VARCHAR(50) NOT NULL,

age INT,

email VARCHAR(100) UNIQUE

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

"""

cursor.execute(sql)

提交事务

conn.commit()

print("表创建成功")

except Exception as e:

print(f"表创建失败: {e}")

回滚事务

conn.rollback()

```

4. 插入数据

```python

try:

with conn.cursor() as cursor:

插入单条数据

sql = "INSERT INTO users (name, age, email) VALUES (%s, %s, %s)"

cursor.execute(sql, ('Alice', 25, 'alice@example.com'))

插入多条数据

users = [

('Bob', 30, 'bob@example.com'),

('Charlie', 22, 'charlie@example.com')

]

sql = "INSERT INTO users (name, age, email) VALUES (%s, %s, %s)"

cursor.executemany(sql, users)

提交事务

conn.commit()

print(f"成功插入 {cursor.rowcount} 条数据")

except Exception as e:

print(f"数据插入失败: {e}")

conn.rollback()

```

5. 查询数据

```python

查询所有数据

try:

with conn.cursor() as cursor:

sql = "SELECT * FROM users"

cursor.execute(sql)

results = cursor.fetchall() # 获取所有记录

for row in results:

print(f"ID: {row['id']}, 姓名: {row['name']}, 年龄: {row['age']}, 邮箱: {row['email']}")

except Exception as e:

print(f"查询失败: {e}")

查询单条数据

try:

with conn.cursor() as cursor:

sql = "SELECT * FROM users WHERE id = %s"

cursor.execute(sql, (1,))

result = cursor.fetchone() # 获取单条记录

print(f"ID为1的用户: {result}")

except Exception as e:

print(f"查询失败: {e}")

```

6. 更新数据

```python

try:

with conn.cursor() as cursor:

sql = "UPDATE users SET age = age + 1 WHERE name = %s"

cursor.execute(sql, ('Alice',))

提交事务

conn.commit()

print(f"成功更新 {cursor.rowcount} 条数据")

except Exception as e:

print(f"数据更新失败: {e}")

conn.rollback()

```

7. 删除数据

```python

try:

with conn.cursor() as cursor:

sql = "DELETE FROM users WHERE age < %s"

cursor.execute(sql, (25,))

提交事务

conn.commit()

print(f"成功删除 {cursor.rowcount} 条数据")

except Exception as e:

print(f"数据删除失败: {e}")

conn.rollback()

```

8. 使用上下文管理器管理连接

为了简化资源管理,可以将数据库连接封装成上下文管理器:

```python

class MySQLConnection:

def init(self, host, user, password, database):

self.host = host

self.user = user

self.password = password

self.database = database

self.conn = None

def enter(self):

self.conn = pymysql.connect(

host=self.host,

user=self.user,

password=self.password,

database=self.database,

cursorclass=pymysql.cursors.DictCursor

)

return self.conn

def exit(self, exc_type, exc_val, exc_tb):

if self.conn:

self.conn.close()

使用示例

with MySQLConnection('localhost', 'user', 'password', 'dbname') as conn:

with conn.cursor() as cursor:

cursor.execute("SELECT * FROM users")

results = cursor.fetchall()

for row in results:

print(row)

```

9. 处理数据库事务

```python

try:

with conn.cursor() as cursor:

开始事务

conn.begin()

执行多个操作

cursor.execute("INSERT INTO users (name, age) VALUES (%s, %s)", ('David', 28))

cursor.execute("UPDATE users SET age = age + 1 WHERE name = 'Bob'")

提交事务

conn.commit()

print("事务提交成功")

except Exception as e:

回滚事务

conn.rollback()

print(f"事务回滚: {e}")

```

```

create table blog(

id int unsigned not null auto_increment comment "主键",

title varchar(200) not null comment "文章标题",

authoer varchar(50) not null comment "文章作者",

description varchar(500) not null comment "文章摘要",

content text not null comment "内容",

primary key(id)

)charset=utf8;

```

相关推荐
belldeep2 小时前
本草纲目:如何应用 PostgreSQL 实现【中医药】主题数据库 ?
数据库·postgresql·本草纲目
Bert.Cai2 小时前
MySQL CURTIME()函数详解
数据库·mysql
Bert.Cai2 小时前
MySQL CURDATE()函数详解
数据库·mysql
NGSI vimp3 小时前
MySQL|MySQL 中 `DATE_FORMAT()` 函数的使用
数据库·mysql
秋93 小时前
MySQL8.0.46 与 MySQL8.4.9:跨越代际的深度差异解析与升级全指南
mysql
HAWK eoni3 小时前
Mysql 驱动程序
数据库·mysql
二哈赛车手3 小时前
新人笔记---实现简易版的rag的bm25检索(利用ES),以及RAG上传时的ES与向量数据库双写
java·数据库·笔记·spring·elasticsearch·ai
xxjj998a3 小时前
Laravel4.x核心特性全解析
android·mysql·laravel
何中应3 小时前
CentOS 7安装、卸载MySQL数据库(二)
数据库·mysql·centos