【MySQL】表的增删改查 | CRUD | 新增 | 查询 | 修改 | 删除 | 数据库约束

文章目录

  • 表的增删改查
    • 一、CRUD
      • 1.新增(Create)
            • 1.插入多行
            • 2.指定列多行插入
            • 3.插入datetime类型
            • 4.插入当前时间
            • 5.插入查询的结果
      • 2.查询(Retrieve)
            • 1.全列查询 *
            • 2.指定列查询
            • 3.查询字段为表达式
            • 4.指定别名 as
            • 5.去重 distinct
            • 6.排序 order by
            • 7.条件查询 where
            • 8.分页查询:limit
      • 3.修改(Update)
      • 4.删除(Delete)
            • 数据库的备份方式:
    • 二、数据库约束
          • not null
          • unique:唯一的
          • default:
          • primary key 主键
            • 如何保证主键唯一?
          • foreign 外键
      • 表的设计


表的增删改查

一、CRUD

1.新增(Create)

insert into 表名 values(值,值);
insert into student values(1,'zhangsan');
  • 此处的值要和列(个数和类型)相匹配
  • 如果只插入了一个name,id这一列就是默认值null
1.插入多行

个数和类型要和表结构匹配。

insert into 表名 values(值,值),(值,值),(值,值);
insert into techer values(1,'小明'),(3,'李四'),(4,'王五');
2.指定列多行插入
insert into 表名 (列名,列名...)values(值,值),(值,值),(值,值);
-- 插入两条记录,value_list 数量必须和指定列数量及顺序一致
INSERT INTO student (id, sn, name) VALUES (102, 20001, '曹孟德'),(103, 20002, '孙仲谋');
3.插入datetime类型

使用字符串来表示时间的日期

create table student (id int ,name varchar(20),birthday datetime);
insert into student values(1,'张三','2000-01-11 12:00:00');
4.插入当前时间

now()方法

insert into student values(2,'李四',now());
mysql> select * from student;
+------+------+---------------------+
| id   | name | birthday            |
+------+------+---------------------+
|    1 | 张三     | 2000-01-11 12:00:00 |
|    2 | 李四     | 2024-05-13 14:03:02 |
+------+------+---------------------+
5.插入查询的结果
  • 查询的结果集合,列数和类型要和插入的表匹配。
mysql> select * from student;
+------+------+
| id   | name |
+------+------+
|    1 | 张三 |
|    2 | 李四 |
|    3 | 王五 |
+------+------+
3 rows in set (0.00 sec)mysql> select * from student2;
Empty set (0.00 sec)mysql> insert into student2 select *from student;
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0mysql> select * from student2;
+------+------+
| id   | name |
+------+------+
|    1 | 张三 |
|    2 | 李四 |
|    3 | 王五 |
+------+------+

2.查询(Retrieve)

创建表并插入数据:

-- 创建考试成绩表
DROP TABLE IF EXISTS exam_result;
CREATE TABLE exam_result (id INT,name VARCHAR(20),chinese DECIMAL(3,1),math DECIMAL(3,1),english DECIMAL(3,1)
);
-- 插入测试数据
INSERT INTO exam_result (id,name, chinese, math, english) VALUES(1,'唐三藏', 67, 98, 56),(2,'孙悟空', 87.5, 78, 77),(3,'猪悟能', 88, 98.5, 90),(4,'曹孟德', 82, 84, 67),(5,'刘玄德', 55.5, 85, 45),(6,'孙权', 70, 73, 78.5),(7,'宋公明', 75, 65, 30);
1.全列查询 *

查询表中的所有行和所有列。

  • 在生成环境下要谨慎使用。
select * from 表名;
mysql> select * from exam_result;
+------+--------+---------+------+---------+
| id   | name   | chinese | math | english |
+------+--------+---------+------+---------+
|    1 | 唐三藏 |    67.0 | 98.0 |    56.0 |
|    2 | 孙悟空 |    87.5 | 78.0 |    77.0 |
|    3 | 猪悟能 |    88.0 | 98.5 |    90.0 |
|    4 | 曹孟德 |    82.0 | 84.0 |    67.0 |
|    5 | 刘玄德 |    55.5 | 85.0 |    45.0 |
|    6 | 孙权   |    70.0 | 73.0 |    78.5 |
|    7 | 宋公明 |    75.0 | 65.0 |    30.0 |
+------+--------+---------+------+---------+

​ 客户端发送请求给服务器,查询出来之后,服务器把查询到的结果,在网络中通过响应返回给客户端,并在客户端上打印出来。

如果表中的数据特别多时,可能会产生:

​ 1.读取硬盘时,把硬盘的IO跑满了,此时程序的其他部分想访问硬盘,就会非常慢。

​ 2.操作网络,可能会把网卡的带宽跑满,此时其他客户端想通过网络访问服务器,也会非常慢。

这样的拥堵,就有可能导致客户端无法顺利访问

2.指定列查询
  • 按需求进行查询。
select 列名,列名...from 表名;
mysql> select name,math from exam_result;
+--------+------+
| name   | math |
+--------+------+
| 唐三藏 | 98.0 |
| 孙悟空 | 78.0 |
| 猪悟能 | 98.5 |
| 曹孟德 | 84.0 |
| 刘玄德 | 85.0 |
| 孙权   | 73.0 |
| 宋公明 | 65.0 |
+--------+------+
3.查询字段为表达式
  • 一边查询,一边进行计算(列和列之间的计算)

在查询的时候,写作由列名构成的表达式。把这一列中的所有行都代入到表达式中,参与运算。

  • 并不会修改原始数据,展示的是临时表。只针对从数据库服务器查询出来的数据进行运算,不影响原有数据。

查询所有人语文分数-10的值

 select name ,chinese-10 from exam_result;
+--------+------------+
| name   | chinese-10 |
+--------+------------+
| 唐三藏 |       57.0 |
| 孙悟空 |       77.5 |
| 猪悟能 |       78.0 |
| 曹孟德 |       72.0 |
| 刘玄德 |       45.5 |
| 孙权   |       60.0 |
| 宋公明 |       65.0 |
+--------+------------+

查询每个人的总成绩:

mysql>  select name, chinese + english + math from exam_result;
+--------+--------------------------+
| name   | chinese + english + math |
+--------+--------------------------+
| 唐三藏 |                    221.0 |
| 孙悟空 |                    242.5 |
| 猪悟能 |                    276.5 |
| 曹孟德 |                    233.0 |
| 刘玄德 |                    185.5 |
| 孙权   |                    221.5 |
| 宋公明 |                    170.0 |
+--------+--------------------------+
  • SQL在查询的时候,可以进行一些简单的统计操作。
4.指定别名 as
  • 查询的时候,给列/表达式/表 指定别名
select 表达式 as 别名 from 表名;select name,chinese+math+english as sum from exam_result;
+--------+-------+
| name   | sum   |
+--------+-------+
| 唐三藏 | 221.0 |
| 孙悟空 | 242.5 |
| 猪悟能 | 276.5 |
| 曹孟德 | 233.0 |
| 刘玄德 | 185.5 |
| 孙权   | 221.5 |
| 宋公明 | 170.0 |
+--------+-------+
5.去重 distinct
  • distinct修饰某个列/多个列
  • 值相同的行,只会保留一个
distinct
select distinct math from exam_result;
select distinct name,math from exam_result;
6.排序 order by
  • 把行进行排序。
  • 仍然是临时数据,把查询到的结果进行排序,不改变原始结构。

要明确排序的规则:1.针对哪个列作为比较规则 2. 是升序还是降序

select 列名 from 表名 order by 列名 asc
-- 升序排序(默认)select 列名 from 表名 order by 列名 desc;
-- 降序排序select name,math from exam_result order by math;
+--------+------+
| name   | math |
+--------+------+
| 宋公明 | 65.0 |
| 孙权   | 73.0 |
| 孙悟空 | 78.0 |
| 曹孟德 | 84.0 |
| 刘玄德 | 85.0 |
| 唐三藏 | 98.0 |
| 唐三藏 | 98.0 |
| 猪悟能 | 98.5 |
+--------+------+
mysql>  select name,math from exam_result order by math desc;
-- 降序
+--------+------+
| name   | math |
+--------+------+
| 猪悟能 | 98.5 |
| 唐三藏 | 98.0 |
| 唐三藏 | 98.0 |
| 刘玄德 | 85.0 |
| 曹孟德 | 84.0 |
| 孙悟空 | 78.0 |
| 孙权   | 73.0 |
| 宋公明 | 65.0 |
+--------+------+
mysql> select name,math from exam_result;
+--------+------+
| name   | math |
+--------+------+
| 唐三藏 | 98.0 |
| 孙悟空 | 78.0 |
| 猪悟能 | 98.5 |
| 曹孟德 | 84.0 |
| 刘玄德 | 85.0 |
| 孙权   | 73.0 |
| 宋公明 | 65.0 |
| 唐三藏 | 98.0 |
+--------+------+

如果不加上order by,则不应该依赖上述顺序,是“无序的”

