网络运维Day17

文章目录

  • 什么是数据库
  • MySQL介绍
  • 实验环境准备
  • 构建MySQL服务
    • 连接数据库
    • 修改root密码
  • 数据库基础
    • 常用的SQL命令分类
    • SQL命令使用规则
    • MySQL基本操作
      • 创建库
      • 创建表
      • 查看表结构
    • 记录管理命令
  • 数据类型
    • 数值类型
  • 数据类型
    • 日期时间类型
    • 时间函数
    • 案例
    • 枚举类型
  • 约束条件
    • 案例
    • 修改表结构
      • 添加新字段ADD
      • 修改字段类型MODIFY
      • 删除字段DROP
      • 修改字段名CHANGE
      • 修改表名RENAME
  • 普通索引
    • 索引概述
    • 索引的特点
    • 建表时创建普通索引
    • 在已有表创建/删除索引
    • 查看索引信息
  • 高级字段约束
    • 主键
    • 外键
  • 总结

什么是数据库

  • 数据库概述:数据库是按照一定的数据结构将数据存储在存储器的集合

  • 常见数据库软件

软件名开源跨平台厂 商
Oracle甲骨文
MySQL甲骨文
SQL Server微软
DB2IBM
openGauss华为
Redis开源软件
Memcached开源软件
openGauss华为
  • DB (DataBase)

    • 数据库
    • 依照某种数据模型进行组织并存放到存储器的数据集合
  • DBMS (DataBase Management System)

    • 数据库管理系统

    • 用来操纵和管理数据库的服务软件

  • DBS (DataBase System)

    • 数据库系统:即 DB+DBMS
    • 指带有数据库并整合了数据库管理软件的计算机系统

MySQL介绍

  • 主要特点
    • 适用于中小规模、关系型数据库系统
    • 支持Linux、Unix、Windows等多种操作系统
    • 支持Python、Java、Perl、PHP等编程语言
    • LAMP平台,与Apache HTTP Server组合
    • LNMP平台,与Nginx组合

实验环境准备

  • 使用CentOS7.9模板机克隆mysql虚拟机,配置信息如下
主机名内网IP地址
mysql192.168.8.100(VMnet8网络模式)

配置基础环境

[root@localhost ~]# hostnamectl set-hostname mysql
[root@mysql ~]# nmcli connection modify ens33 ipv4.method auto connection.autoconnect yes
[root@mysql ~]# nmcli connection up ens33

配置yum,使用阿里云的镜像站点

[root@localhost ~]# rm -rf /etc/yum.repos.d/*.repo	 	#删除自带的repo文件
[root@localhost ~]# wget -O /etc/yum.repos.d/CentOS-Base.repo \ https://mirrors.aliyun.com/repo/Centos-7.repo		     #下载阿里镜像源

构建MySQL服务

将学习环境中的:C-4软件运维\05_医疗项目\HIS医疗项目\mysql8-centos7上传到虚拟机mysql的/root/

mysql主机操作

[root@mysql ~]# cd  /root/mysql8-centos7
[root@mysql ~]# yum -y  localinstall *.rpm				#安装mysql
[root@mysql ~]# systemctl   start      mysqld     		#启动服务
[root@mysql ~]# systemctl   enable   mysqld    			#开机运行
[root@mysql ~]# ss  -utnlp  |  grep  :3306  			#查看服务信息

软件相关的目录与文件等

文件说明
主配置文件/etc/my.cnf.d/mysql-server.cnf
数据库目录/var/lib/mysql
端口号3306
进程名mysqld
传输协议TCP
进程所有者mysql
进程所属组mysql
错误日志文件/var/log/mysql/mysqld.log

连接数据库

  • 数据库管理员名为 root

  • 连接命令: mysql -h数据库地址 -u用户 -p密码

  • 首次启动之后数据库管理root的密码存放再/var/log/mysqld.log中

  • 连接时不指定密码,默认为无密码

[root@mysql mysql8-centos7]# grep -i password /var/log/mysqld.log	#过滤root初始密码
2023-08-08T14:22:39.197619Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: 3Izdh9OY6&Ef

