1. SQL语句基础

1.2 SQL简介

  • SQL:结构化查询语言(Structured Query Language),在关系型数据库上执行数据操作、数据检索以及数据维护的标准语言。使用SQL语句,程序员和数据库管理员可以完成如下的任务

    • 改变数据库的结构

    • 更改系统的安全设置

    • 增加用户对数据库或表的许可权限

    • 在数据库中检索需要的信息

    • 对数据库的信息进行更新

1.3 SQL语句分类

  • MySQL致力于支持全套ANSI/ISO SQL标准。在MySQL数据库中,SQL语句主要可以划分为以下几类

    • DDL(Data Definition Language):数据定义语言,定义对数据库对象(库、表、列、索引)的操作,如:CREATE、DROP、ALTER、RENAME、 TRUNCATE等

    • DML(Data Manipulation Language): 数据操作语言,定义对数据库记录的操作,如:INSERT、DELETE、UPDATE、SELECT等

    • DCL(Data Control Language): 数据控制语言,定义对数据库、表、字段、用户的访问权限和安全级别,如:

      • GRANT、REVOKE等

      • Transaction Control:事务控制

      • COMMIT、ROLLBACK、SAVEPOINT等

1.4 SQL语句的书写规范

  • 在数据库系统中,SQL语句不区分大小写(建议用大写) ,但字符串常量区分大小写

  • SQL语句可单行或多行书写,以“;”结尾。

  • 关键词不能跨多行或简写。

  • 用空格和缩进来提高语句的可读性。

  • 子句通常位于独立行,便于编辑,提高可读性。

  • 注释:

    • /* */ 和// 为多行注释

    • -- 和 # 为单行注释

2. 数据库操作

2.1 数据库的登录及退出

  • 登录格式

mysql  -u用户名  -h服务器的主机地址 -p密码 -A

分析

  • u 后面跟登录数据库的用户名,这里使用root

  • -h 后面的参数是服务器的主机地址,在这里客户端和服务器在同一台机器上,所以输入 localhost 或者 IP 地址

  • -p 后面是用户登录密码,注意:==-p 和密码之间没有空格。如果出现空格,系统将不会把后面的字符串当成密码来对待==,没有密码时不写

  • -A参数:不预读数据库信息,加上该参数则不预读数据库中的表等信息,不会有表名及列名的补全,但读取速度会加快,不加该参数可能使用数据库时出现下列提示(不影响使用)

Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

  • 显示信息解释:

    • Commands end with; or\g:mysql 命令是以分号(;)或“\g”来结束的,遇到这个结束符就开始执行命令

    • Your MySQL connection id is 22:数据库的连接次数

    • Server version: 8.0.37 Source distribution : 版本

    • Type 'help;' or '\h' for help:输入”help;“或者”\h“可以看到帮助信息

    • Type '\c' to clear the current input statement:表示遇到”\c“就清除前面的命令,注意不是清屏

  • 退出:exit quit \q

PS C:\Users\Administrator> mysql  -uroot -p
Enter password: ******
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 20
Server version: 8.0.37 MySQL Community Server - GPLCopyright (c) 2000, 2024, Oracle and/or its affiliates.Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql>\q# 注意:带有密码登录,会有警告,提示不安全
PS C:\Users\Administrator> mysql  -uroot -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 21
Server version: 8.0.37 MySQL Community Server - GPLCopyright (c) 2000, 2024, Oracle and/or its affiliates.Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql>

2.2 查看数据库

  • 格式
mysql> show databases  [like  条件];    # 注意有s
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)
  • MySQL自带数据库
  • Information_schema: 主要存储了系统中的一些数据库对象信息,如:用户表信息、列信息、权限信息、字符集信息、分区信息等。(数据字典表)

  • performance_schema:主要存储数据库服务器的性能参数

  • mysql: 存储了系统的用户权限信息及帮助信息

  • sys: 5.7新增,之前版本需要手工导入。这个库是通过视图的形式把information_schema 和performance_schema结合起来,查询出更加令人容易理解的数据

  • 使用条件查看
mysql> show databases  like  'sys';
+----------------+
| Database (sys) |
+----------------+
| sys            |
+----------------+
1 row in set (0.00 sec)
  • 带有通配符的条件
  • %:匹配任意零个或多个字符

  • _ :匹配任意单个字符

mysql> show databases  like  's%';
+---------------+
| Database (s%) |
+---------------+
| sys           |
+---------------+
1 row in set (0.00 sec)
  • 显示时间
mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2023-02-10 09:39:14 |
+---------------------+
1 row in set (0.00 sec)
  • 显示数据库版本
mysql> select version();
+-----------+
| version() |
+-----------+
| 8.0.37    |
+-----------+
1 row in set (0.00 sec)

2.3 创建数据库

  • 格式

create  database  数据库名

  • 示例

mysql> create database testdb;
Query OK, 1 row affected (0.00 sec)mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| testdb             |
+--------------------+
  • 如数据库已存在,则报错

mysql> create database testdb;
ERROR 1007 (HY000): Can't create database 'testdb'; database exists
  • 查看创建数据哭的语句

# 格式
show  create database 数据库名

 

mysql> show create database testdb;
+----------+----------------------------------------------------------------------------------------------------------------------------------+
| Database | Create Database                                                                                                                  |
+----------+----------------------------------------------------------------------------------------------------------------------------------+
| testdb   | CREATE DATABASE `testdb` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */ /*!80016 DEFAULT ENCRYPTION='N' */ |
+----------+----------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)# 分析:
# 上述显示创建数据库语句的内容可看做3段内容# CREATE DATABASE `testdb` :表示创建数据库testdb# /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */ :表示注释内容,显示字符集采用utf8mb4方案,一个字符需要 1 ~ 4 个字节。可以存储一些 emoji 表情; utf8mb4_0900_ai_ci表示字符比较规则即ai为不区分重音,ci为不区分大小写# /*!80016 DEFAULT ENCRYPTION='N' */ 表示数据库未加密
  • 注意:再创建数据库或查看创建数据库语句时,database没有s

2.4 mysql中的反引号

  • 上例中查看的sql语句有反引号,其作用可以避免一些与SQL语法冲突的问题,同时可以使代码更加规范化和易读性更强

  • select name, address from table; 其中table若当做表名但其为关键字回报错,加上反引号可以避免与SQL关键字的冲突:

mysql> select name, address from `table`;
  • 注意:

  • 只有保留关键字和特殊字符需要使用反引号,普通的表名和列名不需要

  • 数据类型之间可以加或者不加反引号,但为了代码规范化,建议加上

2.5 切换数据库

查看当前使用的数据库,格式:

select  database();

注意: 当前没有使用数据库,则显示空

mysql> select  database();
+------------+
| database() |
+------------+
| NULL       |
+------------+

选择数据库格式

use  数据库名
mysql> use testdb;
Database changed
mysql> select database();   # 再次查看
+------------+
| database() |
+------------+
| testdb     |
+------------+

2.6 查看当前用户

mysql> select user();
+----------------+
| user()         |
+----------------+
| root@localhost |
+----------------+

2.7 删除数据库

格式:

drop database 数据库名

示例:

mysql> drop database testdb;
Query OK, 0 rows affected (0.01 sec)mysql> show  databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+

2.8 小结

# 新建数据库
create database 数据库名# 设为当前数据库
use  数据库名# 查看当前使用的数据库
select  database();# 显示所有数据库
show  databases;# 删除数据库
drop database 数据库名# 查看当前登录的用户及主机名
select user();

2.9 习题

  • 创建temp1、temp2数据库,查看所有数据库,使用temp1数据库,删除所有数据库

见文章MySQL库表操作-数据库操作练习-CSDN博客

3. MySQL字符集

   MySQL字符集包括字符集(CHARACTER)和排序规则(校对规则)(COLLATION)两个概念

3.1 字符集

  • Character Set(字符集):是字符的编码规则,规定了字符在数据库中的存储格式,比如占多少空间,支持哪些字符等

  • 不同的字符集有不同的编码规则,在运维和使用MySQL数据库中,选取合适的字符集非常重要,如果选择不恰当,轻则影响数据库性能,严重的可能导致数据存储乱码

  • mysql 5.7的默认字符集是latin1,而8.0中是utf8mb4;

  • mysql8的库表创建以及程序中尽可能使用utf8mb4字符集(可支持emoji)

  • mysql中的utf8字符集是utf8mb3字符集的别名,避免使用

latin1支持西欧字符、希腊字符等gbk支持中文简体字符,但是不是国际通用字符集big5支持中文繁体字符utf8几乎支持世界所有国家的字符。utf8mb4完全兼容UTF-8,用四个字节存储更多的字符

3.2 字符序

  • 字符序就是字符排序的规则集合

  • 如:使用A>B>a>b的规则来进行排序或者另一种规则a>b>A>B顺序排序

  • 字符序主要对字符的排序有影响

3.3 查看MySQL字符集

  • 查看所有支持的字符集
# 格式1:
mysql> show character set;  
+----------+---------------------------+---------------------+--------+
| Charset  | Description               | Default collation   | Maxlen |
+----------+---------------------------+---------------------+--------+
| armscii8 | ARMSCII-8 Armenian        | armscii8_general_ci |      1 |
| ascii    | US ASCII                  | ascii_general_ci    |      1 |
| big5     | Big5 Traditional Chinese  | big5_chinese_ci     |      2 |
| binary   | Binary pseudo charset     | binary              |      1 |
…………
# 字段含义# Charset: 字符集的名称;# Description:字符集的简单描述;# Default collation:该字符集的默认字符序;# Maxlen:该字符集中字符最大存储长度。# 或者使用\g替代定界符分号
mysql> show character set\g

 

# 格式2:
# \G表示将查询结果进行按列打印,即将查到的结构旋转90度变成纵向显示,不需要分号
mysql> show character set\G
*************************** 1. row ***************************Charset: armscii8Description: ARMSCII-8 Armenian
Default collation: armscii8_general_ciMaxlen: 1
*************************** 2. row ***************************Charset: asciiDescription: US ASCII
Default collation: ascii_general_ciMaxlen: 1
*************************** 3. row ***************************Charset: big5Description: Big5 Traditional Chinese
Default collation: big5_chinese_ciMaxlen: 2
*************************** 4. row ***************************Charset: binaryDescription: Binary pseudo charset
Default collation: binaryMaxlen: 1
……
  • 查看指定字符集
mysql> show character set like 'gbk';
+---------+------------------------+-------------------+--------+
| Charset | Description            | Default collation | Maxlen |
+---------+------------------------+-------------------+--------+
| gbk     | GBK Simplified Chinese | gbk_chinese_ci    |      2 |
+---------+------------------------+-------------------+--------+
1 row in set (0.00 sec)mysql> show character set like 'utf%';
+---------+------------------+--------------------+--------+
| Charset | Description      | Default collation  | Maxlen |
+---------+------------------+--------------------+--------+
| utf16   | UTF-16 Unicode   | utf16_general_ci   |      4 |
| utf16le | UTF-16LE Unicode | utf16le_general_ci |      4 |
| utf32   | UTF-32 Unicode   | utf32_general_ci   |      4 |
| utf8mb3 | UTF-8 Unicode    | utf8mb3_general_ci |      3 |
| utf8mb4 | UTF-8 Unicode    | utf8mb4_0900_ai_ci |      4 |
+---------+------------------+--------------------+--------+

3.4 查看MySQL字符序

  • MySQL字符序命名规则

    • 以字符序对应的字符集名称开头

    • 以国家名居中(或以general居中)

    • 后缀:

      • bin:二进制;

      • ci:大小写不敏感;

      • cs:大小写敏感;

      • ai:口音(Accent)不敏感;

      • as:口音敏感;

      • ks:假名(Kanatype)敏感

  • 查看支持的字符序