mysql>  select name,math,chinese from exam_result order by chinese desc;
+--------+------+---------+
| name   | math | chinese |
+--------+------+---------+
| 猪悟能 | 98.5 |    88.0 |
| 孙悟空 | 78.0 |    87.5 |
| 曹孟德 | 84.0 |    82.0 |
| 宋公明 | 65.0 |    75.0 |
| 孙权   | 73.0 |    70.0 |
| 唐三藏 | 98.0 |    67.0 |
| 刘玄德 | 85.0 |    55.5 |
| 唐三藏 | 98.0 |    NULL |
+--------+------+---------+
8 rows in set (0.00 sec)mysql>  select name,math from exam_result order by chinese desc;
+--------+------+
| name   | math |
+--------+------+
| 猪悟能 | 98.5 |
| 孙悟空 | 78.0 |
| 曹孟德 | 84.0 |
| 宋公明 | 65.0 |
| 孙权   | 73.0 |
| 唐三藏 | 98.0 |
| 刘玄德 | 85.0 |
| 唐三藏 | 98.0 |
+--------+------+

即使没有选择语文成绩,仍然可以按照语文成绩进行排序

对表达式运算的结果进行排序:

mysql>  select name,chinese+math+english as total from exam_result order by total;
-- 对表达式运算的结果进行排序
+--------+-------+
| name   | total |
+--------+-------+
| 唐三藏 |  NULL |
| 宋公明 | 170.0 |
| 刘玄德 | 185.5 |
| 唐三藏 | 221.0 |
| 孙权   | 221.5 |
| 曹孟德 | 233.0 |
| 孙悟空 | 242.5 |
| 猪悟能 | 276.5 |
+--------+-------+

指定多个列来排序。order by后面写多个列,使用,分隔开。

mysql> select * from exam_result order by math,chinese;
-- 先按照数学成绩来排序,如果数学成绩相同,则按照语文成绩排序
+------+--------+---------+------+---------+
| id   | name   | chinese | math | english |
+------+--------+---------+------+---------+
|    7 | 宋公明 |    75.0 | 65.0 |    30.0 |
|    6 | 孙权   |    70.0 | 73.0 |    78.5 |
|    2 | 孙悟空 |    87.5 | 78.0 |    77.0 |
|    4 | 曹孟德 |    82.0 | 84.0 |    67.0 |
|    5 | 刘玄德 |    55.5 | 85.0 |    45.0 |
|   10 | 唐三藏 |    NULL | 98.0 |    NULL |
|    1 | 唐三藏 |    67.0 | 98.0 |    56.0 |
|    3 | 猪悟能 |    88.0 | 98.5 |    90.0 |
+------+--------+---------+------+---------+
7.条件查询 where
  • 会指定具体的条件,按照条件对数据进行筛选。
  • where:遍历这个表的每一行记录,把每一行的数据分别代入条件中。如果条件成立,则会把数据放进结果集合中。
select 列名 from 表名 where 条件;

比较运算符:

在这里插入图片描述

  • sql中没有==,而是使用=来比较相等(null不安全 null=null的结果是null.null参与的运算结果也是null)
  • <=> 比较相等 (null安全 null<=>null的结果是true)
  • != 、 <> 不等
  • between a1 and a2 : 范围[a1,a2] 如果 a1<= value <=a2 ,返回true
  • in(option…) :当前值如果是option中任意一种情况,返回true
  • like : 模糊匹配 %表示任意多个任意字符;_表示任意一个字符

逻辑运算符:

246.png&pos_id=img-UB64GKXJ-1715761707682)

  • and 优先级 高于or 。在同时使用时,需要小括号来区别。
-- 基本查询
-- 查询英语不及格的同学及英语成绩 ( < 60 )
mysql> select name,english from exam_result where english<60;
+--------+---------+
| name   | english |
+--------+---------+
| 唐三藏 |    56.0 |
| 刘玄德 |    45.0 |
| 宋公明 |    30.0 |
+--------+---------+-- 查询语文成绩好于英语成绩的同学select name,chinese,english from exam_result where chinese>english;
+--------+---------+---------+
| name   | chinese | english |
+--------+---------+---------+
| 唐三藏 |    67.0 |    56.0 |
| 孙悟空 |    87.5 |    77.0 |
| 曹孟德 |    82.0 |    67.0 |
| 刘玄德 |    55.5 |    45.0 |
| 宋公明 |    75.0 |    30.0 |
+--------+---------+---------+-- 查询总分在 200 分以下的同学
select name,math+chinese+english as total from exam_result where chinese+math+english<200;
-- where条件可以使用表达式,但是不能使用别名
+--------+-------+
| name   | total |
+--------+-------+
| 刘玄德 | 185.5 |
| 宋公明 | 170.0 |
+--------+-------+

