MySQL 数据库的约束和表的关系


MySQL

I. 数据库的约束

1. 概述

  • 作用:对表中的数据进行限定,保证数据的正确性、有效性和完整性。

2. 分类

primary key:主键约束,要求表中有一个字段,唯一且非空,通常使用 ID 作为主键

unique:唯一约束

not null:非空约束

default:默认值

foreign key:外键约束

3. 主键约束 primary key

a. 作用

  • 主键的作用一条数据的唯一标识,限定某一列的值非空且唯一。

b. 语法

1. 设置主键约束
	1)创建表
		create table 表名(
		  id int primary key,
		  ...
		  ...
		);
	2)已有表
		alter tabe 表名 add primary key(id);
		
2. 特点:
	一张表只能有一个主键约束,但是可以设置联合主键,即:
		PRIMARY KEY (`id`,`keyword`)
	删除也是非常简单只要: 
		ALTER TABLE test DROP PRIMARY KEY ,ADD PRIMARY KEY (`id`); 
	如果仅仅是删除联合主键会报错: 
		ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key 
		
3. 自增器
	1)创建表
		create table 表名(
			id int priamry key auto_increment,
			...
			...
		);
	2)特点:自增器起始值为1,可以手动指定
		alter table 表名 auto_increment=起始值;		
		
4. 删除主键约束
	1)先移出自增器
		alter table 表名 modify id int;
	2)才能删除主键约束
		alter table 表名 drop primary key;
  • MySQL 中的命名规范:单词与单词之间使用下划线分割。

c. 示例

-- 主键约束
-- 给student表添加主键约束
ALTER TABLE student ADD PRIMARY KEY(id);

-- 创建表时指定主键约束
CREATE TABLE stu1(
 id INT PRIMARY KEY,
 `name` VARCHAR(32)
);
-- 插入数据测试
INSERT INTO stu1 VALUES(1,'jack');
-- Duplicate entry '1' for key 'PRIMARY' 错误:主键不能重复
INSERT INTO stu1 VALUES(1,'lucy');
-- Column 'id' cannot be null 错误:主键不能为空
INSERT INTO stu1 VALUES(NULL,'lucy');

-- 我想让name字段,也作为主键使用...
-- Multiple primary key defined -- 错误:主键被重复定义了
ALTER TABLE stu1 ADD PRIMARY KEY(`name`);



-- 联合主键(主键字段完全相同,在进行约束的限定)
CREATE TABLE stu2(
 id INT ,
 `name` VARCHAR(32),
 PRIMARY KEY(id,`name`)
);
-- 插入数据测试
INSERT INTO stu2 VALUES(1,'jack');
INSERT INTO stu2 VALUES(1,'lucy');
-- Duplicate entry '1-lucy' for key 'PRIMARY' 错误
INSERT INTO stu2 VALUES(1,'lucy');


-- 自增器
CREATE TABLE stu3(
  id INT PRIMARY KEY AUTO_INCREMENT,
  `name` VARCHAR(32)
);
-- 插入数据测试
INSERT INTO stu3 VALUES(1,'jack');
INSERT INTO stu3 VALUES(NULL,'jack');
INSERT INTO stu3 VALUES(3,'jack');
INSERT INTO stu3 VALUES(NULL,'jack');
INSERT INTO stu3 VALUES(10,'jack');
INSERT INTO stu3 VALUES(NULL,'jack');

-- 设置自增器起始值
ALTER TABLE stu3 AUTO_INCREMENT=1000;
INSERT INTO stu3 VALUES(NULL,'jack');

-- delete(橡皮擦) 和 truncat(撕纸) 区别:delete继续主键约束自增器,truncate清除主键约束自增器
DELETE FROM stu3;
INSERT INTO stu3 VALUES(NULL,'jack');


TRUNCATE TABLE stu3;
INSERT INTO stu3 VALUES(NULL,'jack');


-- 1)先移出自增器
	ALTER TABLE stu3 MODIFY id INT;
-- 2)才能删除主键约束
	ALTER TABLE stu3 DROP PRIMARY KEY;

d. 主键与唯一非空

  • 问题:唯一 + 非空 = 主键 吗?
    • 不等于,主键约束一张表只能有一个,唯一 + 非空 设置多个。
  • 主键的特点:
    • 唯一
    • 非空
    • 被引用
  • 某一列设置了非空与唯一与主键的区别: 不能被其他表所引用。
-- 创建一个部门表
CREATE TABLE dept(
	id INT PRIMARY KEY AUTO_INCREMENT,  -- tab键是自动补全
	NAME VARCHAR(10) NOT NULL UNIQUE  -- 非空, 唯一。 
);
     
INSERT INTO dept VALUES(NULL,'财务部');
     
 -- 创建一个员工表
CREATE TABLE emp(
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAR(10),
	dept_id INT, -- 员工所属的部门名称
	CONSTRAINT fk_emp_dept FOREIGN KEY(dept_id) REFERENCES dept(id)-- 建立外键关系
);

