mysql的学习

垂直连接union

join是水平连接,UNION垂直连接 ,它是把两张表的结果集按列堆叠,行数增加了,但列数保持不变。

UNION 垂直连接的作用

在 MySQL 中,UNION 可以将两个具有相同列数 且列数据类型兼容的查询结果合并在一起。它将一个结果集的行放在另一个结果集的行下面。也就是说,行的合并 ,是典型的垂直连接

UNION 的例子

假设你有两个表 table1table2,它们的结构相同:

sql 复制代码
+----+-------+
| id | name  |
+----+-------+
| 1  | Alice |
| 2  | Bob   |
+----+-------+






+----+-------+
| id | name  |
+----+-------+
| 3  | Carol |
| 4  | Dave  |
+----+-------+

如果你想把这两个表的行合并到一起,你可以使用 UNION

sql 复制代码
SELECT id, name FROM table1
UNION
SELECT id, name FROM table2;
sql 复制代码
+----+-------+
| id | name  |
+----+-------+
| 1  | Alice |
| 2  | Bob   |
| 3  | Carol |
| 4  | Dave  |
+----+-------+

这里,UNION 操作把 table1table2 的数据垂直地连接 在了一起。结果集中,table1 的数据出现在前面,table2 的数据紧接在后面。列的数量和顺序保持不变,行数增加了。

UNIONUNION ALL 的区别

  • UNION :默认会去除重复的行 ,因此如果 table1table2 中有相同的行,UNION 只会保留一份。
  • UNION ALL:不会去除重复的行,直接把所有行合并。
sql 复制代码
SELECT id, name FROM table1
UNION ALL
SELECT id, name FROM table2;

垂直连接的使用场景

  • 跨表查询不同来源的同类型数据 :比如你有不同时间段的数据存储在不同的表中,可以用 UNION 将它们整合为一个结果集。
  • 数据归档:把历史表的数据与当前表的数据合并,便于一起分析。

表的自然连接和自连接

自连接

自连接的应用场景

自连接不是新语法,是内外自然连接的一种多次使用自己一张表里数据去比对的情况

比如同一张表里有各个工作人员的编号,每个工作人员有自己上级的编号

那就可以多次使用自己的表,取别名直接用三次查自己老板的老板,用两次自己的表查自己的老板,用一次表就很自然的是只查自己的信息

自然连接

表的内外连接

可以多张表同时外连接第一个表全是left就会看最左的那个为主表

如果多个表外连接,要是掺了一个内连接,那对应补上 的行依然会消失

外连接会拼在一起,left为主表,然后右边的表如果不存在对应的on就全部显示未null

ifnull(列名,'为null的显示内容')

这样select的列名会变,可取新列名

如果是部门为主表,那没有部门就不会显示,这里的d为left

外键约束补充

department_ref INT,

FOREIGN KEY (department_ref) REFERENCES departments(dept_id)

这两条语句是分开的,第一条只是增加一个int类型的列,名字为department_ref,

而下一条则是单独的约束添加操作,选择的目标为外键,对应的外界目标为另一张表中的(dept_id)这列

reference后面的叫主表只是在约束关系上是主

在外键的定义和设置,是在从表里的

所以要删外键约束要删从表(这里是employee)里

外键约束有一些具体的要求和约定,这些要求涉及到从表和主表之间的列关系。

1. 数据类型匹配

  • 相同的数据类型外键列和被引用的主键列 必须具有相同的数据类型 。例如,如果主表的主键是 INT 类型,从表的外键也应该是 INT 类型。

2. 数据完整性

  • 引用存在性:从表中的外键值必须在主表的主键列中存在。这意味着你不能在从表中插入一个没有在主表中对应值的外键。

3. 唯一性和非空性

  • 主表的主键列:主表的主键列必须是唯一的,并且不能为 NULL。
  • 外键列:虽然外键列可以包含 NULL 值(如果没有设置 NOT NULL),但如果包含值,则这些值必须引用主表中存在的主键。