mysql> show collation;# 字段含义# Collation:字符序名称;# Charset:该字符序关联的字符集;# Id:字符序ID;# Default:该字符序是否是所关联的字符集的默认字符序。armscii8_general_ci就是armscii8的默认字符序,而armscii8_bin就不是;# Compiled:字符集是否已编译到服务器中;# Sortlen:这与对以字符集表示的字符串进行排序所需的内存量有关;# Pad_attribute:这表明了字符序在比较字符串时对末尾padding的处理。NO PAD表明在比较字符串时,末尾的padding也会考虑进去,否则不考虑。

指定条件查询:

mysql> show collation where charset = "utf8mb4";

3.5 查看 当前字符集的设置

  • 通过变量查看

mysql> show variables like 'character_set%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8mb4                    |
| character_set_connection | utf8mb4                    |
| character_set_database   | utf8mb4   # 重要            |
| character_set_filesystem | binary                     |
| character_set_results    | utf8mb4                    |
| character_set_server     | utf8mb4   # 重要            |
| character_set_system     | utf8mb3                    |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
  • 变量含义

character_set_client:MySQL客户端的字符集。
character_set_connection:数据通信链路字符集,当MySQL客户机向服务器发送请求时,请求数据以该字符集进行编码。
character_set_database:数据库默认使用的字符集。
character_set_filesystem:MySQL服务器文件系统字符集,该值是固定的binary。
character_set_results:服务器返回给客户端的结果使用的字符集。
character_set_server:服务器默认的字符集。
character_set_system:服务器存储元数据使用的字符集。

3.6 utf8和utf8mb4的区别

  • MySQL在5.5.3之后增加了这个utf8mb4的编码,mb4就是most bytes 4的意思,专门用来兼容四字节的unicode。好在utf8mb4是utf8的超集,除了将编码改为utf8mb4外不需要做其他转换。当然,为了节省空间,一般情况下使用utf8也就够了。

  • 既然utf8能够存下大部分中文汉字,那为什么还要使用utf8mb4呢? 原来mysql支持的 utf8 编码最大字符长度为 3 字节,如果遇到 4 字节的宽字符就会插入异常了。三个字节的 UTF-8 最大能编码的 Unicode 字符是 0xffff,也就是 Unicode 中的基本多文种平面(BMP)。也就是说,任何不在基本多文本平面的 Unicode字符,都无法使用 Mysql 的 utf8 字符集存储。包括 Emoji 表情(Emoji 是一种特殊的 Unicode 编码,常见于 ios 和 android 手机上),和很多不常用的汉字,以及任何新增的 Unicode 字符,如表情等等(utf8的缺点)。

  • 因此在8.0之后,建议大家使用utf8mb4这种编码。

4. 数据库对象

4.1 组成

4.2 数据库对象的命名规则

  • 命名使用具有意义的英文词汇,词汇中间以下划线分隔

  • 名称由字母、数字、#、下划线、$组成,必须以英文字母开头

  • 不要使用MySQL的保留字

  • 所有数据库对象使用小写字母,实际上MySQL中是可以设置大小写是否敏感的,为了保证统一性应使用小写表示

  • 在同一个数据库对象集合内对象不能同名

4.3 生产中对象命名规范

  • 数据库

    • 数据库命名尽量不超过30个字符

    • 数据库命名一般为项目名称+代表库含义的简写,比如IM项目的工作流数据库,可以是 im_flow

    • 命名应使用小写

    • 常规表:以t_开头,t代表table的意思,命名规则即 t + 模块(包含模块含义的简写)+ 表(包含表含义的简写),比如用户模块的教育信息表:t_user_eduinfo

    • 临时表:temp前缀+模块+表+日期后缀:temp_user_eduinfo_20240520

    • 备份表(用于保存和归档历史数据或者作为灾备恢复的数据)命名规则,bak前缀+模块+表+日期后缀:bak_user_eduinfo_20231219

    • 同一个模块的表尽可能使用相同的前缀,表名称尽可能表达含义

    • 多个单词以下划线 _ 分隔

    • 常规表表名尽量不超过30个字符,temp表和bak表视情况而定,也尽量简短为宜,命名应使用小写

5. 表的基本操作

5.1 数据类型

  • 类型组成:数字、文本、日期/时间类型

  • 整型

数据类型字节数带符号值范围不带符号值范围
tinyint1[-128,[127][0,255]
smallint2[-32768,32767][0,65535]
mediumint3[-8388608,8388607][0,16777215]
int4[-2147483648,2147483647][0,4294967295]
bigint8[-9223372036854775808,9223372036854775807][0,18446744073709551616]

- 注意:
  实际开发的角度,一定要为合适的列选取合适的数据类型,如

  •     一个枚举字段只有0和1两个枚举值,选用TINYINT就足够了,但在开发场景下却使用了BIGINT,这就造成了资源浪费
  •     简单计算一下,假使该数据表中有100W数据,那么总共浪费了700W字节也就是6.7M左右,如果更多的表这么做了,那么浪费的更多

  - 整型(N)表现形式:有时代码写法为int(10),表示数字宽度限制,要求如下:

  •       无论N等于多少,int永远占4个字节
  •       N表示的是显示宽度,不足则补0,超过长度则会无视长度直接显示整个数字

浮点型

数据类型字节数备注
float4单精度浮点型
double8双精度浮点型

注意:可以使用float(M,D)、double(M,D)格式限制宽度按(M)和精度(D),如float(3,2),不指定M、D的时,会按照实际的精度来处理

定点型decimal(size,d) ,作为字符串存储的 DOUBLE 类型,允许固定的小数点,由于float、double类型存在精度丢失问题,即**写入数据库的数据未必是插入数据库的数据**,而decimal无论写入数据中的数据是多少,都不会存在精度丢失问题,这就是要引入decimal类型的原因,decimal类型常见于银行系统、互联网金融系统等对小数点后的数字比较敏感的系统中,结论:float/double在db中存储的是近似值,而decimal则是以字符串形式进行保存。

mysql> create database  mydb1_test;mysql> use mydb1_test;
Database changedmysql> create table t1(float_num float(10,2) , double_num  double(20,2) , decimal_num decimal(20,2));
Query OK, 0 rows affected, 2 warnings (0.03 sec)mysql> insert into t1 value (1234567.66,1234567899000000.66,123456789000000.66);
Query OK, 1 row affected (0.00 sec)mysql> select * from  t1;
+------------+---------------------+--------------------+
| float_num  | double_num          | decimal_num        |
+------------+---------------------+--------------------+
| 1234567.62 | 1234567899000000.80 | 123456789000000.66 |
+------------+---------------------+--------------------+
# 注意:Query OK, 0 rows affected, 2 warnings (0.03 sec)含义如下:该信息是MySQL数据库执行SQL语句的结果。它表示SQL语句成功执行,但是没有影响到任何行,并且出现了两个警告。"Query OK" 表示查询操作成功。"0 rows affected" 表示SQL语句执行后,影响到数据库中的0行数据。"2 warnings" 表示在执行这个查询时,发出了两个警告。"(0.03 sec)" 表示查询执行的时间。
可以通过命令  show  warnings; 查看警告信息
  • 文本型

数据类型描述
char(size)保存固定长度的字符串(可包含字母、数字以及特殊字 符)。在括号中指定字符串的长度。最多 255 个字符。
varchar(size)保存可变长度的字符串(可包含字母、数字以及特殊字 符)。在括号中指定字符串的最大长度。最多 255 个字 符。 注释:如果值的长度大于 255,则被转换为 TEXT 类型。
tinytext存放最大长度为 255 个字符的字符串。
text存放最大长度为 65,535 个字符的字符串。
blob用于 BLOBs (Binary Large OBjects)。存放最多 65,535 字节的数据。
mediumtext存放最大长度为 16,777,215 个字符的字符串。
mediumelob用于 BLOBs (Binary Large OBjects)。存放最多 16,777,215 字节的数据。
longtext存放最大长度为 4,294,967,295 个字符的字符串。
longblob用于 BLOBs (Binary Large OBjects)。存放最多 4,294,967,295 字节的数据。
enum(x,y,z,etc.)允许输入可能值的列表。可以在 ENUM 列表中列出最大 65535 个值。如果列表中不存在插入的值,则插入空值。 注释:这些值是按照你输入的顺序存储的。 可以按照此格式输入可能的值: ENUM('X','Y','Z')
set与 enum 类似, SET 最多只能包含 64 个列表项,不过 SET 可存储一个以上的值。
  • 文本型
数据类型描述
char(size)保存固定长度的字符串(可包含字母、数字以及特殊字 符)。在括号中指定字符串的长度。最多 255 个字符。
varchar(size)保存可变长度的字符串(可包含字母、数字以及特殊字 符)。在括号中指定字符串的最大长度。最多 255 个字 符。 注释:如果值的长度大于 255,则被转换为 TEXT 类型。
tinytext存放最大长度为 255 个字符的字符串。
text存放最大长度为 65,535 个字符的字符串。
blob用于 BLOBs (Binary Large OBjects)。存放最多 65,535 字节的数据。
mediumtext存放最大长度为 16,777,215 个字符的字符串。
mediumelob用于 BLOBs (Binary Large OBjects)。存放最多 16,777,215 字节的数据。
longtext存放最大长度为 4,294,967,295 个字符的字符串。
longblob用于 BLOBs (Binary Large OBjects)。存放最多 4,294,967,295 字节的数据。
enum(x,y,z,etc.)允许输入可能值的列表。可以在 ENUM 列表中列出最大 65535 个值。如果列表中不存在插入的值,则插入空值。 注释:这些值是按照你输入的顺序存储的。 可以按照此格式输入可能的值: ENUM('X','Y','Z')
set与 enum 类似, SET 最多只能包含 64 个列表项,不过 SET 可存储一个以上的值。

注意:

- blob和text都是为了存储很大数据而设计的字符串数据类型,blob采用二进制形式存储无排序规则和字符集,text采用字符形式存储且有排序规则和字符集适用于存储如文章内容、评论等

- char是固定长度字符串,其长度范围为0~255且与编码方式无关,无论字符实际长度是多少,都会按照指定长度存储,不够的用空格补足,char类型数据时会将结尾的所有空格处理掉

mysql> create table t2(char_value char(5) , varchar_value varchar(5));
Query OK, 0 rows affected (0.01 sec)mysql> insert  into t2 value('a','a');
Query OK, 1 row affected (0.00 sec)mysql> insert  into t2 value('  a','  a');
Query OK, 1 row affected (0.01 sec)mysql> insert  into t2 value('a  ','a  ');
Query OK, 1 row affected (0.00 sec)mysql> insert  into t2 value('  a  ','  a  ');
Query OK, 1 row affected (0.00 sec)mysql> select  * from  t2;
+------------+---------------+
| char_value | varchar_value |
+------------+---------------+
| a          | a             |
|   a        |   a           |
| a          | a             |
|   a        |   a           |
+------------+---------------+
4 rows in set (0.00 sec)mysql> select length(char_value),length(varchar_value) from  t2;
+--------------------+-----------------------+
| length(char_value) | length(varchar_value) |
+--------------------+-----------------------+
|                  1 |                     1 |
|                  3 |                     3 |
|                  1 |                     3 |
|                  3 |                     5 |
+--------------------+-----------------------+
4 rows in set (0.00 sec)
  • date 类型

数据类型字节数格式备注
date3yyyy-MM-dd存储日期值
time3HH:mm:ss存储时分秒
year1yyyy存储年
datetime8yyyy-MM-dd HH:mm:ss存储日期+时间
timestamp4yyyy-MM-dd HH:mm:ss存储日期+时间,可作时间戳
mysql> create table t3( date_value date,time_value time,year_value year,datetime_value datetime,timestamp_value timestamp);
Query OK, 0 rows affected (0.02 sec)mysql> insert  into  t3  values(now(), now(), now(), now(), now());
Query OK, 1 row affected, 1 warning (0.01 sec)mysql> select * from t3;
  • 总结:常用数据类型:

5.2 创建表

  • 格式:
create  table  表名 (表选项)
  • 表定义选项格式为:
列名1  列类型1  约束, 列名2  列类型2  约束,……
  • 默认的情况是,表被创建到当前的数据库中。若表已存在、没有当前数据库或者数据库不存在,则会出现错误
  • 使用 crate table 创建表时,必须指定以下信息:
  • 要创建的表的名称不区分大小写,不能使用SQL语言中的关键字,如DROP、ALTER、INSERT等。

  • 必须指定数据表中每个列(字段)的名称和数据类型,如果创建多个列,要用逗号隔开

  • 示例1:创建数据库并新建表

数据表属于数据库,在创建数据表之前,应使用语句“use <数据库>”指定操作在哪个数据库中进行,如果没有选择数据库,就会抛出 No database selected 的错误

mysql> select  database();  # 查看当前数据库mysql> create database mydb2_stuinfo;  # 创建数据库
Query OK, 1 row affected (0.02 sec)mysql> use mydb2_stuinfo;  # 使用数据库
Database changedmysql> create table student1(id int, name varchar(30), sex char(2), age int unsigned, score float, addr varchar(50));
Query OK, 0 rows affected (0.02 sec)mysql> show tables;
+-------------------------+
| Tables_in_mydb2_stuinfo |
+-------------------------+
| student1                |
+-------------------------+

示例2:新建员工表

mysql> create database mydb3_employee;
Query OK, 1 row affected (0.01 sec)mysql>  use mydb3_employee;
Database changedmysql> create table tb1(id int(11), name varchar(25), salary float); 
Query OK, 0 rows affected, 1 warning (0.03 sec)mysql> show tables;
+--------------------------+
| Tables_in_mydb3_employee |
+--------------------------+
| tb1                      |
+--------------------------+
1 row in set (0.00 sec)

练习:

在mydb2_stuinfo库中新建班级表class1,字段如下:cla_num int(5) , cla_name varchar(10) , number int(4) , monitor varchar(20) ,creation_date date

mysql>  use  mydb2_stuinfo;mysql> create table class1(cla_num int(5), cla_name varchar(10), number int(4),monitor  varchar(20),creation_date  date);mysql> desc  class1;
+---------------+-------------+------+-----+---------+-------+
| Field         | Type        | Null | Key | Default | Extra |
+---------------+-------------+------+-----+---------+-------+
| cla_num       | int         | YES  |     | NULL    |       |
| cla_name      | varchar(10) | YES  |     | NULL    |       |
| number        | int         | YES  |     | NULL    |       |
| monitor       | varchar(20) | YES  |     | NULL    |       |
| creation_date | date        | YES  |     | NULL    |       |
+---------------+-------------+------+-----+---------+-------+
5 rows in set (0.00 sec)

5.3 查看表

show语句:显示当前数据库中已有的数据表

describe语句:查看数据表中各列的信息

  • 字段意义分析:

    • Field :字段名称

    • type:字段类型

    • null:是否允许为空

    • key:索引类型

    • default:默认值

    • extra:填充

  • 使用\G可以查看更全面的表定义信息

mysql> show  create  table  student1\G
*************************** 1. row ***************************Table: student1
Create Table: CREATE TABLE `student1` (`id` int DEFAULT NULL,`name` varchar(30) DEFAULT NULL,`sex` char(2) DEFAULT NULL,`age` int unsigned DEFAULT NULL,`score` float DEFAULT NULL,`addr` varchar(50) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

5.4 删除表

格式

drop table [if exists] 表名;
mysql> use mydb3_employee;
Database changedmysql> show columns from tb1;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| id     | int         | YES  |     | NULL    |       |
| name   | varchar(25) | YES  |     | NULL    |       |
| salary | float       | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)mysql> drop table tb1;
Query OK, 0 rows affected (0.01 sec)mysql> show  tables;
Empty set (0.00 sec)

注意:

  • 用户必须拥有执行 drop table 命令的权限,否则数据表不会被删除

  • 推荐使用if exists字句,即先判断是否存在,存在则删除,如:

mysql> drop table  if exists  tb1;
Query OK, 0 rows affected (0.01 sec)

5.5 修改表

# 法1:
alter  table  表名  rename  新表名;  # 法2:
rename  table  表名  to  新表名;
mysql> use mydb2_stuinfo;
Database changed
mysql> show tables;
+-------------------------+
| Tables_in_mydb2_stuinfo |
+-------------------------+
| class1                  |
| student1                |
+-------------------------+
1 row in set (0.00 sec)mysql> create table student2(id int(11), name varchar(30), salary float);
Query OK, 0 rows affected, 1 warning (0.05 sec)mysql> desc student2;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| id     | int         | YES  |     | NULL    |       |
| name   | varchar(30) | YES  |     | NULL    |       |
| salary | float       | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.01 sec)mysql> alter table student2 rename student3; # 修改
Query OK, 0 rows affected (0.01 sec)mysql> show tables;
+-------------------------+
| Tables_in_mydb2_stuinfo |
+-------------------------+
| class1                  |
| student1                |
| student3                |
+-------------------------+
2 rows in set (0.01 sec)mysql> rename table student3 to teacher1;  # 修改
Query OK, 0 rows affected (0.01 sec)mysql> show tables;
+-------------------------+
| Tables_in_mydb2_stuinfo |
+-------------------------+
| class1                  |
| student1                |
| teacher1                |
+-------------------------+
2 rows in set (0.00 sec)
  • 添加新列
