数据库操作
一、前置回顾(承接上节)
- 数据库初阶 = MySQL 数据库 ,是一类软件的统称。
- Oracle、MySQL、SQL Server、SQLite → 关系型数据库,通过「表」组织数据。
- 很多行,每一行都有固定的列 → 对数据的格式要求非常严格。
- MySQL 是一个客户端-服务器 结构的程序。
- 主动发起通信的一方 => 客户端 ;被动接受的一方 => 服务器。
- 客户端给服务器发送的数据 => 请求 ;服务器给客户端返回的数据 => 响应。
- 服务器的两个特性:1) 要给多个客户端提供服务;2) 通常要 7×24 小时运行。
- MySQL 服务器是「本体」(存储、组织数据的部分)。服务器通常没有用户界面,因此只能看到命令行这样的程序(8.0)。
- MySQL 客户端种类很多:
-
官方自带命令行客户端 (非常广泛使用,重点掌握)------适合「专业人士」使用。
-
界面形如:
textEnter password: **** Welcome to the MySQL monitor. Commands end with ; or \g. Server version: 8.0.42 MySQL Community Server - GPL Copyright (c) 2000, 2025, Oracle and/or its affiliates. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql>
-
-
官方自带的图形化客户端:MySQL Workbench 8.0 CE。
-
第三方的图形化客户端:Navicat Premium Lite。
-
- idea、vscode 也都自带 MySQL 的图形化客户端......
二、MySQL 初阶主要学什么?
- SQL 编程语言 (如何和数据库服务器之间进行交互)
- 其他关系型数据库都支持 SQL 这一套语言;虽然不同数据库的 SQL 语法细节支持略有差异,90% 以上的内容都是一致的。
- 对于「非关系型数据库」通常不能直接支持 SQL(NoSQL)。
- MySQL 相关的一些核心面试题:索引、事务。
- 如何在 Java 程序中操作数据库。
三、SQL
- SQL(Structured Query Language)是结构化查询语言的简称。
- SQL 的风格和 C/Java 差距非常大:
- 命令式语言:需要开发者明确说清楚,每一步都做什么。
- 声明式语言:开发者只描述「我想要啥」,至于东西是咋来的、中间的过程,开发者不关心。
- SQL 本身语法规则并不复杂。
3.2 SQL 分类
- DDL (Data Definition Language,数据定义语言):用来维护存储数据的结构。代表指令:
create、drop、alter。 - DML (Data Manipulation Language,数据操纵语言):用来对数据进行操作。代表指令:
insert、delete、update、select。 - DCL (Data Control Language,数据控制语言):主要负责权限管理和事务。代表指令:
grant、revoke、commit。 - 不需要记住这些分类,只需要知道常用的 SQL 怎么写即可。
关于学习 SQL
暴论:SQL 语法是可以速成的~~
- 可以(速成),但没必要(面试一般不考语法层面的东西)。
四、库的操作
注意理解「数据库」这个词的差别:
- 之前谈的数据库:一类软件。
- 此处的数据库:只是一种数据集合。
结构示意:
text
客户端 ───────▶ 服务器(主机)
◀─────── └─ 服务器(程序)── 存储数据操作
数据库(逻辑上的数据集合)
- 数据库和数据库之间,里面的数据是「互不相关」的。
- 能否存储「多类数据」(站在业务的角度):完全可以把这些不同的数据,存储在同一个机器、同一个数据库服务器程序中(常见做法)。
MySQL 的数据库服务器程序,对于数据是这样管理的:
- 一个数据库服务器程序,可以存储多个「数据库」逻辑集合。
- 一个数据库逻辑集合,里面可以存储多个数据表。
- 一个数据表,里面可以包含很多记录(每个记录对应一行、一条数据)。
- 一个记录中,可以包含很多列(每个列也称为一个字段 / 属性)。
创建 / 查看 / 选中 / 删除数据库,都可以通过 SQL 这样的编程语言来操作。
1. 创建数据库
sql
create database 数据库名字;
create、database是关键字。- 注意事项:
- 确保关键字英文拼写不要写错。
- 单词之间至少要有一个空格。
- SQL 中的关键字不区分大小写(还是区分比较好,但 SQL 是一个非常古老的编程语言;个人建议写成「小写」)。
- 在同一个数据库服务器中,创建的数据库名字不能重复。
- 数据库的名字不能和 SQL 的关键字重复。典型例子:
order(既是 SQL 关键字「排序」,又有「订单」的意思)。
语法:
sql
CREATE DATABASE [IF NOT EXISTS] 数据库名 [create_option] ...
IF NOT EXISTS:不存在时才创建。使用之后,即使数据库已经存在也不会报错。- 给数据库名字加上反引号 `````,就可以绕开关键字的限制,顺利创建出数据库。
- 反引号:1) 英文模式;2) 键盘左上角,和
~是同一个按键。
- 反引号:1) 英文模式;2) 键盘左上角,和
- 在命令行的客户端中,可以通过向上的方向键切到上一条 SQL。
常见报错:
text
mysql> create database java119;
ERROR 1007 (HY000): Can't create database 'java119'; database exists
mysql> create database if not exists java119;
Query OK, 1 row affected, 1 warning (0.01 sec)
text
mysql> CREATE DATABASE java119;
ERROR 1007 (HY000): Can't create database 'java119'; database exists
text
mysql> create database order
(order 与关键字冲突)
mysql> create database java119;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds
to your MySQL server version for the right syntax to use near 'create database jav...
- 学习阶段,SQL 是「一条一条」手动输入 / 执行的。
- 真实的开发中,通常都是把 SQL 提前写到一个文件中,批量执行 。
- 批量执行的场景下,其中任何一个 SQL 报错,都会使批量执行停下来。
字符集详解(重点)
create_option 中的字符集相关选项:
sql
[DEFAULT] { CHARACTER SET [=] charset_name
| COLLATE [=] collation_name
| ENCRYPTION [=] {'Y' | 'N'} }
- 字符集 / 字符编码,是专业的开发者与非专业之间对字符集理解的重要分水岭。
问题:在计算机中,一个汉字占几个字节??
-
这取决于你当前使用的字符集是什么。
-
很多同学脱口而出「2 个」(错误)。只要你回答出具体数字,都一定是错误的。
-
计算机表示字符,就是通过数字。
-
ASCII:只使用一个字节进行编码,实际能表示的范围非常有限,只能表示英文字母 + 阿拉伯数字 + 标点符号。
-
汉字的种类太多了:日常常用汉字 4000 多个,算上各种生僻字 5-6w 个。还是用数字表示汉字,但要建立更大的表。
-
一种典型做法:GBK 编码(国内一度非常流行的编码方式),使用 2 个字节表示一个汉字。
- 2 个字节表示的数字范围 0~65535。
- Windows 简体中文版默认的字符编码方式就是 GBK。
- 学习 C 阶段,打印
strlen=> 2。
-
放眼全世界,语言文字的种类更多了:少数民族的语言文字有蒙文、满文、藏文......
-
UTF-8 变长编码:
- 一个字符可能是 1~4 个字节 => 全世界最主流的编码方式。
- 全世界所有的语言文字都能被囊括其中。
- 汉字在 UTF-8 体系中通常占用 3 个字节。
- 具体码表长啥样?一个汉字对应的 GBK / UTF8 数值是啥?这样的表比较大。
小结:
- 一个汉字几个字节 => 编码方式。
- 编码方式约定了一个大表格,每个汉字 / 字符使用怎样的数字来表示。
- 编码方式有很多种,不同的方式下表示细节也不同。
- UTF-8 是当下最主流的编码方式。
- MySQL 8.0 中默认使用
utf8作为编码方式。 - MySQL 5 系列中默认使用拉丁文作为编码方式(引起中文乱码)。
- Java 中默认使用 UTF-16 编码方式(UTF-8 的变种),也是固定 2 个字节表示一个文字。
进制对照示例:
| 字符 | 编码(10 进制) | 编码(16 进制) |
|---|---|---|
| 你 | 20320 | 4F60 |
| 好 | 22909 | 597D |
- 一个 16 进制数字对应 4 bit;两个 16 进制数字对应 8 bit => 1 byte。
- Unicode 编码(16 进制)也是一种编码方式,UTF-8 基于 Unicode 展开。
字符集的细节补充:
- 实际上 MySQL 中的 utf8 是一个「残废」,是不完整的版本 ,典型的就是缺失 emoji。
- 教务系统上提交作业时,如果你的作业中包含了类似这种 emoji 的字符,作业就会提交失败。
- utf8mb4 => 完全体的 utf8。
2. 查看数据库
sql
show databases;
-
输出示例:
text+--------------------+ | Database | +--------------------+ | information_schema | | java117 | | java117_2 | | java117_3 | | java118 | | java118_2 | | java119 | | mysql | | performance_schema | | store | | sys | | test | +--------------------+ -
information_schema、mysql、performance_schema、sys等是自带的数据库,保存了 MySQL 服务器这边的一些配置信息(数据库高阶)。 -
一旦列表比较长、比较杂,命令行客户端就不太方便输入。
3. 选中数据库
- 当前已经有多个数据库了,选中某个数据库之后,后续针对数据表的操作就围绕这个数据库来展开。
sql
use 数据库名;
- 执行结果:
Database changed - 非常类似于 RTS 类游戏的选中单位 => 发起命令。
- 在 Navicat 中,选中 SQL 之后
ctrl + r就能快速运行选中的 SQL。
4. 删除数据库
sql
drop database 数据库名;
- 这是一个非常危险的操作!! 一旦删除,数据就还原不回来了!!
- 当前阶段,自己在电脑上怎么搞都行;但是在公司的机器上(生产环境上)千万不要乱操作!!
- 很可能一个操作,你的饭碗就没了,甚至搞不好会「进去」。
- 公司的数据库中,通常是非常重要、非常宝贵的数据。万一删错了、把不该删的「重要数据」给删了 => 非常严重的后果,毁灭性打击。
- 从「删库」到「跑路」。
公司中接触的几类环境:
- 办公环境:往往就是普通的笔记本(台式机),少数公司可能发 mac(装逼神器,mac 上没法打游戏)。
- 开发环境:写代码、调试代码的环境。简单项目里开发环境 == 办公环境;复杂项目里开发环境是单独的服务器,用办公机远程连接到服务器上开发(很可能你开发的程序,一启动就吃掉 100G 内存~~ )。
- 测试环境:和开发环境差不多。
- 生产环境 / 线上环境 :一组专门的服务器,给外面的用户提供真实服务,这里的 bug 都能被真实用户感知到;生产环境也有专门的数据库,保存真实用户的数据。
- 这里的数据库也需要,但上面的数据一般都是构造的「假数据」。
既然数据库这么重要,如何保证数据库不被「误删除」??
- 对数据库的权限进行明确限制 (主流数据库都支持一套「权限体系」)。
- 老员工承担「管理员」的角色,给其他人分配不同权限的用户 => DBA 数据库管理员。
- 对数据进行及时备份 。
- 即使有数据出现问题,还可以通过备份来还原。
- 备份得越频繁,成本更高;备份得越不频繁,还原数据时的数据偏差更大。
- 确实需要你真正进行数据库的危险操作时 (尤其是针对生产环境操作):
- 不要自己「咋呼咋搞」,而是拉一个老员工和你一起。
- 一旦出问题,你的饭碗基本就丢了。
- 很多公司入职时会给你分配一个导师(导师并不会真的教你啥东西,更不会给你上课......)。
- 但如果你闯出祸来,导师往往要「连坐」;如果没有导师,就找你的领导。
五、LLM 操作数据库
-
数据库的命令行客户端 => 由文本构成。
-
对于图形化的客户端,对于「多模态」的大模型也能操作。
-
命令行客户端的入口示例:
text$ mysql -h 127.0.0.1 -P 3306 -u root -p2222 -e "SHOW DATABASES;"text$ & 'C:\Program Files\MySQL\MySQL Server 8.0\bin\mysql.exe' -h 127.0.0.1 -P 3306 -u root -p2222 ` -e "CREATE DATABASE java119 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; SHOW CREATE DATABASE java119;" 2>&1执行后会出现警告:
mysql: [Warning] Using a password on the command line interface can be insecure. -
LLM 对于数据库操作非常在行。
- 未来会有一些比较复杂的查询操作。
- 这样的操作最多只在开发环境 / 测试环境 执行,不敢让 LLM 直接操作生产环境!!
- LLM 是可能有幻觉的:万一 LLM 理解错了,给你搞个删库操作 => 后果非常严重。
- LLM 没法替人去坐牢。
-
LLM 能否替代程序员??
- 一定无法完全替代。
- LLM 不能承担责任。
- LLM 会大幅度减少社会上程序员的数量。
-
命令行程序 => 专业人士 / 生产力工具 => 天然和 LLM 结合。
-
图形化程序 => 非专业人士 / 降低上手门槛。
- 业界目前有一种风潮:把当前的一些图形化程序开发出对应的命令行版本。其中有 PS、飞书(钉钉?)→ 飞书 CLI(命令行版本的飞书)。
- 无奈之举:GUI 程序不好直接操作。
-
MCP:一种「客户端-服务器」通信的方式,用来实现 LLM 的控制。
- 24 年 12 月左右 MCP 被提出,刚提出来的时候很火。
- 确实挺有用,但缺点非常明显:每增加一个 MCP 都会占用一部分上下文空间。
- 现在业界对 MCP / skill 的态度和以前不一样:以前是「多多益善」,要做更强的工程化;现在则是要「节制、克制」,更多的能力交给 LLM 本身(LLM 现在也比之前强太多了)。
-
同样是操作 MySQL,现在看到的情况非常顺(准确率、速度都非常好);去年 6 月左右,当时使用 LLM 操作 MySQL 就比较费劲。
-
理解了 SQL,正确地指挥 LLM ~~ 操作者决定了 LLM 的上限 ~~
- 一个 LLM 通常有很多很多的参数。
- 一次响应过程中只激活其中的一部分操作(与提示词直接相关)。
六、数据类型
数据库表操作 => 数据类型。
- 数据类型,就是对数据进行了不同的分类。
- 不同的类型,支持的动作 / 操作是不同的。
- 通过类型表示。
常见数值类型(部分):
| 类型 | 大小 | 说明 |
|---|---|---|
BIT[(M)] |
bit | 位值类型,M 表示每个值的位数(1~64) |
TINYINT[(M)] |
1 byte | 相当于 Java 的 byte |
BOOL |
1 byte | 布尔 |
SMALLINT[(M)] |
2 byte | short |
MEDIUMINT[(M)] |
3 byte | --- |
INT[(M)] |
4 byte | int |
INTEGER[(M)] |
4 byte | INT[(M)] 的同义词 |
BIGINT[(M)] |
8 byte | long |
FLOAT[(M,D)] |
4 byte | 单精度浮点型 |
DOUBLE[(M,D)] |
8 byte | 双精度浮点型 |
DECIMAL[(M[,D])] |
动态 | 不存在精度损失 |
-
数字类型 :如果需要表示「位图」这样的结构,就可以使用
bit。上述对应 Java 的 bit / byte / short / int / long。 -
SQL 太古老了,上古时期对于类型叫什么名字还没有达成「共识」。
-
上面这些都是「有符号类型 」,还有一类「无符号类型 」
unsigned。- 比较鸡肋,很多时候不推荐使用,特别容易溢出,相减时也有问题(负数)。
- MySQL 官方文档中明确表述不推荐使用无符号类型(但仍支持)。
-
float/double都存在精度问题:textif (0.1 + 0.2 == 0.3) // false -
Decimal能够精确表示小数。- 代价:消耗更多的空间存储,计算时消耗更多的时间。