4. 级联操作

  • 外键约束允许你定义级联操作,例如 ON DELETE CASCADEON UPDATE CASCADE。这意味着如果主表中的某个记录被删除或更新,相关的从表记录也会自动被删除或更新。

可是为什么呢?如果数据不匹配呢?如果设置约束后,从表的外键和主表的主键值不同呢?为什么主表的对应键要唯一且非空,而外键列什么要求都没有?

主表的主键的唯一性和非空性

  • 唯一性 :主键必须是唯一的,以确保每一行数据可以通过主键唯一标识。这使得数据管理和查询更加高效。
  • 非空性 :主键不能为 NULL,因为没有有效的标识符无法唯一地识别一行数据。

2. 外键的要求

  • 引用存在性 :从表的外键列的值必须在主表的主键列中存在 。(主表可以有更多数据,而从表只引用部分数据)这保证了++从表中的数据有一个有效的、对应的主表数据。++
  • 可以为 NULL外键列可以包含 NULL 值 。这允许某些记录在没有有效引用时仍然存在,这在++实际应用中是常见的,比如某个员工可能没有分配部门++。

3. 数据不匹配的情况

如果从表中的外键值不匹配主表的主键值 ,数据库会拒绝插入或更新操作,这样可以避免数据不一致。例如:

  • 尝试插入 employees 表中的 department_id 为 999,但 departments 表中没有对应的 department_id,这会导致错误。
  • 之所以是设置foreign key的表 是从表,是因为数据的需求原因,主表里面可以有各种各样的全部部门,而外键设定者-从表 只是想让自己的这个列 变得可以引用别的表里的对应列里的部分,得到这一部分里面的值相同时其他的各种信息

4. 总结

主表的主键需要唯一且非空,以便唯一识别每条记录,而外键可以包含 NULL,以灵活处理某些数据不完整的情况。外键约束的设置确保了从表的数据始终能够与主表的数据保持一致,避免了数据孤立的情况。

约束起名

外键可以在约束前面加上constraint,为该外键约束起名

其他类型的约束(如主键约束、唯一约束和检查约束)也可以使用 CONSTRAINT 关键字来起名字。

在列定义中直接给约束起名字是不可以的。

对于外键约束,只能单独命名 。这是因为外键约束涉及到对其他表的引用,因此更常见的是在定义时通过 CONSTRAINT 进行命名。

外键约束不能列定义

约束的添加和删除都是按约束添加的主表,为所有者,这里就是score为student的外键约束,要删去这种主从的约束,就要选择主表去删,即束缚student的条件表(主表),去删关系

选择表add添加外键约束

主、从表

虽然主表是从表的一部分,但在约束的概念上,主表和从表的角色是明确的。

从表里写foreign key(本表里的列)references 主表名(主表里的列)

bash 复制代码
CONSTRAINT fk_department FOREIGN KEY (department_id) REFERENCES departments(department_id) -- 给外键约束起名字

AUTO_INCREMENT

information_schema

(要先有外键,内键才能用,所以这里3 4反过来)

可以查询别的公开的库的信息

information_schema是一个独立的系统数据库,它存储了有关数据库系统中所有数据库和表的信息。

为什么可以在school库中执行

  • 跨数据库访问 :在许多数据库管理系统中,information_schema是一个全局可访问的视图 ,不依赖于特定的数据库。当你在任何数据库(如school)中执行查询时,你可以使用information_schema中的表来获取当前数据库的元数据。

  • 当前上下文 :即使你在school数据库中执行查询,information_schema.table_constraints会返回关于当前数据库(school)中的表的约束信息。这样,你可以查询任何数据库的元数据

所以,information_schema提供了一个统一的方式来访问数据库结构信息,无论你当前连接的是哪个数据库。