where条件可以使用表达式,但是不能使用别名

select条件查询执行的顺序:

​ 1.遍历表中的每一个记录

​ 2.把当前记录的值,代入条件,根据条件进行筛选

​ 3.如果这个记录成立,就要保留,进行列上的表达式计算

​ 4.如果有order by,会在所有行都被获取到之后(表达式也算完了)再针对所有的结果进行排序。

第三步定于的别名,where是第二部执行的

and or

-- 查询语文成绩大于80分,且英语成绩大于80分的同学
mysql> select name,english,chinese from exam_result where chinese>80 and english >80;
+--------+---------+---------+
| name   | english | chinese |
+--------+---------+---------+
| 猪悟能 |    90.0 |    88.0 |
+--------+---------+---------+-- 查询语文成绩大于80分,或英语成绩大于80分的同学
mysql> select name,english,chinese from exam_result where chinese>80 or english >80;
+--------+---------+---------+
| name   | english | chinese |
+--------+---------+---------+
| 孙悟空 |    77.0 |    87.5 |
| 猪悟能 |    90.0 |    88.0 |
| 曹孟德 |    67.0 |    82.0 |
+--------+---------+---------+-- 观察AND 和 OR 的优先级:
mysql> SELECT * FROM exam_result WHERE chinese > 80 or math>70 and english > 70;
+------+--------+---------+------+---------+
| id   | name   | chinese | math | english |
+------+--------+---------+------+---------+
|    2 | 孙悟空 |    87.5 | 78.0 |    77.0 |
|    3 | 猪悟能 |    88.0 | 98.5 |    90.0 |
|    4 | 曹孟德 |    82.0 | 84.0 |    67.0 |
|    6 | 孙权   |    70.0 | 73.0 |    78.5 |
+------+--------+---------+------+---------+
4 rows in set (0.00 sec)mysql> SELECT * FROM exam_result WHERE (chinese > 80 or math>70) and english > 70;
+------+--------+---------+------+---------+
| id   | name   | chinese | math | english |
+------+--------+---------+------+---------+
|    2 | 孙悟空 |    87.5 | 78.0 |    77.0 |
|    3 | 猪悟能 |    88.0 | 98.5 |    90.0 |
|    6 | 孙权   |    70.0 | 73.0 |    78.5 |
+------+--------+---------+------+---------+

between and

-- 查询语文成绩在 [80, 90] 分的同学及语文成绩
mysql> select name,chinese from exam_result where chinese between 80 and 90;
+--------+---------+
| name   | chinese |
+--------+---------+
| 孙悟空 |    87.5 |
| 猪悟能 |    88.0 |
| 曹孟德 |    82.0 |
+--------+---------+
-- 使用 AND 也可以实现
mysql> select name,chinese from exam_result where chinese >=80 and chinese <=90;
+--------+---------+
| name   | chinese |
+--------+---------+
| 孙悟空 |    87.5 |
| 猪悟能 |    88.0 |
| 曹孟德 |    82.0 |
+--------+---------+

in

-- 查询数学成绩是 58 或者 59 或者 98 或者 99 分的同学及数学成绩
mysql> select name,math from exam_result where math in(58,59,98,99);
+--------+------+
| name   | math |
+--------+------+
| 唐三藏 | 98.0 |
| 唐三藏 | 98.0 |
+--------+------+
-- 使用 OR 也可以实现
mysql> SELECT name, math FROM exam_result WHERE math = 58 OR math = 59 OR math-> = 98 OR math = 99;
+--------+------+
| name   | math |
+--------+------+
| 唐三藏 | 98.0 |
| 唐三藏 | 98.0 |
+--------+------+

模糊查询:like

-- % 匹配任意多个(包括 0 个)字符
mysql>  select name from exam_result where name like '孙%';
+--------+
| name   |
+--------+
| 孙悟空 |
| 孙权   |
+--------+-- _ 匹配严格的一个任意字符
mysql>  select name from exam_result where name like '孙_';
+------+
| name |
+------+
| 孙权 |
+------+
mysql>  select name from exam_result where name like '孙__';
+--------+
| name   |
+--------+
| 孙悟空 |
+--------+

NULL 的查询:IS [NOT] NULL


