MySQL(表的约束)

news2024/11/20 10:47:30

文章目录

  • 0. 前言
  • 1. 空属性
  • 2. 默认值
  • 3. 列描述
  • 4. zerofill
  • 5. 主键
  • 6. 自增长
  • 7. 唯一键
  • 8. 外键

0. 前言

  • 真正约束字段的是数据类型,但是数据类型约束很单一,需要有一些额外的约束,更好的保证数据的合法性,从业务逻辑角度保证数据的正确性。比如有一个字段是email,要求是唯一的。

    表的约束很多,这里主要介绍如下几个: null/not null,default, comment, zerofill,primary key,auto_increment,unique key 
    
  • 表的结构
    在这里插入图片描述

1. 空属性

  • 两个值:null(默认的)和not null(不为空)
  • 数据库默认字段基本都是字段为空,但是实际开发时,尽可能保证字段不为空,因为数据为空没办法参与运算。
    在这里插入图片描述

案例:
创建一个班级表,包含班级名和班级所在的教室。(班级和教室不能为空)

mysql> system clear
mysql> system clear;
mysql> create table myclass(
    -> class_name varchar(20) not NULL,
    -> class_room varchar(10) not NULL
    -> );
Query OK, 0 rows affected (0.18 sec)

mysql> desc myclass;
+------------+-------------+------+-----+---------+-------+
| Field      | Type        | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| class_name | varchar(20) | NO   |     | NULL    |       |
| class_room | varchar(10) | NO   |     | NULL    |       |
+------------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> insert into myclass values(NULL, NULL);
ERROR 1048 (23000): Column 'class_name' cannot be null
mysql> insert into myclass values();
ERROR 1364 (HY000): Field 'class_name' doesn't have a default value

2. 默认值

  • 默认值:某一种数据会经常性的出现某个具体的值,可以在一开始就指定好,在需要真实数据的时候,
    用户可以选择性的使用默认值(就是不再显示填写)。

案例:

mysql> create table tt8(
    -> name varchar(20) not NULL,
    -> age tinyint unsigned default 18,
    -> sex char(1) default '女'
    -> );
Query OK, 0 rows affected (0.27 sec)

mysql> desc tt8;
+-------+---------------------+------+-----+---------+-------+
| Field | Type                | Null | Key | Default | Extra |
+-------+---------------------+------+-----+---------+-------+
| name  | varchar(20)         | NO   |     | NULL    |       |
| age   | tinyint(3) unsigned | YES  |     | 18      |       |
| sex   | char(1)             | YES  |     ||       |
+-------+---------------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

默认值生效

mysql> insert into tt8(name) values('刘亦菲');
Query OK, 1 row affected (0.03 sec)

mysql> select * from tt8;
+-----------+------+------+
| name      | age  | sex  |
+-----------+------+------+
| 刘亦菲    |   18 ||
+-----------+------+------+
1 row in set (0.00 sec)

3. 列描述

  • 列描述:comment,没有实际含义,专门用来描述字段,会根据表创建语句保存。就类似于代码中的注释。

案例:

mysql> create table tt9(
    -> name varchar(20) not NULL comment '姓名',
    -> age tinyint unsigned default 18 comment '年龄',
    -> sex char(1) default '女' comment '性别'
    -> );
Query OK, 0 rows affected (0.14 sec)

mysql> desc tt9;
+-------+---------------------+------+-----+---------+-------+
| Field | Type                | Null | Key | Default | Extra |
+-------+---------------------+------+-----+---------+-------+
| name  | varchar(20)         | NO   |     | NULL    |       |
| age   | tinyint(3) unsigned | YES  |     | 18      |       |
| sex   | char(1)             | YES  |     ||       |
+-------+---------------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

desc 查看不到注释信息,通过show查看创建完整指令可以看见。

mysql> show create table tt9\G
*************************** 1. row ***************************
       Table: tt9