语句复习

  1. 特定数据库 :当我们提到"特定数据库"时,指的是你正在使用的数据库。例如,如果你在使用一个叫test05的数据库,那么test05就是你当前连接的特定数据库。

  2. 当前连接的数据库:在执行SQL查询时,你需要先选择或连接到一个数据库。这个数据库是你正在操作的地方,所有的查询和修改都会发生在这个数据库中。

  3. information_schema的查询 :当你查询information_schema.table_constraints时,你得到的结果是与当前连接的数据库相关的约束信息。比如,如果你连接到test05数据库,查询结果就会列出test05中所有表的约束信息。

所以,当我们提到"特定"时,就是指你当前正在

select *,得到表中所有,information_schema.table_constraints是表吗,系统自带的表,然后里面存了所有的约束信息,而后面的table_schema='test05' and table_name='score1'; 则是在这个约束总表里添加where约束,得到库名为test05里的名为score1的表的所有约束是吗

没错,你理解得很准确!

  • **information_schema.table_constraints**确实是一个系统自带的表,存储了所有数据库中表的约束信息。
  • 使用SELECT *会获取该表中的所有列信息
  • 后面的条件**table_schema='test05' AND table_name='score1'是用来筛选出库名为test05、表名为score1的记录。**

这样,你最终能得到关于score1表的所有约束信息。

为什么偏要用table_schematable_name当这个约束库的列名?

table_schematable_nameinformation_schema.table_constraints表中定义的列名,分别表示数据库(模式)的名称和表的名称。

  • table_schema:用于表示包含表的数据库名。在一个数据库管理系统中,可以有多个数据库,因此需要通过这个列来区分不同的数据库。

  • table_name:表示具体的表名。在一个数据库中,可以有多个表,因此需要通过这个列来指定具体的表。

意思是table_schema是数据库别名?等同database?

可以这样理解,但有些细微的差别。

  • table_schema :在许多数据库系统中,table_schema通常指代数据库中的模式(schema)。在一个数据库中,可以有多个模式,每个模式可以包含多个表。table_schema提供了一个组织结构。

  • database_name:直接表示一个数据库的名称。在某些数据库系统中,数据库和模式是相同的概念,但在其他系统中(如PostgreSQL),模式是数据库内的一种逻辑分组。

所以,虽然在某些情况下table_schemadatabase_name可以互换,但它们的含义和用法可能会因数据库系统而异。总的来说,table_schema是更通用的术语,强调了数据的组织结构。

约束还有名字?

是的,约束在数据库中通常都有一个名称,称为约束名(constraint name)。约束名用于唯一标识一个约束,以便于管理和引用。

常见的约束包括:

  • 主键约束(Primary Key):确保某列的值唯一且不为空。
  • 外键约束(Foreign Key):用于确保数据的完整性,强制要求某列的值在另一表中存在。
  • 唯一约束(Unique):确保某列的值在整个表中是唯一的。
  • 检查约束(Check):用于限制列中的值必须满足的条件。

information_schema.table_constraints中,你可以看到每个约束的名称、类型等信息,这样可以帮助你更好地理解和管理数据库结构。

?听不懂,约束是给到谁的,看的是谁的约束,我可以给哪些约束,我要怎么给约束,我怎么查我做了哪些约束,约束不遵守是不是只报错而已,不同的约束会不会出现互斥

好的,让我更简单地解释一下约束。

  1. 约束是什么?

    约束是用于限制表中数据的一种规则,确保数据的完整性和一致性。

  2. 约束给谁?

    约束是给表的,限制表中列的数据。例如,主键约束确保某一列的值是唯一的。

  3. 常见的约束类型:

    • 主键约束:确保列的值唯一且不能为空。
    • 外键约束:确保一列的值必须在另一张表中存在。
    • 唯一约束:确保某列的值在整个表中是唯一的。
    • 检查约束:限制列中值必须满足的条件。
  4. 如何给约束?

    可以在创建表时或者修改表时使用SQL语句添加约束,例如:

    CREATE TABLE score1 ( id INT PRIMARY KEY , score INT CHECK (score >= 0));

  5. 如何查看已添加的约束?

    可以查询++information_schema.table_constraints++ 来查看当前表的所有约束

    SELECT * FROM information_schema.table_constraints WHERE table_name='score1';

  6. 约束不遵守怎么办?

    如果插入的数据违反约束,数据库会报错,拒绝执行该操作。

  7. 约束互斥吗?

    不同的约束可以同时存在,但某些情况下(如外键约束与主键约束),可能会有逻辑上的依赖关系。