select * from exam_result where chinese = null;
-- =的话,查询到的还是空
Empty set (0.00 sec)mysql> select * from exam_result where chinese <=> null;
+------+--------+---------+------+---------+
| id   | name   | chinese | math | english |
+------+--------+---------+------+---------+
|   10 | 唐三藏 |    NULL | 98.0 |    NULL |
+------+--------+---------+------+---------+mysql> select * from exam_result where chinese <=> english;
+------+--------+---------+------+---------+
| id   | name   | chinese | math | english |
+------+--------+---------+------+---------+
|   10 | 唐三藏 |    NULL | 98.0 |    NULL |
+------+--------+---------+------+---------+
1 row in set (0.00 sec)mysql> select * from exam_result where chinese is null;
-- is null只能顾及到一个列
+------+--------+---------+------+---------+
| id   | name   | chinese | math | english |
+------+--------+---------+------+---------+
|   10 | 唐三藏 |    NULL | 98.0 |    NULL |
+------+--------+---------+------+---------+
1 row in set (0.00 sec)
8.分页查询:limit
  • 使用select * 这种查询方式,比较危险,要保障一次查询的数量有限,避免堵塞。

  • limit可以限制这次查询最多能查出多少个结果

mysql>  select * from exam_result limit 3;
mysql>  select * from exam_result limit 3 offset 0;
-- 显示前三条记录
-- limit 表示这次查询查几条记录
-- offset:偏移量,也就是一个下标,从0开始
+------+--------+---------+------+---------+
| id   | name   | chinese | math | english |
+------+--------+---------+------+---------+
|    1 | 唐三藏 |    67.0 | 98.0 |    56.0 |
|    2 | 孙悟空 |    87.5 | 78.0 |    77.0 |
|    3 | 猪悟能 |    88.0 | 98.5 |    90.0 |
+------+--------+---------+------+---------+mysql>  select * from exam_result limit 3 offset 3;
+------+--------+---------+------+---------+
| id   | name   | chinese | math | english |
+------+--------+---------+------+---------+
|    4 | 曹孟德 |    82.0 | 84.0 |    67.0 |
|    5 | 刘玄德 |    55.5 | 85.0 |    45.0 |
|    6 | 孙权   |    70.0 | 73.0 |    78.5 |
+------+--------+---------+------+---------+mysql>  select * from exam_result limit 3 offset 6;
+------+--------+---------+------+---------+
| id   | name   | chinese | math | english |
+------+--------+---------+------+---------+
|    7 | 宋公明 |    75.0 | 65.0 |    30.0 |
|   10 | 唐三藏 |    NULL | 98.0 |    NULL |
+------+--------+---------+------+---------+

3.修改(Update)

update 表名 set 列名 =where 条件;-- 将孙悟空同学的数学成绩变更为 80 分
mysql> update exam_result set math = 80 where name = '孙悟空';-- 将曹孟德同学的数学成绩变更为 60 分,语文成绩变更为 70 分
mysql> update exam_result set math = 60,chinese = 70 where name = '曹孟德';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0-- 将总成绩倒数前三的 3 位同学的数学成绩减上 30 分
update exam_result set math = math - 30 order by math+chinese+english limit 3;

4.删除(Delete)

delete from 表名 where 条件/ order by / limit;
  • 把符合条件的行,从表中删除掉。
-- 删除孙悟空同学的考试成绩delete from exam_result where name = '孙悟空';-- 删除整张表数据
delete from exam_result ;-- (清空整张表->空表)
drop table exam_result; -- (删除表信息,表没了)
-- 准备测试表
DROP TABLE IF EXISTS for_delete;
CREATE TABLE for_delete (id INT,name VARCHAR(20)
);
-- 插入测试数据
INSERT INTO for_delete (name) VALUES ('A'), ('B'), ('C');
-- 删除整表数据
DELETE FROM for_delete;
数据库的备份方式:

1.数据库的数据最终是以文件(二进制)的形式,存储在硬盘上。将文件之间拷贝到新的机器上(全量备份)

2.mysqldump工具,将mysql中的数据导出成一系列insert语句,再把这些insert 语句放在新的mysql上执行。(全量&增量)

3.mysql的binlog功能,把mysql的各种操作,都通过日志记录下来,借住binlog,让另一个数据库按照binlog的内容执行(增量备份/实时备份)

二、数据库约束

​ 有的时候,数据库中的数据,是有一定要求的。有些数据认为是合法数据,有些是非法的数据。数据库会自动的对数据的合法性进行校验检查。目的就是为了保证数据库中避免被插入/修改一些非法的数据。

在这里插入图片描述

  • not null :表示某列不能填空值。
  • unique : 表示某列的某行必须有唯一的值,不能重复。
  • default : 设置默认值。
  • primary key 主键 : 唯一标识(not null + unique)
  • foreign key 外键: 保证一个表中的数据匹配另一个表中的值的参照完整性。
