【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.hqwc.cn/news/703748.html

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

相关文章

算法分析与设计复习__递归方程与分治

总结自&#xff1a;【算法设计与分析】期末考试突击课_哔哩哔哩_bilibili 1.递归&#xff0c;递归方程 1.1递归条件: 1.一个问题的解可以分解为几个子问题的解&#xff1b; 2.这个问题与分解之后的子问题&#xff0c;除了数据规模不同&#xff0c;求解思路完全一样; 3.存在…

Python从0到100(二十四):正则表达式的应用

正则表达式是一种用于字符串搜索和操作的强大工具&#xff0c;它允许你使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在编程中&#xff0c;正则表达式被广泛应用于文本处理&#xff0c;如模式搜索、文本替换、字符串验证等。 1.正则表达式基础 正则表达式由一…

Edge(微软)——一款充满创新精神的浏览器

随着科技的不断进步&#xff0c;互联网浏览器已经成为我们日常生活中不可或缺的工具。在这个领域&#xff0c;微软Edge作为一款新型的浏览器&#xff0c;凭借其独特的功能和优秀的性能&#xff0c;逐渐在市场上占据了一席之地。本文将深入探索微软Edge的特点、优势以及它如何改…

【MySQL 数据宝典】【事务锁】- 002 事务控制的演进

一、事务处理思路 1.1 排队 排队处理是事务管理最简单的方法&#xff0c;就是完全顺序执行所有事务的数据库操作&#xff0c;不需要加锁&#xff0c;简单的说就是全局排队。序列化执行所有的事务单元&#xff0c;数据库某个时刻只处理一个事务操作&#xff0c;特点是强一致性…

测缝计测量的是实际缝宽吗?

在土木工程中&#xff0c;测缝计作为一种重要的监测工具&#xff0c;广泛应用于桥梁、隧道、大坝等大型结构中&#xff0c;用以测量和监控结构接缝或裂缝的实际宽度变化。然而&#xff0c;有些人可能会产生疑问&#xff1a;测缝计测量的是实际缝宽吗?本文将对这一问题进行深入…

六西格玛管理培训对企业有哪些实际帮助?

当下&#xff0c;企业要想脱颖而出&#xff0c;不仅要有创新思维和敏锐的市场洞察力&#xff0c;更要有高效的管理体系和严谨的质量控制手段。而六西格玛管理培训正是这样一项能够帮助企业实现提质增效、提升竞争力的关键举措。那么&#xff0c;六西格玛管理培训对企业究竟有哪…

亲子失和最大的内耗是:家长总是“说硬话,办软事”!

一声爸妈&#xff0c;一辈子的责任&#xff0c;操不完的心、做不完的事。 然而&#xff0c;爱太满&#xff0c;注定会溢出。爱有边界&#xff0c;我们是父母&#xff0c;更是自己&#xff01; 01 前些时候悠悠起床又开始混账了&#xff01; 气愤的是&#xff0c;周末休息那…

MES系统在电线电缆行业生产上的应用

MES系统在线缆行业的应用可以带来多重价值&#xff0c;包括提高生产效率、降低生产成本、提高产品质量、优化库存管理、改善生产环境和提高企业竞争力等方面。因此&#xff0c;在电线电缆行业中广泛应用MES系统可以提高企业的经济效益和社会效益&#xff0c;推动企业发展和行业…

平芯微PW4056HH中文规格书

概述 PW4056HH 是一款完整的采用恒定电流/恒定电压的高压、大电流、单节锂离子电池线性充电 IC。充电电流可达 1A。输入 MAX 低工作电压 3.75V&#xff0c;降低充电功耗&#xff0c;提高效率。 PW4056HH 采用了内部 PMOS 架构&#xff0c;加上防反充电路&#xff0c;不需要外部…

Lumina-T2X 一个使用 DiT 架构的内容生成模型,可通过文本生成图像、视频、多视角 3D 对象和音频剪辑。

Lumina-T2X 是一个新的内容生成系列模型&#xff0c;统一使用 DiT 架构。通过文本生成图像、视频、多视角 3D 对象和音频剪辑。 可以在大幅提高生成质量的前提下大幅减少训练成本&#xff0c;而且同一个架构支持不同的内容生成。图像质量相当不错。 由 50 亿参数的 Flag-DiT …

HL7协议

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1.介绍2.传输协议规范2.1. MLLP2.1.1. 数据头定义2.1.2. 转义字符集 2.2. 规范说明2.3. 消息格式说明 3.HL7结构介绍3.1. 患者建档&#xff08;ADT^A28&#xff09;…

webpack5零基础入门-14提取css为单独文件

1.背景 Css文件目前被打包到JS文件中&#xff0c;当JS文件加载时&#xff0c;会尝试创建一个style标签来生成样式&#xff0c;这样对于网站来说&#xff0c;会出现闪屏的现象&#xff0c;用户体验不好。我们应该是单独的Css文件&#xff0c;通过link标签来加载性能才好。 2.下…