4. 唯一约束 unique

a. 作用

  • 限定某一列的值不能重复,可以出现多个 null。

b. 语法

1. 创建表时设置唯一约束
		create table 表名(
			列名 数据类型 unique,
			...
			...
		);

c. 示例

-- 唯一约束
CREATE TABLE stu4(
  id INT PRIMARY KEY AUTO_INCREMENT,
  `name` VARCHAR(32) UNIQUE 
);

INSERT INTO stu4 VALUES(1,'jack');
-- Duplicate entry 'jack' for key 'name' 错误:名称重复了
INSERT INTO stu4 VALUES(2,'jack');
INSERT INTO stu4 VALUES(3,NULL);
INSERT INTO stu4 VALUES(4,NULL);

5. 非空约束 not null

a. 作用

  • 限定某一列的值不能为 null。

b. 语法

1. 创建表时设置非空约束
		create table 表名(
			列名 数据类型 not null,-- 非空约束
			列名 数据类型 unique not null,-- (唯一+非空)
		
		);

c. 示例

-- 唯一+非空
CREATE TABLE stu5(
 id INT PRIMARY KEY AUTO_INCREMENT,
 `name` VARCHAR(32) UNIQUE NOT NULL
);

INSERT INTO stu5 VALUES(1,'jack');
-- Column 'name' cannot be null 错误:名称不能为空
INSERT INTO stu5 VALUES(2,NULL);

6. 默认值 default

a. 作用

  • 限定某一列的默认值,再没有指定的情况下所有列的默认值为 null。

b. 语法

1. 创建表设置默认值
		create table 表名(
		  列名 数据类型 default 默认值,
		  ...
		  ...
		);

c. 示例

-- 默认值
CREATE TABLE stu6(
  id INT PRIMARY KEY AUTO_INCREMENT,
  `name` VARCHAR(32),
  sex VARCHAR(5) DEFAULT '男'
);
INSERT INTO stu6(id,`name`) VALUES(1,'小张');
INSERT INTO stu6(id,`name`,sex) VALUES(2,'小刘','女');
-- 因为这里指定了默认值为男,如果再插入null,会把默认值覆盖...
INSERT INTO stu6 VALUES(3,'小王',NULL);

II. 表的关系

1. 概述

  • 现实生活中,(班级)实体与(学生)实体之间肯定是有关系的,那么在设计表的时候,就应该体现出(班级)表与(学生)表之间的这种关系。
  • 简称:关系型数据库(Relation DBMS)

2. 分类

  1. 一对多
    • 应用场景:班级和学生、部门和员工。
    • 解释:一个班级下面有多名同学,多名同学属于某一个班级。
  2. 多对多
    • 应用场景:老师和学生、学生和课程。
    • 解释:一名老师可以教导多名学生,一名学生可以被多个老师教导。
  3. 一对一
    • 应用场景:公民和身份证号、公司和注册地。
    • 解释:一个公民只能有一个身份证号,一个身份证号对应一个公民。

a. 一对多

  • 例如,班级和学生。
    在这里插入图片描述
  • 称“一”方为:主表或一表;称“多”方为:从表或多表。
  • 建立原则:在从表中添加一个字段(列),字段名(主表名_id)类型与主表的主键一致。这个字段称作外键,通过主外键关联,就建立两张表的关联了。
-- 创建新库
CREATE DATABASE day19_pro;
USE day19_pro;

-- 一对多

-- 班级表(主表)
CREATE TABLE class(
  id INT PRIMARY KEY AUTO_INCREMENT,
  `name` VARCHAR(32)
);
INSERT INTO class VALUES(1,'java一班');
INSERT INTO class VALUES(2,'java二班');

-- 学生表(从表)
CREATE TABLE student(
  id INT PRIMARY KEY AUTO_INCREMENT,
  `name` VARCHAR(32),
  class_id INT -- 外键字段
  
);
INSERT INTO student VALUES(1,'流川枫',1);
INSERT INTO student VALUES(2,'樱木花道',1);
INSERT INTO student VALUES(3,'大猩猩',2);
INSERT INTO student VALUES(4,'赤木晴子',2);

-- 通过班级找学生
SELECT * FROM student WHERE class_id =1;

-- 通过学生找班级
SELECT * FROM class WHERE id = 2;


-- 给学生表添加外键约束
ALTER TABLE student ADD CONSTRAINT class_id_fk FOREIGN KEY(class_id) REFERENCES class(id);

-- 删除学生表的外键约束
ALTER TABLE student DROP FOREIGN KEY class_id_fk;

b. 多对多

  • 例如,学生和课程。
    在这里插入图片描述
  • 建表原则:由两个一对多组成。创建第三张表(从表,又称中间表),在中间表中添 2 个外键字分别指向各自的主键,通常中间表的这 2 个外键字称作联合主键。
-- 多对多