not null
mysql> create table student(id int not null,name varchar(20));
Query OK, 0 rows affected (0.01 sec)mysql> insert into student values(null,null);
ERROR 1048 (23000): Column 'id' cannot be nullmysql> update student set id = null where name = '张三';
ERROR 1048 (23000): Column 'id' cannot be null
unique:唯一的
  • unique约束,会让后续插入数据/修改数据的时候,都先触发一次查询操作。通过查询来确定当前记录是否已经存在
  • 引入约束后,执行效率就会受到影响,可能会降低很多。
mysql> create table student(id int unique,name varchar(20));
Query OK, 0 rows affected (0.01 sec)mysql> insert into student values(1,'张三');
Query OK, 1 row affected (0.00 sec)mysql> insert into student values(1,'张三');
ERROR 1062 (23000): Duplicate entry '1' for key 'id'-- 重复  -- 条目
default:
  • 描述某一列的默认值. 默认的默认值是null,可以通过default约束来修改默认值。
mysql>  desc student;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | YES  | UNI | NULL    |       |
| name  | varchar(20) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+mysql> create table student(id int ,name varchar(20) default '未命名');
Query OK, 0 rows affected (0.01 sec)mysql> desc student;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | YES  |     | NULL    |       |
| name  | varchar(20) | YES  |     | 未命名  |       |
+-------+-------------+------+-----+---------+-------+

alter table 可以修改表的结构,进而修改约束

primary key 主键
  • 一行记录的身份标识

  • 一张表只能有一个主键。

  • 主键不一定只有一个列,可以用多个列共同构成一个主键(联合主键)

  • 带有主键的表,每次插入/修改数据,也会先进行查询的操作。

    mysql会把带有unique和primary key的列自动生成索引,从而加快查询的速度。

mysql> create table student(id int primary key,name varchar(20));
Query OK, 0 rows affected (0.01 sec)mysql> desc student;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | NO   | PRI | NULL    |       |
| name  | varchar(20) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
如何保证主键唯一?

​ mysql提供了一种“自增主键”的机制。主键经常会使用int/bigint来进行设置。程序员在插入数据的时候,不必手动指定主键的值,由数据库服务器自动分配一个主键。从1开始,依次递增的分配主键的值。

mysql> create table student(id int primary key auto_increment,name varchar(20));
Query OK, 0 rows affected (0.00 sec)mysql> desc student;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| name  | varchar(20) | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+mysql>  insert into student values(null,'张三');
-- 不设置id,让自增主键自行分配
Query OK, 1 row affected (0.01 sec)mysql>  insert into student values(null,'张三');
Query OK, 1 row affected (0.01 sec)mysql> select * from student;
+----+------+
| id | name |
+----+------+
|  1 | 张三 |
|  2 | 张三 |
+----+------+
mysql>  insert into student values(10,'李四');
Query OK, 1 row affected (0.01 sec)
-- 从最大值开始,后续自动分配
-- 相当于使用了一个变量,保存了表的最大id值,后续根据最大id来进行自增分配
mysql>  insert into student values(null,'王五');
Query OK, 1 row affected (0.01 sec)mysql> select * from student;
+----+------+
| id | name |
+----+------+
|  1 | 张三 |
|  2 | 张三 |
|  3 | 李四 |
| 10 | 李四 |
| 11 | 王五 |
+----+------+

​ 这里的自动分配具有局限性,如果是单个的mysql服务器,是没有问题的。但是如果是一个分布式系统,有多个mysql服务器构成的集群,就不能依靠自增主键了。

要保证在分布式的musql服务器中,其中一个主机存储的id,具有唯一性。往往要进行一定的算法处理。可以运用时间戳+机房编号/主机编号+随机因子的字符串拼贴,来得到唯一的id.

foreign 外键
  • 描述了两个表之间的关联关系

    class(classid ,name)2101  计科2102  计科2103  计科
    student(id ,name,classid)01  张三   210102  李四   210205  王五   2107(不在class表中)
    

    class表中的数据,约束了student表中的数据。

    create table student(id int primary key,name varchar(20),classid int,foreign key(classid) references class(classid));
    

    把class表称为父表(约束别人),把student表称为子表(被别人约束)