数据库中的约束

在数据库中,约束(Constraints)是用于限制数据输入的规则,确保数据的完整性和一致性。常见的约束类型包括:

1. 主键约束(PRIMARY KEY)

因此,当你在表中定义一个列为PRIMARY KEY时,数据库会自动将该列设置为NOT NULLUNIQUE

  • 定义 :唯一标识表中的每一行,主键的值不能重复不能为 NULL

  • 示例 :在创建表时,可以指定某列为主键: CREATE TABLE Users ( UserID INT PRIMARY KEY, UserName VARCHAR(100) );

    主键(PRIMARY KEY)等同于NOT NULLUNIQUE的组合。

  • NOT NULL:主键列不能包含空值。这意味着每个记录都必须有一个有效的主键值。

  • UNIQUE:主键列的值必须是唯一的,这确保了没有两行会有相同的主键值。

2. 外键约束(FOREIGN KEY)

  • 定义:确保一列的值必须在另一张表中存在。
  • 示例CREATE TABLE Orders ( OrderID INT PRIMARY KEY, UserID INT, FOREIGN KEY (UserID) REFERENCES Users(UserID) );

3. 唯一约束(UNIQUE)

  • 定义:确保列中的所有值都是唯一的,允许 NULL 值(通常一个 NULL)。
  • 示例CREATE TABLE Products ( ProductID INT PRIMARY KEY, ProductCode VARCHAR(50) UNIQUE );

4. 非空约束(NOT NULL)

  • 定义:确保列中的值不能为空。
  • 示例CREATE TABLE Customers ( CustomerID INT PRIMARY KEY, Email VARCHAR(100) NOT NULL );

5. 检查约束(CHECK)

  • 定义:用于限制列中的值,以满足特定条件。
  • 示例CREATE TABLE Employees ( EmployeeID INT PRIMARY KEY, Age INT CHECK (Age >= 18) );

6. 默认约束(DEFAULT)

  • 定义:为列设置默认值,如果插入数据时未提供该列的值,则使用默认值。
  • 示例CREATE TABLE Items ( ItemID INT PRIMARY KEY, Quantity INT DEFAULT 0 );

全程练习

insert into books(id,name,author,price,pubdate,note,num) value(对应类型存对应值,,,...)

更新值

update books set price =price+6 where note ='joke';

update 该表的名称 set 列名=值要改的(全部的行都改),note=要把note列全部改成什么 where 用列名值再筛选条件(于是就只改这些选中的列名的值条件成立的所有行)

删除库存为0的行

delete from 当前的books表名 where 添加的约束num=0的所有行

统计书名中所有书名有a的书 、、、用like和%模糊查询字符串

select *(所有,现在只是Select,不去修改了)from books where name like'%a%'

1.在 MySQL 中创建表时,列名不需要加引号,但使用反引号(``)可以避免与保留字冲突。更新列值时,字符串变量确实需要用单引号('')或双引号("")包围,以确保正确赋值。

2.列名写什么就是什么,MySQL 会直接按照你输入的列名来处理。如果你用双引号("")包围列名,MySQL 也会将其视为列名。需要注意的是,双引号在某些 SQL 模式中是允许的