连接mysql(每个人过滤到的mysql管理员root的初始密码都是随机的,不要照抄,建议加上’')

[root@mysql ~]# mysql -uroot -p'3Izdh9OY6&Ef'

修改root密码

  • 格式:使用 ALTER USER 用户@“主机” IDENTIFIED BY “密码”;
  • 新密码必须满足密码策略
  • 管理员root 使用新密码连接服务
mysql> ALTER USER root@"localhost" IDENTIFIED BY "tedu123...A";  	 #修改登陆密码
[root@mysql ~]# mysql -hlocalhost  -uroot  -p'tedu123...A'	         #使用新密码登陆

数据库基础

常用的SQL命令分类

  • 管理数据库使用SQL(结构化查询语言)

  • DDL 数据定义语言 如:CREATE、ALTER、DROP

  • DML 数据操作语言 如:INSERT、UPDATE、DELETE

  • DCL 数据控制语言 如:GRANT、REVOKE

  • DTL 数据事务语言 如:COMMIT、ROLLBACK、SAVEPOINT

SQL命令使用规则

  • SQL命令不区分字母大小写(密码、变量值除外)

  • 每条SQL命令以;结束

  • 默认命令不支持Tab键自动补齐

  • \c 终止sql命令

MySQL基本操作

  • 可以创建多个库,通过库名区分
  • SHOW DATABASES; #显示已有的库
  • SELECT USER(); #显示连接用户
  • USE 库名; #切换库
  • SELECT DATABASE(); #显示当前所在的库
  • CREATE DATABASE 库名; #创建新库
  • SHOW TABLES; #显示已有的表
  • DROP DATABASE 库名; #删除库

创建库

  • 库命名规则
    • 仅可以使用数字、字母、下划线、不能纯数字
    • 区分字母大小写,具有唯一性
    • 不可使用指令关键字、特殊字符
mysql> CREATE DATABASE  DB1;			#创建库DB1
Query OK, 1 row affected (0.06 sec)
mysql> CREATE DATABASE  db1;			#创建库db1
Query OK, 1 row affected (0.03 sec)
mysql> CREATE DATABASE  haha;			#创建库haha
Query OK, 1 row affected (0.03 sec)
mysql> USE DB1;							#切换至DB1库
mysql> SHOW TABLES;						#查看DB1库里有哪些表
mysql> DROP DATABASE haha;				#删除库haha
mysql> SELECT USER();					#查看当前登录数据库的用户
SELECT  DATABASE();						#查看当前所在库

创建表

  • 格式
mysql> CREATE TABLE 库名.表名(
       字段名1  类型(宽度),
       字段名2  类型(宽度),
	   ……
       )DEFAULT CHARSET=utf8; 

创建db1.stuinfo表,包含name字段、homeaddr字段,指定字符集为utf8

mysql> CREATE TABLE db1.stuinfo(
    ->  name    CHAR(15),
    ->  homeaddr   CHAR(20)
    ->  ) DEFAULT CHARSET=utf8;

查看表结构

  • DESC 库名.表名;
mysql> DESC db1.stuinfo;
+----------+----------+------+-----+---------+-------+
| Field    | Type     | Null | Key | Default | Extra |
+----------+----------+------+-----+---------+-------+
| name     | char(15) | YES  |     | NULL    |       |
| homeaddr | char(20) | YES  |     | NULL    |       |
+----------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)

记录管理命令

  • 查询

    • SELECT * FROM 库名.表名;
  • 插入

    • INSERT INTO 库名.表名 VALUES(值列表);
  • 修改

    • UPDATE 库名.表名 SET 字段=值;
  • 删除

    • DELETE FROM 表名;

向db1.stuinfo表里插入一行记录

mysql> INSERT INTO db1.stuinfo VALUES("sam","Beijing");

查询db1.stuinfo表格里的所有数据

mysql> SELECT  *  FROM db1.stuinfo;

修改db1.stuinfo表格里边的homeaddr字段内容为"Shanghai"

mysql> UPDATE   db1.stuinfo  SET homeaddr="Shanghai";

删除db1.stuinfo表里边的所有数据

mysql> DELETE FROM db1.stuinfo;
mysql> SELECT  *  FROM db1.stuinfo;							#查看验证

数据类型

  • 定长:CHAR(字符个数)
    • 最大字符个数255
    • 不够指定字符个数时在右边用空格补全
    • 字符个数超出时,无法写入数据。
mysql> CREATE  TABLE db1.t1(name char(5) , homedir CHAR(50) );	#创建表格
mysql> INSERT INTO db1.t1 VALUES("bob","USA");					#写入数据
  • 变长:VARCHAR(字符个数)

    • 按数据实际大小分配存储空间(0-65535)

    • 字符个数超出时,无法写入数据。

    • 大文本类型:text/blob

    • 字符数大于65535存储时使用

创建db1.t2表,包含name CHAR(5)、email VARCHAR(30)