alter table 表名 add  新列名 列类型  [after|first] 列名;# after:在指定列之后插入新列
# first:在第一列插入新列
# 注意:无before关键字

 

# 例:增加一列password	
mysql> alter table student1 add password char(8);
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0# 注意:数据库操作后得到的反馈,表明操作的结果。这个信息表示:Records: 2: 表示成功导入或处理的记录总数是2条。Duplicates: 0: 表示在操作过程中没有发现重复的记录。Warnings: 0: 表示在操作过程中没有产生任何警告。mysql> desc student1;
+----------+--------------+------+-----+---------+-------+
| Field    | Type         | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| id       | int          | YES  |     | NULL    |       |
| name     | varchar(30)  | YES  |     | NULL    |       |
| sex      | char(2)      | YES  |     | NULL    |       |
| age      | int unsigned | YES  |     | NULL    |       |
| score    | float        | YES  |     | NULL    |       |
| addr     | varchar(50)  | YES  |     | NULL    |       |
| password | char(8)      | YES  |     | NULL    |       |
+----------+--------------+------+-----+---------+-------+
7 rows in set (0.00 sec)# 例:再添加一个新列notes varchar(30),位置在score之前
mysql> alter table student1 add notes varchar(30)  after  age;
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0mysql> desc  student1;
+----------+--------------+------+-----+---------+-------+
| Field    | Type         | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| id       | int          | YES  |     | NULL    |       |
| name     | varchar(30)  | YES  |     | NULL    |       |
| sex      | char(2)      | YES  |     | NULL    |       |
| age      | int unsigned | YES  |     | NULL    |       |
| notes    | varchar(30)  | YES  |     | NULL    |       |
| score    | float        | YES  |     | NULL    |       |
| addr     | varchar(50)  | YES  |     | NULL    |       |
| password | char(8)      | YES  |     | NULL    |       |
+----------+--------------+------+-----+---------+-------+# 例:再第一列添加一个新列
mysql> alter table student1 add aa int  first;mysql> desc  student1;
+----------+--------------+------+-----+---------+-------+
| Field    | Type         | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| aa       | int          | YES  |     | NULL    |       |
| id       | int          | YES  |     | NULL    |       |
| name     | varchar(30)  | YES  |     | NULL    |       |
| sex      | char(2)      | YES  |     | NULL    |       |
| age      | int unsigned | YES  |     | NULL    |       |
| notes    | varchar(30)  | YES  |     | NULL    |       |
| score    | float        | YES  |     | NULL    |       |
| addr     | varchar(50)  | YES  |     | NULL    |       |
| password | char(8)      | YES  |     | NULL    |       |
+----------+--------------+------+-----+---------+-------+
9 rows in set (0.00 sec)
  • 删除列
alter table 表名 DROP 列名;

 

# 例:删除上例的notes、aa列
mysql> alter table student1  drop notes;
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0mysql> alter table student1  drop aa;
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0mysql> desc  student1;
+----------+--------------+------+-----+---------+-------+
| Field    | Type         | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| id       | int          | YES  |     | NULL    |       |
| name     | varchar(30)  | YES  |     | NULL    |       |
| sex      | char(2)      | YES  |     | NULL    |       |
| age      | int unsigned | YES  |     | NULL    |       |
| score    | float        | YES  |     | NULL    |       |
| addr     | varchar(50)  | YES  |     | NULL    |       |
| password | char(8)      | YES  |     | NULL    |       |
+----------+--------------+------+-----+---------+-------+
  • 修改列名
alter  table  表名 change  旧列名  新列名 列类型;

 

mysql> alter table student1 change password passwd char(8);  # 改名
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0mysql> desc student1;
+--------+--------------+------+-----+---------+-------+
| Field  | Type         | Null | Key | Default | Extra |
+--------+--------------+------+-----+---------+-------+
| id     | int          | YES  |     | NULL    |       |
| name   | varchar(30)  | YES  |     | NULL    |       |
| sex    | char(2)      | YES  |     | NULL    |       |
| age    | int unsigned | YES  |     | NULL    |       |
| score  | float        | YES  |     | NULL    |       |
| addr   | varchar(50)  | YES  |     | NULL    |       |
| passwd | char(8)      | YES  |     | NULL    |       |
+--------+--------------+------+-----+---------+-------+
7 rows in set (0.01 sec)
  • 修改列类型
alter  table  表名  modify  列名  列类型;
# 插入新列,修改类型
mysql> alter table student1 add birthday char(10); # 增加
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0mysql> desc student1;
+----------+--------------+------+-----+---------+-------+
| Field    | Type         | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| id       | int          | YES  |     | NULL    |       |
| name     | varchar(30)  | YES  |     | NULL    |       |
| sex      | char(2)      | YES  |     | NULL    |       |
| age      | int unsigned | YES  |     | NULL    |       |
| score    | float        | YES  |     | NULL    |       |
| addr     | varchar(50)  | YES  |     | NULL    |       |
| passwd   | char(8)      | YES  |     | NULL    |       |
| birthday | char(10)     | YES  |     | NULL    |       |
+----------+--------------+------+-----+---------+-------+
8 rows in set (0.00 sec)mysql> alter table student1 modify birthday date; # 修改
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0mysql> desc student1;
+----------+--------------+------+-----+---------+-------+
| Field    | Type         | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| id       | int          | YES  |     | NULL    |       |
| name     | varchar(30)  | YES  |     | NULL    |       |
| sex      | char(2)      | YES  |     | NULL    |       |
| age      | int unsigned | YES  |     | NULL    |       |
| score    | float        | YES  |     | NULL    |       |
| addr     | varchar(50)  | YES  |     | NULL    |       |
| passwd   | char(8)      | YES  |     | NULL    |       |
| birthday | date         | YES  |     | NULL    |       |
+----------+--------------+------+-----+---------+-------+
8 rows in set (0.00 sec)

5.6 修改列位置

alter table 表名 modify  列名  列类型 after 某列;

 