-- 课程表(主表)
CREATE TABLE course(
  id INT PRIMARY KEY AUTO_INCREMENT,
  `name` VARCHAR(32)
);
INSERT INTO course VALUES(1,'java');
INSERT INTO course VALUES(2,'ui');
INSERT INTO course VALUES(3,'美容美发');
INSERT INTO course VALUES(4,'挖掘机');
-- 中间表(从表)
CREATE TABLE sc(
  s_id INT,
  c_id INT,
  PRIMARY KEY(s_id,c_id)
);
INSERT INTO sc VALUES(1,1);
INSERT INTO sc VALUES(1,2);
INSERT INTO sc VALUES(2,1);
INSERT INTO sc VALUES(2,3);

-- 联合主键,可以处理校验重复选修问题
INSERT INTO sc VALUES(1,1);


-- 给中间表增加外键约束
ALTER TABLE sc ADD CONSTRAINT s_id_fk FOREIGN KEY(s_id) REFERENCES student(id);
ALTER TABLE sc ADD CONSTRAINT c_id_fk FOREIGN KEY(c_id) REFERENCES course(id);

-- 流川枫不能选修,不存在的课程
INSERT INTO sc VALUES(1,6);

c. 表与实体类

  • 数据库的表是映射的 Java 中的类。
  • 表与表的关系在 Java 中会用类中的某个字段等形式体现出来,但不会有什么“中间类”。
  • 多对多可以分为两个一对多,而一对多的表的关系在 Java 类中以 包含 关系体现,比如,一个班级有多个学生。
class 班级 {
	private List<学生> 学生List;
}

d. 一对一

  • 一对一关系在实际开发中用的并不多,因为可以办关联字段设计在同一张表。
  • 例如,公司和注册地。
-- 一对一

-- 公司表
CREATE TABLE company(
 id INT PRIMARY KEY AUTO_INCREMENT,
 `name` VARCHAR(32)
);
INSERT INTO company VALUES(1,'拼多多');
INSERT INTO company VALUES(2,'传智播客');
-- 地址表
CREATE TABLE address(
 id INT PRIMARY KEY AUTO_INCREMENT, -- 同时也作为外键
 `name` VARCHAR(32),
 CONSTRAINT id_fk FOREIGN KEY(id) REFERENCES company(id)
);
INSERT INTO address VALUES(1,'上海');
INSERT INTO address VALUES(2,'江苏沭阳');

3. 外键约束 foreign key references

a. 作用

  • 限定二张表有关系的数据,保证数据的正确性、有效性和完整性。
  • 在企业开发过程中:传统的项目需要外键约束,互联网项目因为性能问题绝对不用。实际开发中,大部分项目会对数据库禁止使用约束。

b. 特点

  1. 主表不能删除从表已引用的数据。
  2. 从表不能添加主表未拥有的数据。
  3. 先添加主表数据再添加从表数据。
  4. 先删除从表数据再删除主表数据。
  5. 外键约束允许为空但不能是错的。

c. 语法

1. 在从表中添加外键约束
	1)创建表
		create table 表名(
			列名 数据类型,
			[constraint] [约束名] foreign key(外键列) references 主表(主键)
		);		
	2)已有表
		alter table 表名 add [constraint] [约束名] foreign key(外键列) references 主表(主键);
		
		
2. 删除外键约束
		alter table 表名 drop foreign key 约束名;

4. 外键的级联

a. 作用

  • 对主表进行修改、删除的时候自动级联到从表中(即修改了主表,那么从表的数据跟着变化)

b. 语法

on update cascade 更新级联

on delete cascade 删除级联


CREATE TABLE 表名(
  CONSTRAINT 外键名称 FOREIGN KEY(从表外键列) REFERENCES 主表(主键列) on update cascade || on delete cascade   -- 建立外键关系,并且创建外键的级联关系
);

c. 示例

-- 创建一个部门表
CREATE TABLE dept(
   id INT PRIMARY KEY AUTO_INCREMENT,  -- tab键是自动补全
    
   NAME VARCHAR(10) NOT NULL UNIQUE  -- 非空, 唯一。 
);

INSERT INTO dept VALUES(NULL,'财务部');

-- 创建一个员工表
CREATE TABLE emp(
  id INT PRIMARY KEY AUTO_INCREMENT,
  NAME VARCHAR(10),
  dept_id INT, -- 员工所属的部门名称
  CONSTRAINT fk_emp_dept FOREIGN KEY(dept_id) REFERENCES dept(id)
  ON UPDATE CASCADE ON DELETE CASCADE-- 建立外键关系
);

INSERT INTO emp VALUES(NULL,'老板',1);
INSERT INTO emp VALUES(NULL,'小明',2);
INSERT INTO emp VALUES(NULL,'小陈',2);
INSERT INTO emp VALUES(NULL,'花花',2);

原文链接:https://qwert.blog.csdn.net/article/details/105840314

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值