mysql> CREATE TABLE db1.t2(name CHAR(5),
       -> email VARCHAR(30)
       -> );
mysql> INSERT INTO db1.t2 VALUES("lucy","lucy@tedu.cn");

数值类型

  • 整数型
类 型名称有符号范围无符号范围
TINYINT微小整数-128~1270 ~ 255
SMALLINT小整数-32768~327670 ~ 65535
MEDIUMINT中整型-223 ~ 223-10 ~ 224-1
INT大整型-231 ~ 231-10 ~ 232-1
BIGINT极大整型-263 ~ 263-10 ~ 264-1
UNSIGNED使用无符号存储范围
  • 浮点数
类 型名称有符号范围无符号范围
FLOAT单精度-3.402823466E+38 到 -1.175494351E-381.175494351E-38 到 3.402823466E+38
DOUBLE双精度-1.7976931348623157E+308到 -2.2250738585072014E-3082.2250738585072014E-308 到 1.7976931348623157E+308
mysql> CREATE  TABLE db1.t3(pay FLOAT , id DOUBLE);
mysql> CREATE  TABLE db1.t4(pay FLOAT(5,2) , id DOUBLE(4,2) );

数据类型

日期时间类型

  • 日期 DATE
    • 范围:0001-01-01 ~ 9999-12-31
    • 格式: yyyy-mm-dd 1949-10-01
  • YEAR
    • 范围:1901~2155
    • 格式:yyyy 1998 2000
    • 要求使用4位数赋值
    • 当使用2位数赋值时:01-99(1970-2069某个年份)
    • 00~69视为 2000~2069
    • 70~99视为 1970~1999
  • 时间 TIME
    • 格式:HH:MM:SS 22:18:28
  • 日期时间 DATETIME
    • 范围:1000-01-01 00:00:00~ 9999-12-31 23:59:59
    • 格式: “YYYY-MM-DD HH:MM:SS”
  • 日期时间 TIMESTAMP
    • 范围:1970-01-01 00:00:00 ~ 2038-01-19 00:00:00
    • 格式: “YYYY-MM-DD HH:MM:SS”
    • 当未给TIMESTAMP类型字段赋值时,自动以当前系统时间赋值,而DATETIME 值为 NULL (空)

时间函数

  • 函数服务内置的命令,可以使用时间函数给字段赋值
类 型用 途
CURTIME( )获取当前的系统时间"时:分:秒"部分
CURDATE( )获取当前的系统时间"年-月-日"部分
NOW( )获取当前系统时间"年-月-日 时:分:秒"
YEAR(NOW())获取年
MONTH(NOW( ))获取月
DAY(NOW())获取日
DATE(NOW())获取日期"年-月-日"
TIME(NOW())获取时间"时:分:秒"
[root@mysql ~] mysql -uroot -p'密码' 		   #连接数据库
mysql> SELECT CURTIME();					#查看"时:分:秒"
mysql> SELECT CURDATE();					#查看"年-月-日"
mysql> SELECT NOW();						#查看"年-月-日 时:分:秒"
mysql> SELECT YEAR(NOW());					#查看"年-月-日 时:分:秒"

案例

  • 新建库bbsdb
[root@mysql ~]# mysql –uroot –p密码		   #连接数据库
mysql> CREATE DATABASE bbsdb;			    #创建库bbsdb
  • 创建bbsdb.t5表
    • 包含name字段 CHAR(15)类型
    • 包含s_year字段 YEAR类型
    • 包含school_time字段 TIME类型
    • 包含birthday字段 DATE类型
    • 包含party DATETIME类型

创建bbsdb.t5表

mysql> CREATE TABLE bbsdb.t5(name CHAR(15),s_year YEAR,
       -> school_time TIME, birthday DATE,
       -> party DATETIME);

向bbsdb.t5表插入数据

mysql> INSERT INTO bbsdb.t5 VALUES("sam",1980,"19:00:00",
       -> "1980-10-06","2029-06-18 12:05:16");

查询bbsdb.t5表数据

mysql> SELECT * FROM bbsdb.t5;					
+------+--------+-------------+------------+---------------------+
| name | s_year | school_time | birthday   | party               |
+------+--------+-------------+------------+---------------------+
| sam  |   1980 | 19:00:00    | 1980-10-06 | 2029-06-18 12:05:16 |
+------+--------+-------------+------------+---------------------+
1 row in set (0.00 sec)	

枚举类型

  • ENUM 单选
    • 格式:字段名 ENUM(值1, 值2, 值N)
    • 仅能在列表里选择一个值