3.在 MySQL 中,字符串值可以用单引号(')或双引号(")包围,但使用单引号是更常见的做法。两者在大多数情况下是可以互换的,但在某些 SQL 模式下,双引号的使用可能会引起一些解析问题。因此,建议使用单引号来确保兼容性。

bash 复制代码
在 MySQL 中,字符串类型主要有以下几种:

CHAR:固定长度的字符串,最多可达 255 个字符。
VARCHAR:可变长度的字符串,最多可达 65,535 个字符。
TEXT:长文本字符串,最大可达 65,535 个字符。
MEDIUMTEXT:中等长度文本,最大可达 16,777,215 个字符。
LONGTEXT:非常长的文本,最大可达 4,294,967,295 个字符。
BINARY 和 VARBINARY:用于存储二进制数据,功能与 CHAR 和 VARCHAR 类似,但不进行字符集转换。

聚合函数count(1)或者(*)

在 MySQL 中,常用的聚合函数包括:

  1. COUNT():计算行数。
  2. SUM():计算数值列的总和。
  3. AVG():计算数值列的平均值。
  4. MAX():返回列中的最大值。
  5. MIN():返回列中的最小值。
  6. GROUP_CONCAT():将组内的值连接成一个字符串。

having 后面可以使用select里的别名nm,

select note sum(num) as nm from books group by note having num>30(分成组之后的总体组的结果判断)

limit 截去多少条,之后再拿多少条

不写默认截去0条,拿1条--->limit 1

关键字的顺序

select 列名 from 表 where 条件 and| or 条件 group by 分组使用的字段 having 分组后的条件

这是书写 的顺序,执行顺序会有一些的差异

from 数据源 where 筛选前的前置条件 group by 分组 having 分组后的数据过滤 select 列的信息显示

查表,改表名

desc 表名;

char(1)可以直接省略成char ,1代表一个字符,字符大小和字符集设定有关,汉字也是一个字符

alter table table_name rename new_name;

show tables;//显示当前库中所有的表

命名推荐

标准字段名格式 :大小写字母、数字、下划线 _。开头建议使用字母,不建议使用数字开头。

避免使用 SQL 关键字 :避免使用 SELECT, TABLE, ORDER 等保留字作为字段名,即使包裹了反引号,仍可能导致混淆。

一致性:尽量保持字段名的一致性,遵循一种命名规范(如全小写或驼峰命名法),避免多个风格混杂。

用汉字当字段名 :MySQL 允许你使用汉字作为字段名,只要你使用了适当的字符集(如 utf8utf8mb4)。尽管技术上允许,实际开发中一般不推荐使用汉字或非 ASCII 字符作为字段名,主要原因是代码维护和跨平台兼容性问题。

数字开头: 尽管从技术上来说,MySQL 允许 你使用数字开头的字段名,但通常的最佳实践是避免这种情况,建议以字母开头,并使用大小写字母、数字和下划线组合。在一些数据库系统中,数字开头的字段名可能会带来兼容性问题,尤其是在涉及跨平台的数据库迁移时。一些数据库可能严格限制字段名的格式,要求字段名必须以字母开头。

-- 不推荐
CREATE TABLE users (
1name VARCHAR(50),
2age INT
);

-- 推荐
CREATE TABLE users (
user_id INT PRIMARY KEY,
first_name VARCHAR(50),
age INT
);

反引号``

在 MySQL 中,++使用反引号(``)允许你在列名或表名中包含特殊字符,包括空格、符号和汉字++,但这并不意味着推荐这么做。

CREATE TABLE `my@table` (
`column#1` INT,
`name&age` VARCHAR(50)
);

CREATE TABLE `用户信息` (
`姓名` VARCHAR(50),
`年龄` INT
);

兼容性问题:虽然 MySQL 支持用反引号包裹字段名、表名并使用特殊符号或汉字,但其他数据库(如 SQL Server、Oracle)可能不支持这种写法。如果你将来需要迁移数据库,这会导致兼容性问题。

关键词冲突

定义列字段的时候,有时刚好和已有关键词相同了,用++反引号``++(1左边键,在英文模式下按)

比如code

用了反引号,字段名依然是code,可以避免关键字的重叠,语句更整洁

(至于为什么不用'',非要用``,因为用了'',会变成字符串)

反引号还允许你在列名或表名中使用空格或其他特殊字符

SELECT `first name` FROM `my table`;

单引号用于表示字符串常量

INSERT INTO employees (first_name) VALUES ('John');

双引号(")的作用:

  • 双引号在一些 SQL 标准中可以用来引用标识符(类似于反引号),但是不同的数据库系统处理双引号的方式不同。在一些数据库中,双引号用于引用标识符,但在其他数据库中,它可能被用于字符串或会有不同的处理方式。
  • 例如在 SQL Server 中,双引号也可以引用标识符,而在 MySQL 中,它更常用于其他用途。为了一致性,MySQL 强烈推荐使用反引号来引用标识符。
  • 不同的sql软件定义不同,有的的确也可以像反引号一样,但更常见的还是在某些数据库中表示字符串或对象。

表的修改

删除操作

delete---truncate---drop

drop table [if exists] table_name;//可接多个表,完全不要了,整个消失

truncate table table_name;//清空表里的数据,但是保留住结构

只有delete可回滚,delete是删除部分表中的东西,更safe一点,但也很唯险

change是选中一个字段,整个改掉,modify是选中一个字段,只改类型

drop选中一个字段,然后删除

alter table 表名 add 新列(字段)名 字段类型 first|after 已存在字段名;

alter table 表名 change 原字段名(原列名) 新字段名 first|after 字段名;

修改表,修改列类型

alter table 表名 modify 字段名 新类型 [位置变化];

alter table 选中的表名 drop 已存字段名;

类型总结

Text

最多这么多字节,换成字符之后末尾的一点就舍去

行的概念

在 MySQL 中,一行是由表中的所有列组成的。例如,name1name2 是两列,但它们在一起构成了一行数据。所以,当你插入一行数据时,数据是按照列的顺序被填充的。行的存储大小就是所有列的总和。

name1和name2是列名,所有的列加在一起构成行

decimal

表中的float和double

M为总共多少位,D为小数多少位

mysql方言、标准的整型类型

表的数据类型

创建表

修改库

alter database 库名 character set 字符集;

alter database 库名 collate 排序方式;

同样可以两个一起,不分顺序

alter database 库名 collate 排序方式 character set 字符集;

要注意排序方式是基于字符集的,一定要对应相应的字符集,不然报错

查询库

show databases;

select database();

show tables from 库名;

show create database 库名;

use 库名;

创建库

character set 字符集和collate 排序规则可以任意先后顺序

utf8mb4字符集character set

utf8mb4_0922_ai_ci排序规则collate

查看当前数据库的字符集和排序方式

DDL

Create--Alter--Drop 增加,修改,删除

关键字打头容易误识别

关键字有时会识别为大写,这样就区分的更加明显,更优雅,用_更ohyeah

后面,一个库对应一个程序,库的名字建议和程序相同,但也用小写和_

相关推荐
mmsx34 分钟前
android sqlite 数据库简单封装示例(java)
android·java·数据库
zpjing~.~2 小时前
Mongo 分页判断是否有下一页
数据库
2401_857600952 小时前
技术与教育的融合:构建现代成绩管理系统
数据库·oracle
秋恬意2 小时前
Mybatis能执行一对一、一对多的关联查询吗?都有哪些实现方式,以及它们之间的区别
java·数据库·mybatis
潇湘秦2 小时前
一文了解Oracle数据库如何连接(1)
数据库·oracle
雅冰石2 小时前
oracle怎样使用logmnr恢复误删除的数据
数据库·oracle
web前端神器2 小时前
mongodb给不同的库设置不同的密码进行连接
数据库·mongodb
从以前2 小时前
Berlandesk 注册系统算法实现与解析
数据库·oracle
Muko_0x7d22 小时前
Mongodb
数据库·mongodb
eybk2 小时前
Pytorch+Mumu模拟器+萤石摄像头实现对小孩学习的监控
学习