网络运维Day17

文章目录

什么是数据库

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

  • 常见数据库软件

软件名 开源 跨平台 厂 商
Oracle 甲骨文
MySQL 甲骨文
SQL Server 微软
DB2 IBM
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地址
mysql 192.168.8.100(VMnet8网络模式)

配置基础环境

shell 复制代码
[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,使用阿里云的镜像站点

shell 复制代码
[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主机操作

shell 复制代码
[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中

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

shell 复制代码
[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的初始密码都是随机的,不要照抄,建议加上'')

shell 复制代码
[root@mysql ~]# mysql -uroot -p'3Izdh9OY6&Ef'

修改root密码

  • 格式:使用 ALTER USER 用户@"主机" IDENTIFIED BY "密码";
  • 新密码必须满足密码策略
  • 管理员root 使用新密码连接服务
shell 复制代码
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 库名; #删除库

创建库

  • 库命名规则
    • 仅可以使用数字、字母、下划线、不能纯数字
    • 区分字母大小写,具有唯一性
    • 不可使用指令关键字、特殊字符
sql 复制代码
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)
sql 复制代码
mysql> USE DB1;							#切换至DB1库
mysql> SHOW TABLES;						#查看DB1库里有哪些表
mysql> DROP DATABASE haha;				#删除库haha
sql 复制代码
mysql> SELECT USER();					#查看当前登录数据库的用户
SELECT  DATABASE();						#查看当前所在库

创建表

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

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

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

查看表结构

  • DESC 库名.表名;
shell 复制代码
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表里插入一行记录

sql 复制代码
mysql> INSERT INTO db1.stuinfo VALUES("sam","Beijing");

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

sql 复制代码
mysql> SELECT  *  FROM db1.stuinfo;

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

sql 复制代码
mysql> UPDATE   db1.stuinfo  SET homeaddr="Shanghai";

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

sql 复制代码
mysql> DELETE FROM db1.stuinfo;
mysql> SELECT  *  FROM db1.stuinfo;							#查看验证

数据类型

  • 定长:CHAR(字符个数)
    • 最大字符个数255
    • 不够指定字符个数时在右边用空格补全
    • 字符个数超出时,无法写入数据。
sql 复制代码
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)

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

数值类型

  • 整数型
类 型 名称 有符号范围 无符号范围
TINYINT 微小整数 -128~127 0 ~ 255
SMALLINT 小整数 -32768~32767 0 ~ 65535
MEDIUMINT 中整型 -223 ~ 223-1 0 ~ 224-1
INT 大整型 -231 ~ 231-1 0 ~ 232-1
BIGINT 极大整型 -263 ~ 263-1 0 ~ 264-1
UNSIGNED 使用无符号存储范围
  • 浮点数
类 型 名称 有符号范围 无符号范围
FLOAT 单精度 -3.402823466E+38 到 -1.175494351E-38 1.175494351E-38 到 3.402823466E+38
DOUBLE 双精度 -1.7976931348623157E+308到 -2.2250738585072014E-308 2.2250738585072014E-308 到 1.7976931348623157E+308
sql 复制代码
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()) 获取时间"时:分:秒"
shell 复制代码
[root@mysql ~] mysql -uroot -p'密码' 		   #连接数据库
mysql> SELECT CURTIME();					#查看"时:分:秒"
mysql> SELECT CURDATE();					#查看"年-月-日"
mysql> SELECT NOW();						#查看"年-月-日 时:分:秒"
mysql> SELECT YEAR(NOW());					#查看"年-月-日 时:分:秒"

案例

  • 新建库bbsdb
sql 复制代码
[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表

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

向bbsdb.t5表插入数据

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

查询bbsdb.t5表数据

sql 复制代码
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")

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

向db1.t5表插入数据

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

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

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

向db1.t6表插入数据

sql 复制代码
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
sql 复制代码
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
        -> );

插入数据,不使用默认值

sql 复制代码
mysql> INSERT INTO db1.t7 VALUES ('Alice', 22, 'nsd', 35000.50);

插入数据,使用默认值

sql 复制代码
mysql> INSERT INTO db1.t7(name) VALUES("Bob");

查询db1.t7表中的数据

sql 复制代码
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个宽度

sql 复制代码
mysql> ALTER TABLE db1.t6 ADD home VARCHAR(20) AFTER likes;

修改字段类型MODIFY

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

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

sql 复制代码
mysql> ALTER TABLE db1.t6 MODIFY home CHAR(30) ;

删除字段DROP

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

删除db1.t6表中的home字段

sql 复制代码
mysql> ALTER TABLE db1.t6 DROP home ;

修改字段名CHANGE

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

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

sql 复制代码
mysql> ALTER TABLE db1.t6 CHANGE  name user VARCHAR(30);

修改表名RENAME

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

修改db1.t6表名为db1.userinfo

sql 复制代码
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"。该字段可以为空
sql 复制代码
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

sql 复制代码
mysql> CREATE INDEX age_index ON db1.t9 (age);

删除db1.t9表中的age_index字段

sql 复制代码
mysql> DROP INDEX age_index ON db1.t9;

查看索引信息

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

查看db1.t9表索引

sql 复制代码
mysql> SHOW INDEX FROM db1.t9 \G

高级字段约束

主键

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

单列主键测试

mysql 复制代码
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;

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

sql 复制代码
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;

自增长测试

sql 复制代码
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 复制代码
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字段

sql 复制代码
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基本管理命令
  • 数据类型(字符类型、数值类型、浮点型)
  • 掌握修改表结构
  • 掌握索引的作用
  • 掌握主键与外键的作用及使用方法
相关推荐
dessler13 分钟前
Docker-如何启动docker
运维·docker·云原生·容器·eureka
zhy2956313 分钟前
【DOCKER】基于DOCKER的服务之DUFS
运维·docker·容器·dufs
小蜗牛慢慢爬行25 分钟前
有关异步场景的 10 大 Spring Boot 面试问题
java·开发语言·网络·spring boot·后端·spring·面试
秋名山小桃子28 分钟前
Kunlun 2280服务器(ARM)Raid卡磁盘盘符漂移问题解决
运维·服务器
与君共勉1213829 分钟前
Nginx 负载均衡的实现
运维·服务器·nginx·负载均衡
MARIN_shen31 分钟前
Marin说PCB之POC电路layout设计仿真案例---06
网络·单片机·嵌入式硬件·硬件工程·pcb工艺
MZWeiei39 分钟前
Zookeeper基本命令解析
大数据·linux·运维·服务器·zookeeper
Arenaschi1 小时前
在Tomcat中部署应用时,如何通过域名访问而不加端口号
运维·服务器
waicsdn_haha1 小时前
Java/JDK下载、安装及环境配置超详细教程【Windows10、macOS和Linux图文详解】
java·运维·服务器·开发语言·windows·后端·jdk
m0_748240021 小时前
Chromium 中chrome.webRequest扩展接口定义c++
网络·c++·chrome