创建db1.t5表,包含name字段 CHAR类型15个宽度,sex字段单选枚举类型(“boy”,“girl”,“other”)

mysql> CREATE TABLE db1.t5(
       -> name CHAR(15),
       -> sex ENUM("boy","girl","other")
       -> );

向db1.t5表插入数据

mysql> INSERT INTO db1.t5 VALUES("sam","boy");	
  • SET 多选
    • 格式:字段名 SET(值1, 值2, 值N)
    • 在列表里选择一个或多个值

创建db1.t6表,包含name字段CHAR类型5个宽度,likes字段多选枚举类型(“eat”, “game” , “music”, “money”)

mysql> CREATE  TABLE db1.t6(
        -> name   CHAR(5),
        -> likes	 SET("eat", "game" , "music", "money" )   
        -> );

向db1.t6表插入数据

mysql> INSERT INTO db1.t6 VALUES("lisi","eat,game,music");

约束条件

  • NULL 允许为空(默认设置)
  • NOT NULL 不允许为空
  • KEY 键值类型
  • DEFAULT 设置默认值,缺省为NULL
  • EXTRA 额外设置

案例

  • 创建db1.t7表
    • name字段 CHAR类型10个宽度,不允许为空
    • age字段 TINYINT类型无符号范围,默认值19
    • class字段CHAR类型7个宽度,不允许为空,默认值为"nsd"
    • pay字段FLOAT(7,2)类型,默认值为28000
mysql> CREATE TABLE db1.t7(
        -> name CHAR(10) NOT NULL,
        -> age TINYINT UNSIGNED DEFAULT 19,
        -> class CHAR(7) NOT NULL DEFAULT "nsd",
        -> pay FLOAT(7,2) DEFAULT 28000
        -> );

插入数据,不使用默认值

mysql> INSERT INTO db1.t7 VALUES ('Alice', 22, 'nsd', 35000.50);

插入数据,使用默认值

mysql> INSERT INTO db1.t7(name) VALUES("Bob");

查询db1.t7表中的数据

mysql> SELECT * FROM db1.t7;                                                         
+-------+------+-------+----------+
| name  | age  | class | pay      |
+-------+------+-------+----------+
| Alice |   22 | nsd   | 35000.50 |
| Bob   |   19 | nsd   | 28000.00 |
+-------+------+-------+----------+
2 rows in set (0.00 sec)

修改表结构

  • 格式:mysql> ALTER TABLE 库名.表名 执行动作;
  • 执行动作
    • ADD 添加字段
    • MODIFY 修改字段类型
    • CHANGE 修改字段名
    • DROP 删除字段
    • RENAME 修改表名

添加新字段ADD

  • 新字段默认添加在字段末尾
  • mysql> ALTER TABLE 库名.表名 ADD 字段名 类型(宽度) 约束条件 [ AFTER 字段名 | FIRST ] ;

修改db1.t6表,在likes字段后,添加home字段VARCHAR类型20个宽度

mysql> ALTER TABLE db1.t6 ADD home VARCHAR(20) AFTER likes;

修改字段类型MODIFY

  • mysql> ALTER TABLE 库名.表名 MODIFY 字段名 类型(宽度) 约束条件 [ AFTER 字段名 | FIRST ] ;
  • 注:修改的字段类型不能与已存储的数据冲突

修改db1.t6表结构,将home字段修改为CHAR类型,30个宽度

mysql> ALTER TABLE db1.t6 MODIFY home CHAR(30) ;

删除字段DROP

  • mysql> ALTER TABLE 库名.表名 DROP 字段名 ;
  • 表中有多条记录时,所有列的此字段的值都会被删除

删除db1.t6表中的home字段

mysql> ALTER TABLE db1.t6 DROP home ;

修改字段名CHANGE

  • mysql> ALTER TABLE 库名.表名 CHANGE 原字段名 新字段名 类型 约束条件 ;

修改db1.t6表中name字段为user,VARCHAR类型30个宽度

mysql> ALTER TABLE db1.t6 CHANGE  name user VARCHAR(30);

修改表名RENAME

  • 表对应的文件名,也被改变
  • 表记录不受影响
  • mysql> ALTER TABLE 表名 RENAME 新表名

修改db1.t6表名为db1.userinfo

mysql> ALTER TABLE db1.t6 rename db1.userinfo;

普通索引

  • index 普通索引
  • unique 唯一索引
  • fulltext 全文索引
  • primary key 主键
  • foreign key 外键

索引概述

  • 类似于书的目录
  • 对表中字段值进行排序。
  • 索引算法:Btree、B+tree 、hash