# 例:添加新列
mysql> alter table student1 add notes varchar(30) after name;
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0# 将notes移动到最后
mysql> alter table student1 modify  notes varchar(30) after birthday;
Query OK, 0 rows affected (0.04 sec)
Records: 0  Duplicates: 0  Warnings: 0# 删除该列
mysql> alter table  student1 drop notes;

5.7 练习

  1. 新建商品数据库mydb4_product,

  2. 使用该数据库

  3. 创建商品表pro_tb1,字段包含编号 num int(4),商品名trade_name varchar(30),数量number int(4) ,单价price float(5,2)

  4. 显示创建表的字段内容

  5. 新增一列备注notes varchar(30)

  6. 将编号num字段类型修改为char(4)

  7. 删除该表(先判断)

mysql> create  database  mydb4_product;
Query OK, 1 row affected (0.00 sec)mysql> use  mydb4_product;
Database changedmysql> create table  pro_tb1(num  int(4), trade_name  varchar(30), number int(4), price float(5,2));
Query OK, 0 rows affected, 3 warnings (0.03 sec)mysql> desc  pro_tb1;mysql> alter table  pro_tb1 add notes varchar(30);
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0mysql> desc  pro_tb1;mysql> alter table pro_tb1 modify num char(4);
Query OK, 0 rows affected (0.05 sec)
Records: 0  Duplicates: 0  Warnings: 0mysql> desc  pro_tb1;mysql> drop table if exists  pro_tb1;
Query OK, 0 rows affected (0.01 sec)mysql> show tables;
Empty set (0.00 sec)

5.8 复制表的结构

  • 方法一:在create table语句的末尾添加like子句,可以将源表的表结构复制到新表中,语法格式如下:

create table 新表名 like 源表
mysql> use  mydb2_stuinfo;mysql> insert into student1 value(1000,"zhangsan","M",18,98.5,"xi'an","12345678","2005-10-01");
Query OK, 1 row affected (0.00 sec)mysql> insert into student1 value(1001, "lisi", "W", 20,66.79, "baoji","87654321","2003-5-01");mysql> select * from  student1;mysql> create table student2 like student1;
Query OK, 0 rows affected (0.01 sec)mysql> show tables;
+-------------------------+
| Tables_in_mydb2_stuinfo |
+-------------------------+
| class1                  |
| student1                |
| teacher1                |
+-------------------------+
3 rows in set (0.00 sec)mysql> select * from  student2;   # 注意:只是复制结构框架
Empty set (0.00 sec)
  • 方法二:在create table语句的末尾添加一个select语句,可以实现表结构的复制,甚至可以将源表的表记录拷贝到新表中,下面的语法格式将源表的结构和记录都拷贝到新表中。

 

create table 新表名 select * from 源表
mysql> create table student3 select * from student1;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0mysql> show tables;
+-------------------------+
| Tables_in_mydb2_stuinfo |
+-------------------------+
| class1                  |
| student1                |
| student2                |
| student3                |
| teacher1                |
+-------------------------+
4 rows in set (0.00 sec)mysql> select * from  student3;
  • 方法三:如果已经存在一张结构一致的表,复制数据:

mysql> select * from student2;
Empty set (0.00 sec)mysql> insert into student2 select * from student1;
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0mysql> select * from student2;mysql> drop table if exists student2;
mysql> drop table if exists student3;
mysql> drop table if exists teacher1;

5.9 数据库字典

  • 数据字典:类似于系统编目或花名册,它保存数据库服务器上的元数据信息(数据库的整体属性信息)

  • 元数据(meta data):即“data about data” 关于数据的数据,理解为描述数据的数据,内容包括:数据库的属性信息、数据表的属性信息、字段的属性信息、视图的属性信息、用户信息、统计类信息等。

  • information_schema数据库是MySQL系统自带的数据库,它提供了数据库元数据的访问方式

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mydb1_test         |
| mydb2_stuinfo      |
| mydb3_employee     |
| mydb4_product      |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
8 rows in set (0.00 sec)
  • information_schema就像是MySQL实例的一个百科全书,记录了数据库当中大部分我们需要了结的信息,比如字符集,权限相关,数据库实体对象信息,外检约束,分区,压缩表,表信息,索引信息,参数,优化,锁和事物等等。

  • 通过information_schema我们可以窥透整个MySQL实例的运行情况,可以了结MySQL实例的基本信息,甚至优化调优,维护数据库等,可以说是真正的一部百科全书。

mysql> use information_schema ;mysql> show tables;# 常用表解释
tables-存放数据库里所有的数据表、以及每个表所在数据库。
schemata-存放数据库里所有的数据库信息
views-存放数据库里所有的视图信息。
columns-存放数据库里所有的列信息。
triggers-存放数据库里所有的触发器。
routines-存放数据库里所有存储过程和函数。
key_column_usage-存放数据库所有的主外键
table_constraints-存放数据库全部约束。
statistics-存放了数据表的索引。
……

5.10 小结

# 新建表
create tables  表名(列名1 类型  , 列名2  类型 ……);# 查看表结构
desc  表名;# 修改表名
alter  table  旧表名  rename  新表名;# 表中添加新列
alter table 表名 add  新列名 列类型  [after|first] 列名;   (after为之后)# 删除列
alter table 表名 DROP 列名;# 修改列名
alter  table  表名 change  旧列名  新列名 列类型;# 修改列类型
alter  table  表名  modify  列名  列类型;# 移动列
alter table 表名 modify  列名  列类型 after 某列;# 删除表
drop table  if  exists  表名;  

5.11 删除的注意事项

1.删除数据库表之前,一定要备份数据,以免数据丢失。

2.在删除数据库表之前,要确保该表没有被其他的表所引用,否则可能会破坏外键约束。

3.在删除数据库表之前,要确保该表的数据已经备份,并且不再需要使用。

4.在删除数据库表之前,要确保该表的数据已经被清空,否则会破坏外键约束。

5.在删除数据库表之前,要确保该表的所有索引都已经被删除。如果还存在索引,可能会导致删除失败。
6.在删除数据库表之前,要确保该表的所有相关程序已经停止运行,以免影响其他程序的正常运行。

6. 表的约束

6.1 概念

  • 为什么需要约束

    • 真正约束字段的是数据类型,但是数据类型约束很单一,需要有一些额外的约束,更好的保证数据的合法性,从业务逻辑角度保证数据的正确性,如:有一个字段是身份证,要求是唯一的

    • 定义字段的类型无法满足对表的约束:

      • 表字段是否可以为NULL,有没有默认值,表字段的解释能不能加上

      • 对于数字类型的字段可不可以指定默认表示的位数,可不可以将这个字段设置称为唯一标识该行的数据

    • 本质上Mysql是一套数据存储解决方案,除了解决基本的数据存储功能之外,还要保证数据尽可能的安全,减少用户的误操作可能性, 约束的体现,不仅仅可以体现在数据库层面,在我们进行用户业务逻辑编码的时候,我们其实也可以做判断(约束),约束其实不仅仅只能出现在数据库层而上,编码层面也是可以体现

  • 约束是什么:约束是在==表上强制执行的数据校验规则==,本质上是Mysql通过限制用户操作的方式,来达到维护数据本身安全及数据完整性的一套方案

  • 数据的完整性要从以下四个方面考虑:

    • 实体完整性(Entity Integrity):例如,同一个表中,不能存在两条完全相同无法区分的记录

    • 域完整性(Domain Integrity):例如:年龄范围0-120,性别范围“男/女”

    • 引用完整性(Referential Integrity):例如:员工所在部门,在部门表中要能找到这个部门

    • 用户自定义完整性(User-defined Integrity):例如:用户名唯一、密码不能为空等,本部门经理的工资不得高于本部门职工的平均工资的5倍。

  • 约束作为数据库对象,存放在系统表中,也有自己的名字

  • 常见约束:

    • 非空约束

    • 默认值约束

    • 主键约束

    • 外键约束

    • 唯一约束

    • 检查约束

  • 创建约束的时机:

    • 在建表的同时创建

    • 建表后创建(修改表)

  • 约束可定义列级或表级约束

6.2 语法

  • 列级约束:在定义列的同时定义约束

create  table  表名 (列名  类型 约束 )
  • 表级约束:在定义了所有列之后定义的约束

create  table  表名 constraint 约束名 约束类型  (列信息)

  • 创建表之后添加约束:

alter table 表名 add constraint 约束名 约束类型(要约束的列名)

6.3 非空约束

  • 作用:限定某个字段/某列的值不允许为空

  • 两个值:null(默认的)和not null(不为空)

  • 列字段默认一般都是空,但是实际开发时,尽可能保证字段不为空,因为数据为空没办法参与运算

  • 所有数据类型的值都可以是NULL,空字符串不等于NULL,0也不等于NULL示例:

mysql> use mydb2_stuinfo;
Database changedmysql> desc student1;
+----------+--------------+------+-----+---------+-------+
| Field    | Type         | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| id       | int          | YES  |     | NULL    |       |
| name     | varchar(30)  | YES  |     | NULL    |       |
| sex      | char(2)      | YES  |     | NULL    |       |
| age      | int unsigned | YES  |     | NULL    |       |
| score    | float        | YES  |     | NULL    |       |
| addr     | varchar(50)  | YES  |     | NULL    |       |
| passwd   | char(8)      | YES  |     | NULL    |       |
| birthday | date         | YES  |     | NULL    |       |
+----------+--------------+------+-----+---------+-------+
8 rows in set (0.00 sec)# 插入数据
mysql> insert into student1(id,name) values('1002','张三'); 
Query OK, 1 row affected (0.00 sec)mysql> insert into student1(id,name) values('1003','李四'); 
Query OK, 1 row affected (0.00 sec)mysql> select * from  student1;
+------+----------+------+------+-------+-------+----------+------------+
| id   | name     | sex  | age  | score | addr  | password | birthday   |
+------+----------+------+------+-------+-------+----------+------------+
| 1000 | zhangsan | M    |   18 | 98.50 | xi'an | 12345678 | 2005-10-01 |
| 1001 | lisi     | w    |   20 | 66.79 | baoji | 87654321 | 2003-05-01 |
| 1002 | 张三      | NULL | NULL |  NULL | NULL  | NULL     | NULL       |
| 1003 | 李四      | NULL | NULL |  NULL | NULL  | NULL     | NULL       |
+------+----------+------+------+-------+-------+----------+------------+
4 rows in set (0.00 sec)# 显示sex之后的列都为NULL,表示内容没有填
  • 若需要某些字段必须写入,应该怎么处理,如:创建一个班级表,包含班级名和班级所在的教室,站在正常的业务逻辑中:如果班级没有名字,你不知道你在哪个班级,如果教室名字可以为空,就不知道在哪上课,所以我们在设计数据库表的时候,一定要在表中进行限制,满足上面条件的数据就不能插入到表中,这就是“约束”

mysql> create table myclass1(class_name varchar(20) not null, class_room varchar(20) not null, class_id int);   # 无约束
Query OK, 0 rows affected (0.02 sec)mysql> desc myclass1;
+------------+-------------+------+-----+---------+-------+
| Field      | Type        | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| class_name | varchar(20) | NO   |     | NULL    |       |
| class_room | varchar(20) | NO   |     | NULL    |       |
| class_id   | int         | YES  |     | NULL    |       |
+------------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)# 插入数据时:
mysql> insert into myclass1 (class_room) values('计科1');
ERROR 1364 (HY000): Field 'class_name' doesn't have a default value  # 失败,因为name有约束不能为空mysql> insert into myclass1 (class_name,class_room) values('A104','计科1');     # 同时插入成功
Query OK, 1 row affected (0.00 sec)mysql> select * from myclass1;
+------------+------------+----------+
| class_name | class_room | class_id |
+------------+------------+----------+
| A104       | 计科1      |     NULL |
+------------+------------+----------+
1 row in set (0.00 sec)
# id字段无约束,可以为空
  • 以上为创建表时的设置,也可以创建之后修改:
# 语法:
alter table <数据表名> change column <字段名>      <字段名> <数据类型> not null;
mysql> alter table student1 change column id id int not null;
# 也可以通过modify修改
mysql> alter table student1 modify name varchar(30) not null;# modify字句中省略not null 相当于设置为可以为空
mysql> desc  student1;
+----------+--------------+------+-----+---------+-------+
| Field    | Type         | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| id       | int          | NO   |     | NULL    |       |
| name     | varchar(30)  | NO   |     | NULL    |       |
| sex      | char(2)      | YES  |     | NULL    |       |
| age      | int unsigned | YES  |     | NULL    |       |
| score    | float        | YES  |     | NULL    |       |
| addr     | varchar(50)  | YES  |     | NULL    |       |
| passwd   | char(8)      | YES  |     | NULL    |       |
| birthday | date         | YES  |     | NULL    |       |
+----------+--------------+------+-----+---------+-------+
8 rows in set (0.00 sec)
  • 删除 not null

mysql> alter table student1 modify id int null;
Query OK, 0 rows affected (0.04 sec)
Records: 0  Duplicates: 0  Warnings: 0
# 或者
mysql> alter table student1 modify name varchar(30);mysql> desc student1;
+----------+--------------+------+-----+---------+-------+
| Field    | Type         | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| id       | int          | YES  |     | NULL    |       |
| name     | varchar(30)  | YES  |     | NULL    |       |
| sex      | char(2)      | YES  |     | NULL    |       |
| age      | int unsigned | YES  |     | NULL    |       |
| score    | float        | YES  |     | NULL    |       |
| addr     | varchar(50)  | YES  |     | NULL    |       |
| passwd   | char(8)      | YES  |     | NULL    |       |
| birthday | date         | YES  |     | NULL    |       |
+----------+--------------+------+-----+---------+-------+
8 rows in set (0.00 sec)

6.4 默认值约束

  • 作用:给某个字段/某列指定默认值,一旦设置默认值,在插入数据时,如果此字段没有显式赋值,则赋值为默认值。

mysql> create table teacher1(id int not null, name varchar(30) not null, sex char(2) default '女');
Query OK, 0 rows affected (0.03 sec)mysql> desc teacher1;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int         | NO   |     | NULL    |       |
| name  | varchar(30) | NO   |     | NULL    |       |
| sex   | char(2)     | YES  |     | 女      |       |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.01 sec)mysql> insert into teacher1(id,name) values(1001,'林雪');
Query OK, 1 row affected (0.00 sec)mysql> select * from teacher1;
+------+--------+------+
| id   | name   | sex  |
+------+--------+------+
| 1001 | 林雪   | 女   |
+------+--------+------+
1 row in set (0.00 sec)mysql> insert into teacher1(id,name,sex) values(1002,'石磊','男');                # 也可以全字段插入
Query OK, 1 row affected (0.01 sec)mysql> select * from teacher1;
+------+--------+------+
| id   | name   | sex  |
+------+--------+------+
| 1001 | 林雪   | 女   |
| 1002 | 石磊   | 男   |
+------+--------+------+
2 rows in set (0.00 sec)
# 创建表之后增加默认值:
mysql> alter table student1 modify sex char(2) default '女';
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0mysql> desc student1;
+----------+--------------+------+-----+---------+-------+
| Field    | Type         | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| id       | int          | YES  |     | NULL    |       |
| name     | varchar(30)  | YES  |     | NULL    |       |
| sex      | char(2)      | YES  |     | 女      |       |
| age      | int unsigned | YES  |     | NULL    |       |
| score    | float        | YES  |     | NULL    |       |
| addr     | varchar(50)  | YES  |     | NULL    |       |
| passwd   | char(8)      | YES  |     | NULL    |       |
| birthday | date         | YES  |     | NULL    |       |
+----------+--------------+------+-----+---------+-------+
8 rows in set (0.00 sec)mysql> insert into student1 (id,name) values(1004,'王五');
Query OK, 1 row affected (0.01 sec)mysql> select * from student1;
  • 默认值的生效:数据在插入的时候不给该字段赋值,就使用默认值

  • 注意:若某字段都设置了not null和default约束,则按照不插入时会选择默认值,插入时选择插入值,所以此时not null毫无意义

mysql> alter table teacher1 add age int not null default 18;
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0mysql> desc teacher1;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int         | NO   |     | NULL    |       |
| name  | varchar(30) | NO   |     | NULL    |       |
| sex   | char(2)     | YES  |     | 女      |       |
| age   | int         | NO   |     | 18      |       |
+-------+-------------+------+-----+---------+-------+
4 rows in set (0.01 sec)# not null和defalut一般不需要同时出现,因为default本身有默认值,不会为空

6.5 列描述--comment

    列描述没有实际含义,专门用来描述字段,会根据表创建语句保存,供操作者来查看该列的含义,相当于C/C++的注释

mysql> create table myclass2( class_name varchar(20) not null comment '教室',class_room  varchar(20)  default  '计科2');
Query OK, 0 rows affected (0.02 sec)mysql> desc myclass2;
+------------+-------------+------+-----+---------+-------+
| Field      | Type        | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| class_name | varchar(20) | NO   |     | NULL    |       |
| class_room | varchar(20) | YES  |     | 计科2   |       |
+------------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)mysql> show create table myclass2\G
*************************** 1. row ***************************Table: myclass2
Create Table: CREATE TABLE `myclass2` (`class_name` varchar(20) NOT NULL COMMENT '教室',`class_room` varchar(20) DEFAULT '计科2' COMMENT '班级'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

6.6 主键约束

  • 作用:数据库存储数据不是唯一的目的,还要考虑到提取数据,一般要求数据库表中的记录要有一个特定的唯一标识,来表示唯一性,这个唯一的特定标识就是主键,类似于序号学号这样的唯一标识,可以根据主键来唯一地筛选出一条记录

  • 主键:primary key,用来唯一的约束该字段里面的数据

  • 特点:

    • 主键字段不能为空,不能重复

    • 一张表中最多只能有一个主键

    • 主键所在的列通常是整数类型

    • 主键约束是最频繁的约束

  • 注意:当创建主键约束时,系统默认会在所在的列或列组合上建立对应的主键索引(能够根据主键查询 的,就根据主键查询,效率更高)。如果删除主键约束了,主键约束对应的索引就自动删除了,需要注意的一点是,不要修改主键字段的值。因为主键是数据记录的唯一标识,如果修改了主键的 值,就有可能会破坏数据的完整性。

  • 示例: 创建时增加主键

mysql> create table t1 ( id int unsigned primary key comment '学号不能为空', name varchar(20) not null ,sex char(2) default '男');
Query OK, 0 rows affected (0.02 sec)mysql> desc t1;
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id    | int unsigned | NO   | PRI | NULL    |       |
| name  | varchar(20)  | NO   |     | NULL    |       |
| sex   | char(2)      | YES  |     | 男      |       |
+-------+--------------+------+-----+---------+-------+
3 rows in set (0.01 sec)mysql> insert into t1 values(1,'孙文','女');
Query OK, 1 row affected (0.00 sec)mysql> select * from t1;
+----+--------+------+
| id | name   | sex  |
+----+--------+------+
|  1 | 孙文   | 女   |
+----+--------+------+
1 row in set (0.00 sec)mysql> insert into t1(id,name) values(2,'李文华');
Query OK, 1 row affected (0.00 sec)mysql> select * from t1;
+----+-----------+------+
| id | name      | sex  |
+----+-----------+------+
|  1 | 孙文      | 女   |
|  2 | 李文华    | 男   |
+----+-----------+------+
2 rows in set (0.00 sec)mysql> insert into t1(id,name) values(1,'黎明'); 
ERROR 1062 (23000): Duplicate entry '1' for key 't1.PRIMARY'# 再次插入出错,因为需要保持唯一性

示例:修改表,追加主键

mysql> alter table teacher1 add primary key(id);
Query OK, 0 rows affected (0.07 sec)
Records: 0  Duplicates: 0  Warnings: 0mysql> desc teacher1;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int         | NO   | PRI | NULL    |       |
| name  | varchar(30) | NO   |     | NULL    |       |
| sex   | char(2)     | YES  |     | 女      |       |
| age   | int         | NO   |     | 18      |       |
+-------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
  • 注意:如果该字段内有重复值,则不能以该字段新增为主键,必须先把重复的数据去掉然后才能添加该列为主键

  • 删除主键

alter table 表名 drop primary key;
mysql> alter table teacher1  drop primary key;
Query OK, 2 rows affected (0.04 sec)
Records: 2  Duplicates: 0  Warnings: 0mysql> desc teacher1;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int         | NO   |     | NULL    |       |
| name  | varchar(30) | NO   |     | NULL    |       |
| sex   | char(2)     | YES  |     | 女      |       |
| age   | int         | NO   |     | 18      |       |
+-------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
  • 复合主键:在创建表的时候,在所有字段之后,使用primary key(主键字段列表)来创建主键,如果有多个字段作为主键,可以使用复合主键,这些字段合在一起是一个主键,也就是让多个字段联合在一起作为唯一标识,单个字段主键重复是没有问题的,只要不是成为复合主键的字段一起冲突就行

mysql> create table t2 (id int, hostname varchar(10), ip varchar(20), port int unsigned, primary key (ip,port));
Query OK, 0 rows affected (0.02 sec)mysql> desc t2;
+----------+--------------+------+-----+---------+-------+
| Field    | Type         | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| id       | int          | YES  |     | NULL    |       |
| hostname | varchar(10)  | YES  |     | NULL    |       |
| ip       | varchar(20)  | NO   | PRI | NULL    |       |
| port     | int unsigned | NO   | PRI | NULL    |       |
+----------+--------------+------+-----+---------+-------+
4 rows in set (0.00 sec)mysql> insert into t2 values(1,'node1','192,168,48,2',120);
Query OK, 1 row affected (0.00 sec)mysql> select * from t2;
+------+----------+--------------+------+
| id   | hostname | ip           | port |
+------+----------+--------------+------+
|    1 | node1    | 192,168,48,2 |  120 |
+------+----------+--------------+------+
1 row in set (0.00 sec)mysql> insert into t2 values(2,'node2','192,168,48,3',120);
Query OK, 1 row affected (0.00 sec)  # 可以单个记录重复mysql> insert into  t2  values(3,'node2','192,168,48,2',120);
ERROR 1062 (23000): Duplicate entry '192,168,48,2-120' for key 't2.PRIMARY'  # 复合主键一起冲突,报错

6.7 主键自增长

  • 作用:给主键添加自增长的数值

  • auto_increment:当对应的字段,不给值,会自动的被系统触发,系统会从当前字段中已经有的最大值+1操作,得到一个新的不同的值。通常和主键搭配使用,作为逻辑主键

  • 注意:

    • 自增长字段必须是==整数==,自增长字段可以不设置初始值,默认从1开始递增.

    • 被自增长的字段必须作为主键或者其他具有唯一性的键使用,(必须保证这一列字段具有唯一性的字段)

    • 自增长字段也可以插入数据,只要不与已有数据重复即可,之后新增数据会从最大值开始递增.

    • 任何一个字段要做自增长,前提是本身是一个索引(key一栏有值).

    • 一张表当中最多只能有一个自增长的列

    • 约束的字段必须具备 NOT NULL 属性

  • 示例:

# 先增加主键
mysql> use mydb2_stuinfo;
Database changedmysql> alter table student1 modify id int primary key;
Query OK, 0 rows affected (0.06 sec)
Records: 0  Duplicates: 0  Warnings: 0# 设置自增长
mysql> alter table student1 modify id int auto_increment;
Query OK, 3 rows affected (0.05 sec)
Records: 3  Duplicates: 0  Warnings: 0# 查看
mysql> desc student1;
+----------+--------------+------+-----+---------+----------------+
| Field    | Type         | Null | Key | Default | Extra          |
+----------+--------------+------+-----+---------+----------------+
| id       | int          | NO   | PRI | NULL    | auto_increment |
| name     | varchar(30)  | YES  |     | NULL    |                |
| sex      | char(2)      | YES  |     | 女      |                |
| age      | int unsigned | YES  |     | NULL    |                |
| score    | float        | YES  |     | NULL    |                |
| addr     | varchar(50)  | YES  |     | NULL    |                |
| passwd   | char(8)      | YES  |     | NULL    |                |
| birthday | date         | YES  |     | NULL    |                |
+----------+--------------+------+-----+---------+----------------+
8 rows in set (0.00 sec)mysql> insert into student1(name) values('关六');
Query OK, 1 row affected (0.00 sec)mysql> select * from student1;# 发现自动增长
  • 指定自增长的起始值:如果第一条记录设置了该字段的初始值,那么新增加的记录就从这个初始值开始自增。例如,如果表中插入的第一条记录的 id 值设置为 5,那么再插入记录时,id 值就会从 5 开始往上增加
# 指定自增长的起始值为100
mysql> create table t3 ( id int primary key auto_increment, systemname varchar(10) not null )auto_increment=100;
Query OK, 0 rows affected (0.02 sec)# 插入一条记录
mysql> insert into t3(systemname) values('Linux');
Query OK, 1 row affected (0.00 sec)# 插入一条记录
mysql> insert into t3(systemname) values('windows');
Query OK, 1 row affected (0.00 sec)mysql> select * from t3;
+-----+------------+
| id  | systemname |
+-----+------------+
| 100 | Linux      |
| 101 | windows    |
+-----+------------+
2 rows in set (0.01 sec)

6.8 唯一性约束

  • 产生原因:一张表中有往往有很多字段需要唯一性,数据不能重复,但是一张表中只能有一个主键,唯一键就可以解决表中有多个字段需要唯一性约束的问题

  • 作用:限制某个字段/某列的值不能重复

  • 唯一键主键的关系:

    • 主键更多的是标识唯一性

    • 唯一键更多的是保证在业务上,不要和别的信息出现重复

    • 主键只能有一个,唯一键能设置多个

    • 主键和唯一键不是对立关系而是补充关系,目的是让数据库创建出一个表具有非常强的约束,彻底杜绝用户的误插入,在一张表当中,可以有一个主键,也可以同时具有唯一键, 它们不是用来对比的,只是负责数据在不同层面的唯一性,既要保证选择成为主键的属性字段不能重复不能为空,同时也要保证本身具有唯一性的列的字段不能出现冲突

    • 主键用来查找,唯一键用来保证数据的完整性

    • 如:学生信息中有身份证号和学号两个字段,可以把身份证号设置成为主键,而所有学生的学号也不能重复,此时就可以把学号设置成唯一键

  • 示例:创建表时实现

mysql> create table t4( id int primary key, name varchar(20) unique comment '名子不能重名,可以为空' );
Query OK, 0 rows affected (0.02 sec)mysql> desc t4;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int         | NO   | PRI | NULL    |       |
| name  | varchar(20) | YES  | UNI | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)# 插入数据
mysql> insert into t4  values(1,'刘文');
Query OK, 1 row affected (0.00 sec)# 唯一键数据重复,插入失败
mysql> insert into t4  values(1,'刘文');
ERROR 1062 (23000): Duplicate entry '1' for key 't4.PRIMARY'
mysql> insert into t4  values(2,'张磊');
Query OK, 1 row affected (0.00 sec)mysql> select * from t4;
+----+--------+
| id | name   |
+----+--------+
|  1 | 刘文   |
|  2 | 张磊   |
+----+--------+
2 rows in set (0.00 sec)
  • 唯一键冲突,自增涨字段值不连续