Create Table: CREATE TABLE `tt9` (
  `name` varchar(20) NOT NULL COMMENT '姓名',
  `age` tinyint(3) unsigned DEFAULT '18' COMMENT '年龄',
  `sex` char(1) DEFAULT '女' COMMENT '性别'
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.01 sec)

4. zerofill

可以看到int(11),这个代表什么意思呢?这个10代表什么呢?其实没有zerofill这个属性,括号内的数字是毫无意义的。

mysql> create table `tt10`(
    -> a int,
    -> b int
    -> );
Query OK, 0 rows affected (0.21 sec)

mysql> insert into `tt10` values(1, 2);
Query OK, 1 row affected (0.02 sec)

mysql> show create table `tt10`\G
*************************** 1. row ***************************
       Table: tt10
Create Table: CREATE TABLE `tt10` (
  `a` int(11) DEFAULT NULL,
  `b` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

mysql> select * from `tt10`;
+------+------+
| a    | b    |
+------+------+
|    1 |    2 |
+------+------+
1 row in set (0.00 sec)

alter table `tt10` change a a int(5) unsigned zerofill;
mysql> select * from `tt10`;
+-------+------+
| a     | b    |
+-------+------+
| 00001 |    2 |
+-------+------+
1 row in set (0.00 sec)
// 实际完整写法如下:
mysql> show create table `tt10`\G
*************************** 1. row ***************************
       Table: tt10
Create Table: CREATE TABLE `tt10` (
  `a` int(5) unsigned zerofill DEFAULT NULL,
  `b` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

实际上zerofill属性的作用:宽度小于设定的宽度(这里设置的是5),前面自动填充0。

实际上存的值还是1,调用函数hex来证明.

mysql> select a, hex(a) from `tt10`;
+-------+--------+
| a     | hex(a) |
+-------+--------+
| 00001 | 1      |
+-------+--------+
1 row in set (0.00 sec)

5. 主键

  • 主键:primary key用来唯一的约束该字段里面的数据,不能重复,不能为空,一张表中最多只能有一个。
  • 主键;主键所在的列通常是整数类型。

验证:

mysql> create table `tt11`(
    -> id int unsigned primary key comment '学号不能为空',
    -> name varchar(20) not NULL
    -> );
Query OK, 0 rows affected (0.20 sec)

mysql> insert into `tt11` values(1, '小丁');
Query OK, 1 row affected (0.04 sec)

mysql> insert into `tt11` values(1, '小花');
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
mysql> insert into `tt11`(name) values('小花');
ERROR 1364 (HY000): Field 'id' doesn't have a default value
实际完整写法就包含了不能重复,不能为空
mysql> show create table `tt11`\G
*************************** 1. row ***************************
       Table: tt11
Create Table: CREATE TABLE `tt11` (
  `id` int(10) unsigned NOT NULL COMMENT '学号不能为空',
  `name` varchar(20) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
  • 主键约束:主键对应的字段中不能重复,一旦重复,操作失败。
mysql> insert into `tt11` values(1, '小丁');
Query OK, 1 row affected (0.04 sec)

mysql> insert into `tt11` values(1, '小花');
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
  • 删除主键
alter table 表名 drop primary key;
mysql> alter table `tt11` drop primary key;
Query OK, 1 row affected (0.53 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> insert into `tt11` values(1, '小花');
Query OK, 1 row affected (0.04 sec)

mysql> select * from `tt11`;
+----+--------+
| id | name   |
+----+--------+
|  1 | 小丁   |
|  1 | 小花   |
+----+--------+
2 rows in set (0.00 sec)

  • 追加主键:追加主键的字段表一定要符合主键的性质
alter table 表名 add primary key(字段列表);
mysql> alter table `tt11` add primary key(id);
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'

mysql> alter table `tt11` add primary key(name);
Query OK, 0 rows affected (0.41 sec)
Records: 0  Duplicates: 0  Warnings: 0

// name字段可以成为主键
mysql> desc `tt11`;
+-------+------------------+------+-----+---------+-------+
| Field | Type             | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+-------+
| id    | int(10) unsigned | NO   |     | NULL    |       |
| name  | varchar(20)      | NO   | PRI | NULL    |       |
+-------+------------------+------+-----+---------+-------+
2 rows in set (0.01 sec)
  • 复合主键

id和course为复合主键

mysql> create table `tt12`(
    -> id int unsigned,
    -> score tinyint unsigned default 60 comment '成绩',
    -> primary key(id, score)
    -> );

复合主键特点:id和course只要不完成相同就没事
mysql> select * from `tt12`;
+----+-------+
| id | score |
+----+-------+
|  1 |    60 |
|  1 |    99 |
|  2 |    60 |
+----+-------+
3 rows in set (0.01 sec)

在这里插入图片描述

6. 自增长

  • auto_increment:当对应的字段,不给值,会自动的被系统触发,系统会从当前字段中已经有的最大值+1操作,得到一个新的不同的值。
  • 通常和主键搭配使用,作为逻辑主键。
mysql> create table `tt13`(
    -> id int unsigned primary key auto_increment,
    -> name varchar(20) not NULL default ''
    -> );
Query OK, 0 rows affected (0.19 sec)

mysql> insert into `tt13` values('a');
ERROR 1136 (21S01): Column count doesn't match value count at row 1
mysql> insert into `tt13`(name) values('a');
Query OK, 1 row affected (0.04 sec)

mysql> insert into `tt13`(name) values('b');
Query OK, 1 row affected (0.03 sec)

mysql> insert into `tt13` values();
Query OK, 1 row affected (0.03 sec)

mysql> select * from `tt13`;
+----+------+
| id | name |
+----+------+
|  1 | a    |
|  2 | b    |
|  3 |      |
+----+------+
3 rows in set (0.00 sec)
改下自增长起始值
mysql> insert into `tt13` values(10001, '马化腾');
Query OK, 1 row affected (0.02 sec)

mysql> insert into `tt13`(name) values('c');
Query OK, 1 row affected (0.04 sec)


mysql> select * from `tt13`;
+-------+-----------+
| id    | name      |
+-------+-----------+
|     1 | a         |
|     2 | b         |
|     3 |           |
| 10001 | 马化腾    |
| 10002 | c         |
+-------+-----------+
5 rows in set (0.00 sec)

  • 自增长的特点:
    • 任何一个字段要做自增长,前提是本身是一个索引(key一栏有值)
    • 自增长字段必须是整数
    • 一张表最多只能有一个自增长

7. 唯一键

  • 唯一键与主键
一张表中有往往有很多字段需要唯一性,数据不能重复,但是一张表中只能有一个主键:唯一键可以解决表中有多个字段需要唯一性约束的问题。

案例:

mysql> create table `tt14`(
    -> id int unsigned primary key auto_increment,
    -> student_id char(10) not NULL unique comment '学号不能重复'
    -> );
Query OK, 0 rows affected (0.21 sec)

mysql> insert into `tt14`(student_id) values(1234);
Query OK, 1 row affected (0.02 sec)

mysql> insert into `tt14`(student_id) values(1234);
ERROR 1062 (23000): Duplicate entry '1234' for key 'student_id'   -- 学号重复,报错。


mysql> select * from `tt14`;
+----+------------+
| id | student_id |
+----+------------+
|  1 | 1234       |
+----+------------+
1 row in set (0.00 sec)

注意:

唯一键的本质和主键差不多,唯一键允许为空,而且可以多个为空,空字段不做唯一性比较。
alter table `tt14` change student_id student_id char(10) unique comment '学号不为空,可以重复';

mysql> insert into `tt14` values();
Query OK, 1 row affected (0.02 sec)

mysql> insert into `tt14` values();
Query OK, 1 row affected (0.02 sec)

// 最好在插入数据前就设计好。
mysql> select * from `tt14`;
+----+------------+
| id | student_id |
+----+------------+
|  3 | NULL       |
|  4 | NULL       |
|  1 | 1234       |
+----+------------+
3 rows in set (0.00 sec)

8. 外键

  • 外键用于定义主表和从表之间的关系:外键约束主要定义在从表上,主表则必须是有主键约束或unique约束。当定义外键后,要求外键列数据必须在主表的主键列存在或为null。
    在这里插入图片描述

  • 语法

    foreign key (字段名) references 主表(列)
    

案例:

  • 创建主键表
create table `myclass`(
    -> id int primary key,
    -> name varchar(20) not NULL comment '班级名'
    -> );
  • 创建从表
 create table `stu`(
    -> id int primary key,
    -> name varchar(30) not NULL comment '学生名',
    -> class_id int,
    -> foreign key(class_id) references `myclass`(id)
    -> );
  • 正常插入数据
mysql> insert into `myclass` values(10, '104班'), (20, '105班');
Query OK, 2 rows affected (0.03 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> insert into `stu` values(100, '张三', 10), (101, '李四', 20);
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0
  • 插入主键表不存在的班级,插入失败
mysql> insert into `stu` values(102, '李欢', 30);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`person`.`stu`, CONSTRAINT `stu_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `myclass` (`id`))

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【ChatGPTMidjourney】许多职业即将消失,AI 即将战胜人类了吗?

文章目录 前言一、人类科技发展史二、 AI浪潮下的挑战1. 数据安全和隐私保护问题2. 带来新的伦理和道德问题3. 版权和知识产权问题 三、对传统行业和就业的冲击1.传统文本编辑行业受到冲击2.就业岗位的变化3.工作流程的变化4.创意版权问题 四、AI浪潮下的机遇1.提高效率和创意性…

不用网闸、FTP的话 如何实现内外网数据交换?

网络隔离已然成为很多企业首选的数据保护方式,即使是内部人员之间,也是不能随意的发送敏感文件的。但是,文件的流转交互,又是不可避免的,网络隔离保障了企业网络安全,但在具体实践中仍需解决各隔离网间的数…

基于html+css图展示57

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

Ubuntu一条命令下载MCU固件

现在很多项目开发都逐渐的迁移到Linux环境下。但是Linux开发单片机就没有像Windows下开发那么方便,它没有对应开发工具(KEIL,IAR等),它们自带烧录等功能。所以在Linux上开发单片机需要安装下载固件的工具–JLink。 J…

小程序上线流程

1.配置服务器域名 小程序接口API 2.业务域名配置 ​首先配置小程序的业务域名,将下载txt文件放在A 域名根目录下,然后才可以配置业务域名为 A 。主要应用场景为,小程序页面跳转其他小程序 3. npm run build:weapp 编译,小程序代…

【ChatGPT】 AI 手把手一步一步教学 Self-Attention:这些动图和代码让你一次读懂ChatGPT背后的“自注意力”

BERT 及其多种变体已经在多种语言理解任务上取得了非常出色的表现,这些架构全都基于 Transformer,而 Transformer 又使用了一种名为「自注意力」的方法。本文将通过图示和代码对自注意力机制进行透彻的解读。当然,在阅读本文之前,你可能也想了解什么是注意力机制。没有问题…

【JS】js常用工具类:

文章目录 一、 将对象拼接到url地址后面二、正则获取url中的图片名称三、获取多数组之间的差集四、数组遍历判断是否需要拼接地址五、 数组去重六、如果值不存在就 push 进数组, 反之不处理七、过滤对象中为NaN,undefined的属性八、字符串中插入千位分隔…

基于SpringBoot+Vue的校园疫情防控系统(附源码和数据库)

文章目录 第一章2.主要技术第三章第四章 系统设计4.1功能结构4.2 数据库设计4.2.1 数据库E/R图4.2.2 数据库表 第五章 系统功能实现5.1系统功能模块5.2后台功能模块5.2.1管理员功能 源码咨询 第一章 springboot校园疫情防控系统演示录像2022 一个好的系统能将校园疫情防控的管理…

ChatGPT网站如何像软件一样可以安装下载

今天给大家分享一下, 如何实现网站能够在手机端像软件一样下载在桌面保存, 这样下次就能像打开app一样访问网站了, 是不是听了之后会很心动呢, 接下来我们就一起来学习一下知识, 快来试试这样的效果吧, 最后分享一下我做的一个chatGPT网站, 欢迎大家免费试玩chatGPT, 不过我的免…

JVM系列-第8章-执行引擎

执行引擎 执行引擎概述 执行引擎概述 执行引擎是Java虚拟机核心的组成部分之一。“虚拟机”是一个相对于“物理机”的概念,这两种机器都有代码执行能力,其区别是物理机的执行引擎是直接建立在处理器、缓存、指令集和操作系统层面上的,而虚拟…

GreatSQL社区月报 | 2023.04

GreatSQL 是一个开源的 MySQL 技术路线数据库社区,社区致力于通过开放的社区合作,构建国内自主 MySQL 版本及开源数据库技术,推动中国开源数据库及应用生态繁荣发展。 为了帮助社区的小伙伴们更好地了解 GreatSQL 社区的实时进展&#xff0c…

项目经理什么事都做,只会让你成为工具人

每个人拥有的时间都是一样的,每天二十四个小时,为什么有的项目经理每天提前完成工作下班喝酒撸串,为什么有的项目经理每天熬夜加班到天明? 为什么总是你的时间不够用,每天都很忙碌呢。很可能是你的时间没有管理好。 …

笔记-指针的进阶

1.字符指针 char arr[] "hello bit." char * p arr 这里p指向的是数组的首元素,arr数组是可以修改的。 (const)char * pstr "hello bit." 这里的字符串是常量字符串,不能修改。 这里有一个面试题&#xf…

LeetCode_二叉树_中等_113.路径总和 II

目录 1.题目2.思路3.代码实现(Java) 1.题目 给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有从根节点到叶子节点路径总和等于给定目标和的路径。 叶子节点是指没有子节点的节点。 示例 1: 输入:root…

网络基础知识(1)——从OSI七层模型和TCP/IP说起

网络通信概述 网络通信本质上是一种进程间通信,是位于网络中不同主机上的进程之间的通信,属于 IPC 的一种, 通常称为 socket IPC,如图中所示。所以网络通信是为了解决在网络环境中,不同主机上的应用程序之间的通信问题…

U盘上的文件删除了可以恢复吗 U盘上的文件怎么在电脑上恢复

随着数据时代的到来,人们使用U盘来存储和传输文件已经成为一种普遍的方式。然而,有时候人们会不小心将重要的文件从U盘上删除,或者由于其他原因导致文件丢失,这会给人们带来很多麻烦和不必要的损失。因此,在这篇文章中…

华为OD机试(1-20)老题库解析Java源码系列连载ing

华为OD机试算法题新老题库练习及源码 老题库1.敏感字段加密2.IPv4地址转换成整数3.VLAN资源池4. 求字符串中所有整数的最小和5.求满足条件的最长子串的长度6.字符串分割7.一种字符串压缩表示的解压8.矩阵最大值9.单词接龙10.找出符合要求的字符串子串11.字符串加密12.英文输入法…

指定目标对角线创建值全是1的下三角矩阵numpy.diagflat()方法

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 指定目标对角线 偏离主对角线的距离k 创建值全是1的下三角矩阵 numpy.tri() 选择题 关于以下代码说法错误的一项是? import numpy as np print("【执行】a np.tri(3, 3, 0, dtypeint)…

三十二、VPN技术概述——GRE、IPSec、MPLS vpn

文章目录 vpn 简介用途优缺 一、GRE-VPN1、基础配置步骤:2、可选配置 二、IPSEC-VPN 概述1、IPSes 特性2、IPSec 架构3、IPSec 数据封装 三、GRE OVER IPSEC VPN 配置1、配置2、注意 vpn 简介 vpn:virtual private network(虚拟专用网络&…