在这里插入图片描述

索引的特点

  • 索引优点
    • 可以加快数据的查询速度
  • 索引缺点
    • 当对表中的数据进行增加、删除和修改的时候,索引也要动态的调整,降低了数据的维护速度
    • 索引需要占物理空间

建表时创建普通索引

  • 具体要求如下:
    • 一个表中可以有多个index字段
    • 字段的值允许重复,且可以赋NULL值
    • index字段 标志是 MUL
    • 通常把做为查询条件的字段设置为index字段
  • 建表时创建索引
    • INDEX(字段名), INDEX(字段名) … …
  • 创建db1.t9其中包含
    • id字段,CHAR类型,宽度为 6,不能为空。该字段被定义为一个索引。
    • name字段,VARCHAR类型,宽度为 4,不能为空。该字段也被定义为一个索引。
    • age字段INT类型,不能为空。
    • gender字段ENUM类型,只能是 “male” 或者 “female”。该字段可以为空
mysql> CREATE TABLE db1.t9( id CHAR(6) NOT NULL, 
    -> name VARCHAR(4) NOT NULL, age INT NOT NULL, 
    -> gender ENUM("male","female"), INDEX(id),INDEX(name));

在已有表创建/删除索引

  • 创建索引:CREATE INDEX 索引名 ON 表名(字段名);
  • 删除索引:DROP INDEX 索引名 ON 表名;

在db1.t9表中将age字段设置为索引字段,索引名为age_index

mysql> CREATE INDEX age_index ON db1.t9 (age);

删除db1.t9表中的age_index字段

mysql> DROP INDEX age_index ON db1.t9;

查看索引信息

  • SHOW INDEX FROM 库名.表名 \G;
    • 注:\G表示以垂直格式输出查询结果

查看db1.t9表索引

mysql> SHOW INDEX FROM db1.t9 \G

高级字段约束

主键

  • 主键约束:用于保证字段值具有唯一性并且非空,一张表中只能有一个主键

单列主键测试

mysql> CREATE DATABASE execdb;								#创建execdb
mysql> USE execdb;											#使用execdb库
mysql> CREATE TABLE t4 (name CHAR(5) PRIMARY KEY);			#设置主键约束语法1
mysql> DESC t4;

mysql> CREATE TABLE t5 (name CHAR(5),PRIMARY KEY(name));	#设置主键约束语法2
mysql> DESC t5;
mysql> INSERT INTO t5 VALUES ('zhsan');						#写入成功
mysql> INSERT INTO t5 VALUES ('zhsan');						#值重复,写入失败
ERROR 1062 (23000): Duplicate entry 'zhsan' for key 'PRIMARY'
mysql> INSERT INTO t5 VALUES (NULL);						#值为空,写入失败
ERROR 1048 (23000): Column 'name' cannot be null

mysql> ALTER TABLE t5 DROP PRIMARY KEY;						#删除已有主键
mysql> DESC t5;
mysql> ALTER TABLE t5 ADD PRIMARY KEY(name);				#添加主键约束
mysql> DESC t5;

复合主键测试(多字段组合结果不重复即可)

mysql> CREATE TABLE execdb.t6 (
    -> user CHAR(10),
    -> host CHAR(15),
    -> status ENUM('allow','deny') NOT NULL DEFAULT "deny",
    -> PRIMARY KEY(user,host)
    -> );											#创建execdb.t6表测试复合主键

mysql> DESC t6;

mysql> INSERT INTO t6 VALUES
    -> ('abc','1.1.1.1','allow'),
    -> ('abc','1.1.1.2','deny'),
    -> ('haha','1.1.1.1','deny');					#写入成功

mysql> INSERT INTO t6 VALUES
    -> ('haha','1.1.1.1','allow');					#组合结果与已有数据冲突,写入失败
ERROR 1062 (23000): Duplicate entry 'haha-1.1.1.1' for key 'PRIMARY'

mysql> ALTER TABLE t6 DROP PRIMARY KEY;				#删除已有复合主键
mysql> DESC t6;

mysql> ALTER TABLE t6 ADD PRIMARY KEY(user,host);	#向已有表添加复合主键
mysql> DESC t6;

自增长测试

mysql> CREATE TABLE t7 (
    -> id INT PRIMARY KEY AUTO_INCREMENT,
    -> name CHAR(10)
    -> );									#PRIMARY KEY与AUTO_iNCREMENT联用
mysql> DESC t7;