mysql> create table class(classid int primary key,name varchar(20));
Query OK, 0 rows affected (0.01 sec)mysql> insert into class values(2101,'计科1班'),(2102,'计科2班'),(2103,'计科3班');
create table student(id int primary key,name varchar(20),classid int,foreign key(classid) references class(classid));mysql> insert into student values (1,'张三',2101);
Query OK, 1 row affected (0.01 sec)mysql> insert into student values (2,'李四',2109);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`day5_14`.`student`, CONSTRAINT `student_ibfk_1` FOREIGN KEY (`classid`) REFERENCES `class` (`classid`))
  • references 引用,表示这一列的数据出自另一个表的那一列

  • 如果针对父表进行修改/删除 操作,如果当前要操作的值已经被子表引用了,就会操作失败。

  • 外键要始终保持,子表的数据在对应的父表的列中始终存在。

​ 在操作子表时,要保证在父表的范围内。操作父表时,要保证没有被子表引用。同理,如果父表已经被子表引用,就无法进行父表的删除。只能先删子表,再删父表。

  • 指定外键约束的时候,要求父表中被该关联的这一列,必须是主键或者是unique。

表的设计

根据实际的场景需求,明确当前要创建几个表,每个表的内容和表之间的联系

1.梳理清楚 需求中的“实体”(对象)

每个实体都需要安排一个表,表的列对应到实体的各个属性。

2.确定好实体之间的“关系”

1对1、1对多、多对多

点击移步博客主页,欢迎光临~

偷cyk的图

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

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

相关文章

人物介绍模板 PSD 源文件免费获取

免费获取 下载链接在最后&#xff01; 下载链接在最后&#xff01; 下载链接在最后&#xff01; 下载链接在最后&#xff01; 下载链接在最后&#xff01; 链接&#xff1a;https://pan.baidu.com/s/1sq3e6djMdZt76Sh_uqVxWg 提取码&#xff1a;naun

WPF之DataGird应用

1&#xff0c;DataGrid相关属性 GridLinesVisibility&#xff1a;DataGrid网格线是否显示或者显示的方式。HorizontalGridLinesBrush&#xff1a;水平网格线画刷。VerticalGridLinesBrush&#xff1a;垂直网格线画刷。HorizontalScrollBarVisibility&#xff1a;水平滚动条可见…

SOLIDWORKS 2024云服务新功能

一、简单的分享一下&#xff0c;在线观看&#xff0c;轻松标记 在达索系统SOLIDWORKS 2024云服务中&#xff0c;您只需在达索系统SOLIDWORKS中点击按钮&#xff0c;就可以将当前的设计分享给其他人&#xff0c;无论是客户、供应商还是团队内部成员。共享的用户只要打开浏览器里…

C++:编程世界的永恒之石

在编程的广袤领域中&#xff0c;C犹如一块永恒的基石&#xff0c;历经岁月的洗礼&#xff0c;依旧坚固而璀璨。它的深厚底蕴、强大功能和广泛的应用领域&#xff0c;使其成为无数程序员心中的信仰与追求。 一、C&#xff1a;历史与传承的交汇点 C的历史可追溯到上世纪80年代&…

详解JS的URL()和URLSearchParams() API接口

两个 API 接口定义 URL() 构造函数返回一个新创建的 URL 对象&#xff0c;表示由一组参数定义的 URL。 URLSearchParams 接口定义了一些实用的方法来处理 URL 的查询字符串。 快速了解两个 API 在哪里用 以前我们要对地址栏中的 URL 地址进行分析处理&#xff0c;需要自己进…

Redis如何避免数据丢失?——AOF