# 设置id列为自增长
mysql> alter table t4 modify id int auto_increment;
Query OK, 3 rows affected (0.03 sec)
Records: 3  Duplicates: 0  Warnings: 0# 插入一条记录
mysql> insert into t4(name)  values('张磊磊');ysql> select * from t4;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | 刘文      |
|  2 | 张磊      |
|  3 | 张磊磊    |
+----+-----------+
3 rows in set (0.00 sec)# 插入一条相同姓名记录
mysql> insert into t4(name)  values('张磊磊');
ERROR 1062 (23000): Duplicate entry '张磊磊' for key 't4.name'# 在插入一条记录,由于上述唯一键冲突,自增长会出现不连续
mysql> insert into t4(name)  values('钱明');
Query OK, 1 row affected (0.00 sec)mysql> select * from t4;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | 刘文      |
|  2 | 张磊      |
|  3 | 张磊磊    |
|  5 | 钱明      |
+----+-----------+
4 rows in set (0.00 sec)

6.9 外键约束

  • 作用:限定某个表的某个字段的==引用完整性==

  • 概念

    • 主表(父表):被引用的表、被参考的表

    • 从表(子表):引用别人的表,参考别人的表

    • 外键:从表中的某个字段引用自主表的某个字段或多个字段

    • 引用键:主表被引用的字段

  • 外键约束主要定义在从表上,主表则必须是有主键约束或唯一键约束.当定义外键后,要求外键列数据必须在主表的主键列存在或为null.

  • 格式:

foreign key (从表的字段名称) references 主表名字(主表的字段名称)  # 建立外键关联
  • 示例:

  • 学生表通过class_id和班级表产生关联,在语义上,class_id称为外键,此时的这个学生表就相当于从表,班级表相当于是主表, 比如我们新增一个class_id为30的学生,但是班级表中得先有id为30的班级,才能在学生表中添加, 要删除班级表中id为20的班级,首先必须保证学生表中没有对应班级为class_id =20的学生.,当然我们也可以新增一个class_id为NULL的学生,表示该学生还没有分配班级, 外键可以为空!

  • 注意:

    • 主表必须已经存在于数据库中,或者是当前正在创建的表。如果是后一种情况,则主表与从表是同一个表,这样的表称为自参照表,这种结构称为自参照完整性。

    • 必须为主表定义主键。

    • 主键不能包含空值,但允许在外键中出现空值。也就是说,只要外键的每个非空值出现在指定的主键中,这个外键的内容就是正确的。

    • 在主表的表名后面指定列名或列名的组合。这个列或列的组合必须是主表的主键或候选键。

    • 外键中列的数目必须和主表的主键中列的数目相同。

    • 外键中列的数据类型必须和主表主键中对应列的数据类型相同。

  • 定义从表的时候,设置外键其实就是设置了一个关系,在从表当中插入数据的时候,会对插入数据进行校验,校验插入的数据是否存在于主表字段当中,外键就是增加了表和表之间的约束关系.

  • 示例:

# 定义主表
mysql> create table myclass3(id int primary key, name varchar(20) not null comment '班级名');
Query OK, 0 rows affected (0.02 sec)mysql> desc myclass3;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int         | NO   | PRI | NULL    |       |
| name  | varchar(20) | NO   |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
# 定义从表:
mysql> create table  myclass3_stu( id int primary key, name varchar(30) not null comment '学生名', class_id int, foreign key (class_id) references myclass3(id) );
Query OK, 0 rows affected (0.02 sec)mysql> desc myclass3_stu;
+----------+-------------+------+-----+---------+-------+
| Field    | Type        | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| id       | int         | NO   | PRI | NULL    |       |
| name     | varchar(30) | NO   |     | NULL    |       |
| class_id | int         | YES  | MUL | NULL    |       |
+----------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
# 主表中插入数据
mysql> insert into myclass3 values(10,'C++'),(20,'Java');
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0mysql> select * from myclass3;
+----+------+
| id | name |
+----+------+
| 10 | C++  |
| 20 | Java |
+----+------+
2 rows in set (0.00 sec)
# 从表中正常插入数据:
mysql> insert into myclass3_stu values(1,'Li',10),(2,'Sun',20);
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0mysql> select * from myclass3_stu;
+----+------+----------+
| id | name | class_id |
+----+------+----------+
|  1 | Li   |       10 |
|  2 | Sun  |       20 |
+----+------+----------+
2 rows in set (0.00 sec)
# 从表中插入没有班级的记录,受外键控制,报错
mysql> insert into myclass3_stu values(3,'wang',30);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`stu_info`.`myclass3_stu`, CONSTRAINT `myclass3_stu_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `myclass3` (`id`))
# 从表中,收到外键控制,可以使用null替代,表示没有分配班级
mysql> insert into myclass3_stu values(3,'wang',null);
Query OK, 1 row affected (0.00 sec)mysql> select * from myclass3_stu;
+----+------+----------+
| id | name | class_id |
+----+------+----------+
|  1 | Li   |       10 |
|  2 | Sun  |       20 |
|  3 | wang |     NULL |
+----+------+----------+
3 rows in set (0.00 sec)

6.10 检查约束

  • 作用:检查约束(check)是用来检查数据表中字段值有效性的一种手段,一般用于设置值的范围

  • 注意

    • 设置检查约束时要根据实际情况进行设置,这样能够减少无效数据的输入

    • 在默认值和非空约束可看作是特殊的检查约束

    • 注意检查约束在8.0.16之前,MySQL默认但不会强制的遵循check约束(写不报错,但是不生效,需要通触发器完成),之后就开始正式支持这个约束了

  • 示例1:创建表时设置检查约束

mysql> create table t5(id int primary key, name varchar(20), salary float, check(salary>0 and salary<10000) );
Query OK, 0 rows affected (0.02 sec)mysql> desc t5;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| id     | int         | NO   | PRI | NULL    |       |
| name   | varchar(20) | YES  |     | NULL    |       |
| salary | float       | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)mysql> insert into t5 values(1,'Li',5984);
Query OK, 1 row affected (0.00 sec)mysql> insert into t5 values(2,'wang',12000);
ERROR 3819 (HY000): Check constraint 't5_chk_1' is violated.
  • 示例2:修改表时添加检查约束
# 格式:
alter table 表名 add constraint <检查约束名> check(检查约束)
mysql> alter table t5 add constraint check_id check(id>0);
Query OK, 1 row affected (0.02 sec)
Records: 1  Duplicates: 0  Warnings: 0

6.11 删除表的约束

删除not null约束alter table 表名 modify 列名 类型;删除unique约束alter table 表名 drop index 惟一约束名;删除primary key约束alter table 表名 drop primary key;删除foreign key约束alter table 表名 drop foreign key 外键名;

6.12 存储引擎

  • 数据库存储引擎是数据库底层软件组织,数据库管理系统(DBMS)使用数据引擎进行创建、查询、更新和删除数据,不同的存储引擎提供不同的存储机制、索引技巧、锁定水平等功能。现在许多不同的数据库管理系统都支持多种不同的数据引擎。MySQL的核心就是存储引擎。

  • 插件式存储引擎是MySQL数据库最重要的特性之一, 用户可以根据应用的需要选择如何存储和索引数据、 是否使用事务等,如:

    • MyISAM

      • Mysql 5.5之前的默认数据库引擎,最为常用。

      • 拥有较高的插入,查询速度,但不支持事务应用于以读写操作为主, 很少更新 、 删除 , 并对事务的完整性、 并发性要求不高的情况

    • InnoDB:

      • 事务型速记的首选引擎,支持ACID事务,支持行级锁定

      • 应用于对事务的完整性要求高,在并发条件下要求数据的一致性的情况。

      • InnoDB:是MySQL的默认数据库引擎

    • MEMORY

      • 所有数据置于内存的存储引擎,拥有极高的插入,更新和查询效率。

      • 但是会占用和数据量成正比的内存空间。并且其内容会在MYSQL重新启动是会丢失。

    • Archive

      • 非常适合存储大量的独立的,作为历史记录的数据。

      • 因为它们不经常被读取,则拥有高效的插入速度,但其对查询的支持相对较差

    • Federated :将不同的 MySQL 服务器联合起来,逻辑上组成一个完整的数据库。非常适合分布式应用

    • CSV

      • 逻辑上由逗号分割数据的存储引擎。

      • 它会在数据库子目录里为每个数据表创建一个 .csv 文件。

      • 这是一种普通文本文件,每个数据行占用一个文本行。

      • CSV 存储引擎不支持索引。

    • BlackHole: 黑洞引擎,写入的任何数据都会消失,一般用于记录 binlog 做复制的中继

    • ERFORMANCE_SCHEMA:该引擎主要用于收集数据库服务器性能参数。

  • 默认情况下, 创建表不指定表的存储引擎, 则会使用配置文件的my.ini中default-storage-engine=InnoDB指定的InnoDB

  • 查看支持的引擎命令:

show engines \g
  • 查看当前默认存储引擎

mysql> show variables like '%storage_engine%';
+---------------------------------+-----------+
| Variable_name                   | Value     |
+---------------------------------+-----------+
| default_storage_engine          | InnoDB    |
| default_tmp_storage_engine      | InnoDB    |
| disabled_storage_engines        |           |
| internal_tmp_mem_storage_engine | TempTable |
+---------------------------------+-----------+
  • 在创建表时, 可以指定表的存储引擎:

6.13 总结-完整的建表语句

create table 表名(列名 列类型 [auto_increment] [default 默认值][列约束]...[表约束]) [engine=表类型] [default] charset=字符集;列类型: 该列的数据的存储类型
auto_increment: 自动增尙只能是数值类型的列
defaul 默认值: 设置该列的默认值
约束: 对列的一些限制
engine: 表类型, 也叫表的存储引擎
charset: 设置表的字符篥

6.14 练习

  • 创建销售数据库mydb5_sales

  • 使用该数据库

  • 创建产品表pro_tb (产品编号pro_num int(10) 唯一键 ,产品名pro_name varchar(30) ,产品单价pro_price float(5,2) , 产品规格pro_spe varchar(8) 默认值:件)

  • 创建订单表orders (订单号id int(6) ,客户号customer_id int(4),产品编号pro_num int(10) 外键 ,签订日期signing_date date,金额amount float(5,2) ) , 其中订号单为主键、自增长,金额设置check(大于0)

mysql> create database mydb5_sales;
Query OK, 1 row affected (0.01 sec)mysql> use mydb5_sales;
Database changedmysql> create table pro_tb(pro_num int(10) unique, pro_name varchar(30) not null, pro_price float(5,2) not null, pro_spe varchar(8) default '件' );
Query OK, 0 rows affected, 2 warnings (0.01 sec)mysql> desc  pro_tb;
+-----------+-------------+------+-----+---------+-------+
| Field     | Type        | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| pro_num   | int         | YES  | UNI | NULL    |       |
| pro_name  | varchar(30) | NO   |     | NULL    |       |
| pro_price | float(5,2)  | NO   |     | NULL    |       |
| pro_spe   | varchar(8)  | YES  |     | 件      |       |
+-----------+-------------+------+-----+---------+-------+
4 rows in set (0.01 sec)mysql> create table orders(id int(6) primary key  auto_increment, customer_id int(4) not null, pro_num int(10) not null, signing_date date, amount float(5,2), check(amount>0), foreign key(pro_num) references pro_tb(pro_num));
Query OK, 0 rows affected, 4 warnings (0.02 sec)mysql> desc  orders;
+--------------+------------+------+-----+---------+----------------+
| Field        | Type       | Null | Key | Default | Extra          |
+--------------+------------+------+-----+---------+----------------+
| id           | int        | NO   | PRI | NULL    | auto_increment |
| customer_id  | int        | NO   |     | NULL    |                |
| pro_num      | int        | NO   |     | NULL    |                |
| signing_date | date       | YES  |     | NULL    |                |
| amount       | float(5,2) | YES  |     | NULL    |                |
+--------------+------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

7.MySQL库表设计:范式

7.1 概念

7.2 第一范式(1NF)

  • 原则:库表设计时为了确保原子性,其存储数据具备不可再分性,例:

  • 在上述的学生表中,其中有一个student学生列,这一列存储的数据则明显不符合第一范式:原子性的规定,因为这一列的数据还可以再拆分为姓名、性别、身高三项数据,因此为了符合第一范式,应该将表结构更改为:

  • 如果不去拆分列满足第一范式,会造成什么影响?

    • 客户端语言和表之间无法很好的生成映射关系。

    • 查询到数据后,需要处理数据时,还需要对student字段进行额外拆分。

    • 插入数据时,对于第一个字段的值还需要先拼装后才能进行写入。

7.3 第二范式(2NF)

原则:表中的所有列,其数据都必须依赖于主键,也就是一张表只存储同一类型的数据,不能有任何一列数据与主键没有关系,例:

虽然此时已经满足了数据库的第一范式,但此刻观察course课程、score分数这两列数据,跟前面的几列数据实际上依赖关系并不大,同时也由于这样的结构,导致前面几列的数据出现了大量冗余,所以此时可以再次拆分一下表结构:

经过上述结构优化后,之前的一张表被拆分成学生表、课程表、成绩表三张,每张表中的id字段作为主键,其他字段都依赖这个主键。无论在那张表中,都可以通过id主键确定其他字段的信息,每张表的业务属性都具备“唯一性”,也就是每张表都只会描述了“一件事情”,不会存在一张表中会出现两个业务属性。

7.4 第三范式 (3NF)

  • 原则:表中每一列数据不能与主键之外的字段有直接关系,例:

比如这张学生表,目前即符合第一范式,也符合第二范式,但看最后的两个字段,department表示当前学生所属的院校,dean则表示这个院系的院长是谁。一般来说,一个学生的院长是谁,首先是取决于学生所在的院系的,因此最后的dean字段明显与department字段存在依赖关系,因此需要进一步调整表结构。

  • 经过进一步的结构优化后,又将原本的学生表拆为了院系表、学生表两张,学生表中则是只存储一个院系ID,由院系表存储院系相关的所有数据。至此,学生表中的每个非主键字段与其他非主键字段之间,都是相互独立的,之间不会再存在任何依赖性,所有的字段都依赖于主键。

  • 为什么要这样调整?不调整会发生什么问题:

    • 当一个院系的院长换人后,需要同时修改学生表中的多条数据。

    • 当一个院长离职后,需要删除该院长的记录,会同时删除多条学生信息。

    • ......

    • 如果设计的表结构,无法满足第三范式,在操作表时就会出现异常,使得整个表较难维护。

7.5 三范式小结

  • 范式小结

    • 1NF:确保原子性,表中每一个列数据都必须是不可再分的字段。

    • 2NF:确保唯一性,每张表都只描述一种业务属性,一张表只描述一件事。

    • 3NF:确保独立性,表中除主键外,每个字段之间不存在任何依赖,都是独立的。

  • 没有按照范式设计表时,会存在几个问题

    • 整张表数据比较冗余,同一个学生信息会出现多条。

    • 表结构特别臃肿,不易于操作,要新增一个学生信息时,需添加大量数据。

    • 需要更新其他业务属性的数据时,比如院系院长换人了,需要修改所有学生的记录。

  • 经过三范式的设计优化后,整个库中的所有表结构,会显得更为优雅,灵活性也会更强。

7.6 巴斯-科德范式(BCNF)

  • 概念:

    • 前题:一般在一张表中,可以用于区分每行数据的一个列,通常会被咱们设为主键,例如常用的ID字段就是如此,这类主键通常被称为单一主键,即一个列组成的主键。但除此之外,还有一个联合主键的概念,也就是由多个列组成的主键

    • 巴斯-科德范式也被称为3.5NF,是第三范式的补充版

    • 第三范式的要求是:任何非主键字段不能与其他非主键字段间存在依赖关系,也就是要求每个非主键字段之间要具备独立性。而巴斯-科德范式在第三范式的基础上,进一步要求:任何主属性不能对其他主键子集存在依赖

    • 大白话:规定了联合主键中的某列值,不能与联合主键中的其他列存在依赖关系

例:

  • 分析

    • 这张学生表,此时假设以classes班级字段、class_adviser班主任字段、name学生姓名字段,组合成一个联合主键,在这里我们可以通过联合主键,确定学生表中任何一个学生的信息,比如:熊竹老师管的计算机-2201班,哪个竹子同学有多高啊?可以通过上述的联合主键精准定位到表中第一条数据,并且最终能够给出答案为185cm

    • 出现问题:在这张表中,一条学生信息中的班主任,取决于学生所在的班级,比如「竹子同学、子竹同学」在「计算机-2201班」,所以它们的班主任都是「熊竹老师」,因此班主任字段其实也依赖于班级字段。那会造成什么问题呢?

      • 当一个班级的班主任老师换人后,需要同时修改学生表中的多条数据。

      • 当一个班主任老师离职后,需要删除该老师的记录,会同时删除多条学生信息。

      • 想要增加一个班级时,同时必须添加学生姓名数据,因为主键不允许为空。

  • 通过上述分析可以明显得知,如果联合主键中的一个字段依赖于另一个字段,同样也会造成不小的问题,使得整张表的维护性变差,因此这里需要进一步调整结构:

  • 经过结构调整后:

    • 原本的学生表则又被拆为了班级表、学生表两张,在学生表中只存储班级ID,然后使用classes_id班级IDname学生姓名两个字段作为联合主键。

    • 之前的三个问题也不存在,如换班主任后只需要更改班级表,无需修改学生表中的学生信息;增加班级时,只需要在班级表中新增数据,也不会影响学生表。

  • 小结:第三范式只要求非主键字段之间,不能存在依赖关系,但没要求联合主键中的字段不能存在依赖,因此第三范式并未考虑完善,巴斯-科德范式修正的就是这点,是对第三范式的补充及完善,修正了第三范式。

7.7 第四范式(4NF)

  • 多值依赖:表中的字段之间存在一对多的关系,也就是一个字段的具体值会由多个字段来决定(一个表中至少需要有三个独立的字段才会出现多值依赖问题)

  • 示例:

经典的业务,用户角色权限表,各字段含义:

  • user_name字段 -- 用户名

  • role字段 -- 角色信息:

    • USER:普通用户角色。

    • ADMIN:管理员角色。

    • ROOT:超级管理员角色。

  • permission字段 -- 权限信息:

    • *:超级管理员拥有的权限级别,*表示所有。

    • BACKSTAGE:管理员拥有的权限级别,表示可以操作后台。

    • LOGIN:普通用户拥有的权限级别,表示可以登录访问平台。

  • 此时假设我们需要新增一条数据,那表中的权限字段究竟填什么?这个值是需要依赖多个字段决定的,权限来自于角色,而角色则来自于用户。也就是说,一个用户可以拥有多个角色,同时一个角色可以拥有多个权限,所以此时咱们无法单独根据用户名去确定权限值,权限值必须依赖用户、角色两个字段来决定,这种一个字段的值取决于多个字段才能确定的情况,就被称为多值依赖。

  • 因此第四范式的定义就是要消除表中的多值依赖关系,上述表格拆分为:

  • 观察上述的五张表正是大名鼎鼎的权限五表,将原本的用户角色权限表,拆分成了用户表、角色表、权限表、用户角色关系表、角色权限关系表。

  • 经过这次拆分之后,一方面用户表、角色表、权限表中都不会有数据冗余,第二方面无论是要删除亦或新增一个角色、权限时,都不会影响其他表。后面的两张关系表,主要是为了维护用户、角色、权限三者之间的关系。

7.8 第五范式(5NF)/完美范式

  • 定义:建立在4NF的基础上,进一步消除表中的连接依赖,直到表中的连接依赖都是主键所蕴含的

  • 第五范式解决的是无损连接问题,基本没有实际意义,了解即可,因为无损连接很少出现,而且难以察觉

7.9 第六范式(6NF)/域键范式

域键范式,也被称之为终极范式,但目前也仅有学术机构在研究,在生产环境中实际的用途也不大

7.10 反范式

  • 概念:不遵循数据库范式设计的结构,就被称为反范式结构。

  • 遵循数据库范式设计优点如下:

    • 避免了大量的数据冗余

    • 节省了大量存储空间

    • 表整体结构更为优雅,能让SQL操作更加便捷且减少出错。

  • 但随着范式的级别越高,设计出的结构会更加精细化,原本一张表的数据会被分摊到多张表中存储,表的数量随之越来越多。会存在一个致命问题,也就是当同时需要这些数据时,只能采用联表查询的形式检索数据,有时候甚至为了一个字段的数据,也需要做一次连表查询才能获得。这其中的开销无疑是花费巨大的,尤其是当连接的表不仅两三张而是很多张时,有可能还会造成索引失效,这种情况带来的资源、时间开销简直是一个噩梦,这会严重地影响整个业务系统的性能。

  • 因此,也正是由于上述一些问题,在设计库表结构时,我们不一定要100%遵守范式准则。这种违反数据库范式的设计方法,就被称之为 反范式设计

  • 设计原则:无论那种范式只要能够对业务有利,那就可以称之为好的设计方案。在设计时千万不要拘泥于规则之内,一定要结合实际业务考虑,遵循业务优先的原则去设计结构。

  • 注意:不是所有不遵循数据库范式的结构设计都被称为反范式,反范式设计是指自己知道会破坏范式,但对业务带来好处大于坏处时,刻意设计出破坏范式的结构。

7.11 数据库范式设计总结

  • 经过一系列的阐述后,其实不难发现,越到后面的范式,越难令人理解,同时为了让表满足更高级别的范式,越往后付出代价也越大,而且拆分出的表数量也会越多

  • 一般项目中仅需满足到第三范式或BC范式即可,因为这个度刚刚好,再往后就会因为过于精细化设计,导致整体性能反而下降。

  • 控制到第三范式的级别,一方面数据不会有太多冗余,第二方面也不会对性能影响过大。同时,如若打破范式的设定能对业务更有利,那也可以违背范式原则去设计。

  • 生产项目中库表结构设计的是否合理,区别如下:

    • 不合理的结构设计会造成的问题:

      • 数据冗余,会浪费一定程度上的存储空间

      • 不便于常规SQL操作(例如插入、删除),甚至会出现异常

    • 合理的结构设计带来的好处:

      • 节省空间,SQL执行时能节省内存空间,数据存储时能节省磁盘空间

      • 数据划分较为合理,DB性能整体较高,并且数据也非常完整

      • 结构便于维护和进行常规SQL操作

  • 各范式之间的递进关系图:

  • 范式概念:

    • 第一范式:原子性,每个字段的值不能再分。

    • 第二范式:唯一性,表内每行数据必须描述同一业务属性的数据。

    • 第三范式:独立性,表中每个非主键字段之间不能存在依赖性。

    • 巴斯范式:主键字段独立性,联合主键字段之间不能存在依赖性。

    • 第四范式:表中字段不能存在多值依赖关系。

    • 第五范式:表中字段的数据之间不能存在连接依赖关系。

    • 域键范式:试图研究出一个库表设计时的终极完美范式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/90502.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/90502.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/90502.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DSP的基础平台搭建

1、CCS6.0的安装安装步骤这里就不说了&#xff0c;只谈论最可能遇到的问题&#xff1a;可以看到为需要关闭防火墙和扫描&#xff1b;在这里将其都关闭&#xff0c;然后可以断掉网络&#xff0c;关闭联想管家&#xff0c;可能还是会出现防火墙提示&#xff0c;但是可以安装&…

下一代防火墙-终端安全防护

实验设备1、 山石网科&#xff08;hillstone&#xff09;系列下一代防火墙&#xff08;实训平台v1.0中hillstone设备&#xff09;2、 三层交换机一台&#xff08;实训平台v1.0中cisco vios l2设备&#xff09;3、 二层交换机一台&#xff08;实训平台v1.0中cisco iol switch设备…

Scala实现网页数据采集示例

Scala 可以轻松实现简单的数据采集任务&#xff0c;结合 Akka HTTP&#xff08;高效HTTP客户端&#xff09;和 Jsoup&#xff08;HTML解析库&#xff09;是常见方案。Scala因为受众比较少&#xff0c;而且随着这两年python的热门语言&#xff0c;更让Scala不为人知&#xff0c;…

【IO复用】五种IO模型

文章目录五种IO模型Linux设计哲学BIONIOAIOSIOIO多路复用五种IO模型 Linux设计哲学 在linux系统中&#xff0c;实际上所有的I/O设备都被抽象为了文件这个概念&#xff0c;一切皆文件&#xff0c;磁盘、网络数据、终端&#xff0c;甚至进程间通信工具管道pipe等都被当做文件对…

FeatherScan v4.0 – 适用于Linux的全自动内网信息收集工具

前言 在平时渗透打靶的时候&#xff0c;经常要自己手工输入命令&#xff0c;做各种基本的信息收集&#xff0c;非常的繁琐&#xff0c;所以自研了一款工具&#xff0c;这款工具没有接入AI&#xff0c;因为不合适&#xff0c;接入了AI的话在一些不能上网的环境下进行信息收集&a…

如何精准筛选优质SEO服务资源?

核心要点&#xff1a; 中小企业选择SEO服务常陷困惑——效果难量化、承诺不透明、策略模糊化。本文剖析核心痛点&#xff0c;拆解技术合规性、策略透明度、行业经验匹配度等关键筛选维度&#xff0c;提供一套清晰的评估路径&#xff0c;助您在复杂市场中找到真正专业的合作伙伴…

在教育领域中,如何通过用户ID跑马灯来对视频进行加密?

文章目录前言一、什么是用户跑马灯二、用代码如何实现用户ID跑马灯的功能三、如何通过用户ID跑马灯来对视频进行加密&#xff1f;总结前言 在教育领域&#xff0c;优质视频课程易遭非法传播。为强化版权保护与责任追溯&#xff0c;引入基于用户ID的跑马灯水印技术成为有效手段…

MCP协议:AI时代的“万能插座”如何重构IT生态与未来

MCP协议&#xff1a;AI时代的“万能插座”如何重构IT生态与未来 在人工智能技术爆炸式发展的浪潮中&#xff0c;一个名为Model Context Protocol&#xff08;MCP&#xff09; 的技术协议正以惊人的速度重塑IT行业的底层逻辑。2024年11月由Anthropic首次发布&#xff0c;MCP在短…

同步,异步复位问题

1.同步复位的基本原理是&#xff0c;复位信号仅在时钟的有效边沿影响或重置触发器的状态。复位的主要目标之一是使 ASIC 在仿真时进入已知状态。由于复位树的扇出较大&#xff0c;复位信号相对于时钟周期可能成为 “晚到信号”。即使复位信号会通过复位缓冲树进行缓冲&#xff…

数组和指针回顾,练习与解析

代码见&#xff1a;登录 - Gitee.com 1.数组和指针练习与解析 1.1数组名 1.sizeof(数组名)&#xff0c;这里的数组名表示整个数组&#xff0c;计算的是整个数组的大小。 2.&数组名&#xff0c;这里的数组名表示整个数组&#xff0c;取出的是整个数组的地址。 3.除此之…

【牛客刷题】活动安排

文章目录一、题目介绍二、解题思路2.1 核心问题2.2 贪心策略2.3 正确性证明三、算法分析3.1 为什么按结束时间排序&#xff1f;3.2 复杂度分析3.3 算法流程图解3.3.1 流程图说明3.3.2 关键步骤说明四、模拟演练五、完整代码一、题目介绍 活动安排 题目描述 给定 nnn 个活动&am…

第1讲:C语言常见概念

目录 一、什么是C语言&#xff1f; 二、C语言的历史与成就 三、编译器选择&#xff08;VS2022&#xff09; 1、编译与链接 2、编译器对比 3、VS2022的优缺点 四、VS项目与源文件、头文件介绍 五、第一个C语言程序 六、main函数 七、printf和库函数 八、关键字介绍 …

WinUI3入门18:从APP打开商店链接以及实现内购

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…

BI布局拖拽 (1) 深入react-gird-layout源码

因为有个拖拉拽的需求&#xff0c;类似于quickBi那样的效果。在网上调研了一下发现react-grid-layout实现效果类似&#xff0c;但其也有局限性&#xff0c;比如不支持嵌套&#xff0c;不支持在多个gridLyaout之间互相拖拽。 要求&#xff1a;基于react-grid-layout的思路&#…

CentOS环境搭建-快速升级G++版本

在CentOS环境中快速升级G编译器版本&#xff0c;对于追求最新语言特性的开发者来说至关重要。由于CentOS默认的软件仓库可能不提供G的最新版本&#xff0c;我们通常需要借助第三方软件源&#xff0c;如Developer Toolset或使用Spack等包管理器来完成这一任务。下面将详细介绍两…

分布式接口幂等性的演进和最佳实践,含springBoot 实现(Java版本)

一、背景&#xff1a;为什么需要幂等性 在微服务、分布式架构下&#xff0c;网络不可靠、请求重试机制&#xff08;如前端超时重发、客户端重发、网关重试、消息消费失败重试等&#xff09;会带来重复请求&#xff0c;如果接口没有幂等性&#xff0c;可能导致&#xff1a; 重复…

OGRE 3D----6. 背景图片渲染实现详解

1. 背景图片渲染原理 1.1 渲染队列机制 Ogre3D 使用渲染队列(Render Queue)来控制对象的渲染顺序。背景图片需要在所有其他对象之前渲染,因此我们将其设置为 RENDER_QUEUE_BACKGROUND。 1.2 视图变换控制 为了让背景图片始终保持在场景的最远处,我们需要: 使用单位投影…

K线连续涨跌统计与分析工具

K线连续涨跌统计与分析工具 1. 概述 本工具是一个用于分析金融时间序列数据(特别是K线数据)的Python脚本,主要功能是统计连续n根同方向K线后,第n+1根K线的涨跌情况。该工具不仅提供统计分析功能,还支持图形化标记以验证结果,帮助交易者和量化分析师识别市场中的特定模式…

jQuery EasyUI 简介

jQuery EasyUI 简介 引言 随着互联网技术的飞速发展,前端开发变得越来越重要。jQuery EasyUI 作为一款流行的前端UI框架,极大地简化了前端开发的工作流程,提高了开发效率。本文将详细介绍 jQuery EasyUI 的起源、特点、使用方法以及在实际项目中的应用。 一、jQuery Easy…

《测试开发:从技术角度提升测试效率与质量》

测试开发的核心工作内容与职责解析 一、测试开发的定位与核心价值 测试开发&#xff08;Test Development&#xff0c;简称 TestDev 或 SDET&#xff09;是融合软件开发能力与测试工程思维的复合型岗位&#xff0c;不同于传统测试工程师&#xff0c;其核心目标是通过技术手段提…