mysql> CREATE TABLE t8(
    -> id INT AUTO_INCREMENT,
    -> name CHAR(10),
    -> PRIMARY KEY(id)
    -> );									#PRIMARY KEY与AUTO_INCREMENT分开用
mysql> DESC t8;

mysql> INSERT INTO t8(name) VALUES ('bob');		#id从1开始
mysql> INSERT INTO t8(name) VALUES ('tom');		#id为2
mysql> SELECT * FROM t8;

mysql> INSERT INTO t8 VALUES (10,'jim');		#可以指定id赋值
mysql> INSERT INTO t8(name) VALUES ('john');	#识别id字段最大值
mysql> SELECT * FROM t8;

mysql> DELETE FROM t8;							#清空表记录,验证自增长是否重置
mysql> INSERT INTO t8(name) VALUES ('haha');	#测试写入
mysql> SELECT * FROM t8;						#自增长未重置

mysql> TRUNCATE TABLE t8;						#TRUNCATE语句快速清表
mysql> INSERT INTO t8(name) VALUES ('haha');	#测试写入记录

mysql> SELECT * FROM t8;						#id自增长重置
mysql> DELETE FROM t8;
#主键不一定自增,但被标记自增的一定是主键

外键

  • 外键约束:保证数据的一致性,外键字段值必须在参考表中字段已有值里选择,一张表中可以有多个外键
  • 表存储引擎必须是innodb (在进阶课程里讲 现在仅需要知道如何指定表使用innodb存储引擎)
  • 外键表字段与被关联表字段类型要一致
  • 被参照字段必须要是索引类型的一种(通常是PRIMARY KEY)
mysql> SHOW VARIABLES LIKE "default_storage_engine";
+------------------------+--------+
| Variable_name          | Value  |
+------------------------+--------+
| default_storage_engine | InnoDB |
+------------------------+--------+
1 row in set (0.00 sec)

在execdb中,创建员工表emp(包含ID字段,INT类型,主键,自增长;name字段CHAR类型20个宽度)

在execdb中,创建工资表salary(包含id字段 ,INT类型,wage字段,FLOAT类型)

将execdb.salary表的id字段设置为外键,依赖于execdb.emp表的id字段

mysql> USE execdb;							#切换到练习库

mysql> CREATE TABLE emp (
    -> id INT PRIMARY KEY AUTO_INCREMENT,
    -> name CHAR(20) 
    -> );									#创建练习emp表,用于存储员工信息
Query OK, 0 rows affected (0.00 sec)

mysql> DESC emp;							#查看emp表结构
+-------+----------+------+-----+---------+----------------+
| Field | Type     | Null | Key | Default | Extra          |
+-------+----------+------+-----+---------+----------------+
| id    | int(11)  | NO   | PRI | NULL    | auto_increment |
| name  | char(20) | YES  |     | NULL    |                |
+-------+----------+------+-----+---------+----------------+
2 rows in set (0.00 sec)


mysql> CREATE TABLE salary( 
    -> id INT, 
    -> wage FLOAT,
    -> FOREIGN KEY(id) REFERENCES emp(id)
    -> ON UPDATE CASCADE
    -> ON DELETE CASCADE
	-> );									#创建练习salary表,用于存储员工某个月工资
Query OK, 0 rows affected (0.00 sec)
	
mysql> DESC salary;							#查看salary表结构
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | YES  | MUL | NULL    |       |
| wage  | float   | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)

##测试外键约束
mysql> INSERT INTO salary VALUES (1,5000);		#写入失败,emp表中id字段无值
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`execdb`.`salary`, CONSTRAINT `salary_ibfk_1` FOREIGN KEY (`id`) REFERENCES `emp` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)

mysql> INSERT INTO emp(name) VALUES ('zhangsan'),('lisi');	#添加员工记录(一次插入2行)

mysql> SELECT * FROM emp;									#查看已有员工记录

mysql> INSERT INTO salary VALUES (1,5000);					#给id是1的员工发5000,成功
mysql> INSERT INTO salary VALUES (2,4000);					#给id是2的员工发4000,成功

##验证级联更新(ON UPDATE CASCADE)
mysql> SELECT * FROM emp;						#查询emp表记录
mysql> SELECT * FROM salary;					#查询salary表记录

mysql> UPDATE emp SET id=5 WHERE name='lisi';	#更新emp表中lisi用户id为5

mysql> SELECT * FROM emp;						#确认emp表中lisi的id已更新为5
mysql> SELECT * FROM salary;					#此过程中并未操作salary表,但数据已发生变化