目录 AOF日志 1. 持久化——命令写入到AOF文件 写到用户缓冲区 AOF的触发入口函数——propagate 具体的实现逻辑——feedAppendOnlyFile 从用户缓冲区写入到AOF文件(磁盘&#xff09; 函数write、fsync、fdatasync Redis的线程池 AOF文件的同步策略 触发的入口函数——…

NSSCTF Web方向的例题和相关知识点(二)

[SWPUCTF 2021 新生赛]Do_you_know_http 解题&#xff1a; 点击打开环境&#xff0c;是 提示说请使用wLLm浏览器访问 我们可以更改浏览器信息&#xff0c;在burp重放器中发包后发现是302重定向&#xff0c;但是提示说success成功&#xff0c;说明 我们修改是成功的&#xff…

20232803 2023-2024-2 《网络攻防实践》实践九报告

目录 1.实践内容2.实践过程2.1 手工修改可执行文件&#xff0c;改变程序执行流程&#xff0c;直接跳转到getShell函数2.2 利用foo函数的Bof漏洞&#xff0c;构造一个攻击输入字符串&#xff0c;覆盖返回地址&#xff0c;触发getShell函数2.3 注入一个自己制作的shellcode并运行…

GPU学习记一下线程分组相关

在compute的时候&#xff0c;是要dispatch一个数量的代表分了多少块任务集&#xff0c;dispatch的块内部也是有一个数量的&#xff0c;那么这些值怎么取的呢 内部&#xff0c;N卡32 外面dispatch的数量就是all/32 然后细说这个值 这有一个叫core的东西&#xff0c;就是相当于th…

【数据可视化-05】:Plotly数据可视化宝典

一、引言 数据可视化是机器学习流程中不可或缺的一部分。通过图形和图表展示数据&#xff0c;我们可以更直观地理解数据的分布、趋势和关联&#xff0c;从而更有效地进行数据分析、特征工程和模型评估。Plotly是一个功能强大且灵活的数据可视化库&#xff0c;它提供了丰富的图表…

Linux系统 -目录结构与配网

目录的特点 Windows中有C盘、D盘等&#xff0c;每个都是一个根系统是个多根系统 Linux中只有一个根是个单根系统 Linux-目录存储的内容 1、/root&#xff1a;管理员的家目录 2、/home&#xff1a;存储普通用户家目录的目录/3、/tmp&#xff1a;临时目录&#xff0c;这个目录存储…

合并K个升序链表

题目 解法一 优先级队列 思想 将每个链表中的一个节点存放到优先级队列中&#xff0c;本题采用小根堆&#xff0c;将小根堆中的根节点取出&#xff0c;插入到最终的链表中&#xff0c;并且将该节点在原链表中的下一个节点插入小根堆中&#xff08;需要向下调整&#xff09;&a…

Python查询和操作HTML文档库之pyquery使用详解

概要 在Web开发和数据抓取中,处理HTML文档是一项常见任务。Python的pyquery库提供了一个强大且灵活的方式来查询和操作HTML文档,类似于jQuery的语法。通过这篇文章,将深入了解pyquery的安装、特性、基本和高级功能,以及它在实际应用中的用例。 安装 安装pyquery相当简单,…

python:SunMoonTimeCalculator

# encoding: utf-8 # 版权所有 2024 ©涂聚文有限公司 # 许可信息查看&#xff1a; # 描述&#xff1a; https://github.com/Broham/suncalcPy # Author : geovindu,Geovin Du 涂聚文. # IDE : PyCharm 2023.1 python 3.11 # Datetime : 2024/5/14 21:59 # User …

MQTT_服务器的安装_1.3

此例子是以Windows系统安装开源版本的EMQX 下载 EMQX 下载并解压 解压如图 进入bin 文件夹在文件目录中输入cmd回车 启动服务器 然后在cmd中输入下面的代码&#xff08;会弹出一个访问网络的选项&#xff0c;确认可以访问网络&#xff09; emqx start 结果如图&#xff08;…

在Linux中安装Docker

如果之前安装过旧版本的 Docker&#xff0c;可以使用下面命令卸载&#xff1a; yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-selinux \docker-engine-selinux \docker-engine…

YOLO损失函数——SIoU和Focal Lossr损失函数解析

1. 概述 YOLO&#xff08;You Only Look Once&#xff09; 系列模型以其实时目标检测能力而闻名&#xff0c;其有效性在很大程度上归功于其专门设计的损失函数。在本文中&#xff0c;这里将深入探讨YOLO演进中不可或缺的各种YOLO损失函数&#xff0c;并重点介绍它们在PyTorch中…

免费泛域名证书申请

通配符证书是一种 SSL/TLS 证书&#xff0c;可用于保护多个域&#xff08;主机&#xff09;&#xff0c;由域名字段中的通配符 (*) 指示。 如果您有很多需要保护的域或子域&#xff0c;这会很有帮助&#xff0c;因为它可以节省您的时间和金钱。 本文将讨论通配符证书、它们的工…

代码复现|Demucs Music Source Separation

一、背景介绍 Demucs是一个开源的音源分离项目。 Demucs在算法层面前后经历了三次大版本的进化&#xff0c;最原始的V1版本是&#xff1a;编解码LSTM。具体算法原理图如下所示。该版本在时域进行音源分离。关于阅读笔记请点击这篇文章。 V1版本原理图 V2版本是同时使用时域和频…

车牌检测识别功能实现(pyqt)

在本专题前面相关博客中已经讲述了 pyqt + yolo + lprnet 实现的车牌检测识别功能。带qt界面的。 本博文将结合前面训练好的模型来实现车牌的检测与识别。并用pyqt实现界面。最终通过检测车牌检测识别功能。 1)、通过pyqt5设计界面 ui文件如下: <?xml version="1…