##验证级联删除(ON DELETE CASCADE)
mysql> SELECT * FROM emp;						#查询emp表记录
mysql> SELECT * FROM salary;					#查询salary表记录

mysql> DELETE FROM emp WHERE id=5;				#删除emp表中id为5的表记录
mysql> SELECT * FROM emp;						#确认id为5的记录被删除
mysql> SELECT * FROM salary;					#此过程中并未操作salary表,但数据已发生变化

##外键操作语法
mysql> SHOW CREATE TABLE salary;							#查看完整建表语句

mysql> ALTER TABLE salary DROP FOREIGN KEY `salary_ibfk_1`;	#删除指定外键

mysql> SHOW CREATE TABLE salary;							#查看完整建表语句

mysql> ALTER TABLE salary 
	-> ADD FOREIGN KEY(id) REFERENCES emp(id) 
	-> ON UPDATE CASCADE ON DELETE CASCADE;					#向已有表添加外键

mysql> SHOW CREATE TABLE salary;							#查看完整建表语句

##注意事项
mysql> DROP TABLE emp;										#被关联表不允许删除
ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fails
mysql> 

mysql> SELECT * FROM salary;					#查看salary表记录
mysql> INSERT INTO salary VALUES (1,2000);		#给员工重复发工资
mysql> SELECT * FROM salary;					#重复工资下发成功,该现象不合理
mysql> DESC salary;							#查看salary表结构,id字段不能重复(PRIMARY KEY)

mysql> ALTER TABLE salary ADD PRIMARY KEY(id);	#给salary表id字段添加主键,失败,数据重复
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'

mysql> DELETE FROM salary WHERE wage=2000;		#清理重复数据
mysql> ALTER TABLE salary ADD PRIMARY KEY(id);	#给salary表id字段添加主键,成功
mysql> DESC salary;								#查看salary表结构,id字段标签

mysql> INSERT INTO salary VALUES (1,2000);		#再次测试重复工资,下发失败
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
mysql> SHOW CREATE TABLE salary;				#查看salary建表语句
#PRIMARY KEY和FOREIGN KEY可以共存

总结

  • 搭建MySQL数据库服务器
  • 数据库基础
  • 掌握MySQ基本管理命令
  • 数据类型(字符类型、数值类型、浮点型)
  • 掌握修改表结构
  • 掌握索引的作用
  • 掌握主键与外键的作用及使用方法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/146921.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++实现ransac

目录 一、ransac算法原理 1.1、算法概念 1.2、图解 二、c实现ransac 2.1、设置随机样本和离群点 2.2、随机抽取样本 2.3、内点计算 2.4、更新参数 2.2、完整代码 一、ransac算法原理 1.1、算法概念 随机抽样一致性 (RANSAC) 是一种迭代方法,用于根据一组包…

【Java 进阶篇】JQuery DOM操作:CRUD操作的前端魔法

在前端开发的舞台上,CRUD(Create, Read, Update, Delete)操作是一种极为重要的技能,它涉及对页面元素的增删改查。而JQuery,这位前端开发的魔法师,为我们提供了便捷而强大的方法,使得CRUD操作变…

IP地址如何实现定位功能?

网络犯罪、保护网络安全的重要手段。近日,一则新闻引起了广大网友的关注:IP也能实现定位功能,这是如何做到的呢?本文将对此进行深入解析。 首先,我们需要了解什么是IP地址定位。IP地址定位是通过IP地址确定网络用户所在…

【Windows 开发环境配置——NVIDIA 篇】CUDA、cuDNN、TensorRT 三件套安装

CUDA 从CUDA Toolkit Archive下载相应版本的离线安装包,这里以11.7为例。 打开安装包,在安装选项选择自定义模式,点击下一步。 在自定义安装选项中,仅选择CUDA组件(其中Nsight相关组件用于代码调试与性能分析&#xff…

Linux--线程概念+线程控制

1.什么是线程 相对于进程而言,进程是承担资源调度的实体,线程在进程内部运行,是操作系统调度的基本单位。 在一个程序里的一个执行路线就叫做线程(thread)。更准确的定义是:线程是“一个进程内部的控制序列…

Qt QWebEngine 加载网页及交互,实现C++与JS 相互调用

目录 前言1、QtWebEngine介绍2、安装3、核心类介绍3.1 QWebEngineView3.2 QWebEnginePage3.3 QWebEngineProfile3.4 QWebEngineHistory3.5 QWebEngineSettings 4、加载网页5、C调用JS5.1 无返回值5.2 有返回值 6、JS调用C6.1 新建WebObject 类继承自QObject。6.2 将WebObject对…

Day30力扣打卡

打卡记录 最长回文子序列(区间DP) 链接 class Solution:def longestPalindromeSubseq(self, s: str) -> int:n len(s)f [[0] * n for _ in range(n)]max lambda x, y: x if x > y else yfor i in range(n - 1, -1, -1):f[i][i] 1for j in ra…

数据结构第三课 -----线性表之双向链表

作者前言 🎂 ✨✨✨✨✨✨🍧🍧🍧🍧🍧🍧🍧🎂 ​🎂 作者介绍: 🎂🎂 🎂 🎉🎉&#x1f389…

用Java开发一个扫雷游戏

以下是用Java开发一个扫雷游戏的基本步骤: 创建一个窗口和画布,用来显示游戏界面。 创建一个游戏逻辑类,包含一些基本的操作,如生成地雷、计算周围地雷数量、打开方格等。 在画布上绘制游戏界面,包括格子、数字、地雷…

人工智能与大数据:驱动现代业务转型的双引擎

在当今数字化时代,人工智能(AI)和大数据已成为驱动业务和技术创新的关键力量。它们的结合不仅重塑了传统行业,也催生了新的商业模式和服务方式。 AI与大数据在零售行业的应用 在零售行业,AI和大数据的应用已经成为提…

《洛谷深入浅出进阶篇》 P2367语文成绩——差分

上链接:P2367 语文成绩 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P2367 上题干: 题目背景 语文考试结束了,成绩还是一如既往地有问题。 题目描述 语文老师总是写错成绩,所以当她修改成绩的…

三、Eureka注册中心

目录 一、作用及调用方式 二、搭建eureka注册中心 三、注册user-service和order-service 四、新增实例 五、服务拉取 六、总结 一、作用及调用方式 在服务提供者启动时,它会向eureka注册中心提供自己的信息,并每30秒进行一次刷新eureka注册中心保存…

golang中context使用总结

一、context使用注意事项 在使用context时,有一些需要注意的事项,以及一些与性能优化相关的建议: 避免滥用context传递数据:context的主要目的是传递请求范围的数据和取消信号,而不是用于传递全局状态或大量数据。滥用…

SARAS算法

SARAS算法 代码仓库:https://github.com/daiyizheng/DL/tree/master/09-rl Sarsa算法是一种强化学习算法,用于解决马尔可夫决策过程(MDP)问题。它是一种基于值函数的方法,可以用于学习最优策略。本文将介绍Sarsa算法的流程。 S…

汽车以太网IOP测试新利器

IOP测试目的 汽车以太网物理层IOP(Interoperability )测试,即测试被测对象以太网物理层之间的互操作性。用于验证车载以太网PHY能否在有限时间内建立稳定的链路;此外,还用于验证车载以太网PHY可靠性相关的诊断特性&am…

滚雪球学Java(63):Java高级集合之TreeSet:什么是它,为什么使用它?

咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java SE相关知识点了,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好…

Java Elasticsearch 按一定时间间隔(timeInterval)循环查询数据

最近有个需求&#xff0c;前端传入时间间隔&#xff0c;去elasticsearch按照时间间隔统计每个时间间隔内数据量。 public List<HashMap<String,Object>> getCount(RequestParam Integer time, RequestParam String selectedDatedTime) {SimpleDateFormat format n…

Karmada调度器

调度器就像一个发动机&#xff0c;如果没有了发动机输入动力&#xff0c;是无法正常运行的。就像 Kubernetes 的调度器&#xff0c;它会负责根据节点的资源状态、Pod 的运行状态&#xff0c;判断 Pod 是调度到怎样的集群节点上去。对于 Karmada 这样的多云能力的调度器来说&…

Webpack 性能优化 二次编译速度提升3倍!

本文作者为 360 奇舞团前端开发工程师 Rien. 本篇文章主要记录 webpack 的一次性能优化。 现状 随着业务复杂度的不断增加&#xff0c;项目也开始变得庞大&#xff0c;工程模块的体积也不断增加&#xff0c;webpack 编译的时间也会越来越久&#xff0c;我们现在的项目二次编译的…

【fbtft】如何添加fbtft驱动

获取lcd ic的datasheet&#xff0c;或者直接找到其他平台&#xff08;linux&#xff0c;stm32&#xff0c;esp32&#xff09;的驱动 我用的是合宙的esp32驱动&#xff0c;注意是c语言的&#xff0c;合宙上层用lua封装了&#xff0c;需要找到sdk源码。 源码路径&#xff1a; …