MySQLMySQL知识总结

Posted 快乐的威猛先生

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQLMySQL知识总结相关的知识,希望对你有一定的参考价值。

mysql

MySQL

前言

数据库概念

数据库就是按照数据结构来组织、存储和管理数据,建立在计算存储设备上的仓库。可以看成是电子化的文件柜,也就是存储电子 文件的处所,用户可以对文件中的数据进行进行新增、查询、更新、删除等操作。

为什么要使用数据库?

随着,应用程序的功能越来越复杂,数据量越来越大,如何管理这些数据就成了一个 大问题。

  • 读写文件的并解析出数据需要大量重复代码
  • 从成千上万的数据中快速查询出指定数据需要复杂的逻辑
  • 数据缺乏安全感

如果每个应用程序都各自写自己的读写数据代码,一方面效率低,容易出错,另一方面,每个应用程序访问数据的接口都不同,数据难以复用。

所以

数据库作为一种转门管理数据的软件就出现了。应用程序不需要自己管理数据,而是通过数据库软件提供的接口来读写数据。至于数据本身如何存储到文件,那是数据库软件的事情, 应用程序自己并不关心。

这样一来,编写应用程序的时候,数据读写的功能就被大大地简化了。

MySql简介

MySql作为一种开源的轻量级数据库(关系型数据库),在开源数据库中比较流行,由于小巧安装方便快捷,经常会用于互联网公司, 维护也比较方便。因为开源,使用上比较灵活,mysql还有许多第三方的存储引擎,可以根据自己的需要安装。在功能上mysql可能没有oracle强大,但是对于资源的占用非常少,数据恢复快。在维护上,追求稳定的是性能和易用性。

选择数据库时,既要考虑成本,还要考虑维护的稳定性和便利性, 需要 结合我们的业务,如果提高安全性,海量数据,能承担高昂的成本,可以选择oracle, 一般应用的快速查询,高并发访问,一般情况下都可以选择mysql,另外特殊情况特殊处理。

优势

  1. 开源
  2. 成本低
  3. 快平台性
  4. 容易使用

数据库操作

关系模型

关系数据库是建立在关系模型上的。而关系模型本质上就是若干个存储数据的二维表,可以吧他们看作很多Excel表。

例如:

表的每一行称为记录(Record),记录是一个逻辑上的数据。

表的每一列称为字段(Column),同一个表的每一刚记录都拥有相同的若干字段。

字段定义了数据类型(整型、浮点型、字符串、日期等),以及是否允许为NULL。注意NULL表示字段数据不存在。一个整型字段如果为NULL不表示它的值为0,同样的,一个字符串型字段为NULL也不表示它的值为空串’’。

通常情况下,字段应该避免允许为NULL。不允许为NULL可以简化查询条件,加快查询速度,也利于应用程序读取数据后无需判断是否为NULL。

和Excel表有所不同的是,关系数据库的表和表之间需要建立“一对多”,“多对一”和“一对一”的关系,这样才能够按照应用程序的逻辑来组织和存储数据。

每一行对应着一个班级,而一个班级对应着多个学生,所以班级表和学生表的关系就是“一对多”:

反过来,如果我们先在学生表中定位了一行记录,例如ID=1的小花,要确定他的班级,只需要根据他的“班级ID”对应的值101找到班级表中ID=101的记录,即六年级一班。所以,学生表和班级表是“多对一”的关系。

如果我们把班级表分拆得细一点,例如,单独创建一个教师表:

查看数据库

像文件一样,数据库也能进行如下操作。

(windows下不区分大小写**,**Linux下区分大小写。)

注意结尾的分号;(就像写C/C++一样)


  1. 创建数据库
  2. 查看数据库
  3. 选择数据库
  4. 删除数据库

在创建数据库之前,可以使用SHOW语句来显示当前已经存在的数据库,如下:

SHOW DATABASES;

因为数据库本身的需要,所以它默认自带了几个库。不要随意删除,否则可能会无法正常运行数据库。

创建数据库

创建数据库是指在数据库系统中划分一块空间,用来存储相应的数据,这是进行表操作的基础,也是进行数据库管理的基础。

CREATE DATABASE database_name(数据库的名字);

例如

再SHOW

选择数据库

在对数据库进行操作之前,应该先选择一个数据库。

USE database_name(要记性操作的数据库名字); 

要选择已存在的库,否则会报错。

删除数据库

DROP DATABASE database_name;

要删除已有的数据库, 否则会报错。

成功删除提示。

数据库命名规范

可以采用26个英文字母 (不区分大小写) 和0-9的自然数 (一般不需要) 加上下划线 _ 组成,命名简介明确 (Student_Age),多个单词用下划线 ‘_’ 分隔,一个项目一个数据库,多个项目慎用同一个数据库!!!

数据表的操作

表是一种很重要的数据库对象,是组成数据库的基本元素,由若干个字段组成,主要用来实现存储数据记录。表的操作包含创建表、查询表、修改表和删除表,这些操作是数据库对象的表管理中最基本也是最重要的操作。

创建一个班级表

mysql> create database school;   #创建数据库school

mysql> use school;   #选择数据库school 
mysql> create table class(class_id int, class_name varchar(128), class_teacher varchar(64));         #创建表class
mysql> insert into class values (101, '六年级一班', '马老师');  #往表中插入101班记录
mysql>insert into class values (102, '六年级二班', '潘老师');   #往表中插入102班记录
mysql>select * from class;  #查询表class 中的全部记录
mysql>select * from class where class_id=101;  #查询表class 中的全部记录


补充:mysql中字符串用单引号括起来。


表的创建

CREATE TABLE 表名([表定义选项])[表选项][分区选择];

其中[表定义选项]格式为:

<列名1> <类型1> […] <列名n> <类型n>

CREATE TABLE 命令语法比较多,其主要是由

表创建定义(create-definition)、

表选项(table-options)和

分区选项(partition-options)所组成的。

- CREATE TABLE:用于创建给定名称的表,必须拥有表CREATE的权限。

有些数据库可以使用加引号的识别名,例如,‘mydb’.‘mytbl’ 是合法的,但 mysql 是不合法。

表的创建有两种方式

1.选择选择数据库,然后按照上面方式创建表。

2.不选择先选择数据库,以db_name.tbl_name的方式创建,例如

create table school.class2(class_id int, class_name varchar(128), class_teacher varchar(64));  

<表定义选项>:表创建定义,由列名(col_name)、列的定义(column_definition, 或者叫类型定义)以及可能的空值说明、完整性约束或表索引组成。

mysql> use school;  #选择数据库school 
mysql> create table class4(class_id int PRIMARY KEY, class_namevarchar(128) NOT NULL, class_teacher varchar(64) UNIQUE);#创建表class3 

# UNIQUE 唯一限定-不能重复

注意

默认的情况是,表被创建到当前的数据库中。若表已存在、没有当前数据库或者数据库不存在,则会出现错误。

提示:使用 CREATE TABLE 创建表时,必须注意以下信息:

- 要创建的表的名称不区分大小写,不能使用SQL语言中的关键字,如DROP、ALTER、INSERT等。

- 数据表中每个列(字段)的名称和数据类型,如果创建多个列,要用逗号隔开。

列名

1)采用26字母和0-9的自然数加上下互相 ‘’ 组成,命名简洁明确,多个单词用下划线 ‘’_ 隔开。

2)全部小写命名,尽量避免出现大写

3)字段必须填写描述信息

4)禁止使用数据库关键字

5)字段名称一般采用名词或动宾短语

6)采用字段的名字必须是易于理解,一般不超过三个英文单词

7)在命名表的列时,不要重复表的名称(如:在 user 表中,出现 user_name 字段)

8)字段命名使用完整名称

列的类型定义

整型类型

整数类型是数据库中最基本的数据类型。标准SQL中支持INTEGER和SMALLINT这两种数据类型。MySQL数据库除了支持这两种类型以外,还扩展支持了TINYINT、MEDIUMINT和BIGINT。下表从不同整数类型的字节数、取值范围等方面进行对比。

整数类型的附带属性

(1)类型名后面的小括号

指定显示宽度 (并不是该类型占用的字节数)。如果不显式指定宽度,则默认为:

tinyint(3)、 smallint(5)、 mediumint(8)、 int(11) 和 bigint(20)。

一般配合zerofill使用,顾名思义,zerofill就是用‘0’填充的意思,也就是在数字位不够的空间用字符“0”填满。

create table class2(id,int(8) zerofill,name varchar(128),teacher varchar(64));

效果如下:

​ 超过显示位数则不会补零

(2)UNSIGNED(无符号)

如果需要在字段里面保存非负数或者需要较大的上限值时,可以用此选项,它的取值范围是正常值的下限取 0,上限取原值的 2 倍,例如,tinyint 有符号范围是-128~+127,而无符号范围是 0~255。如果一个列指定为 zerofill,则 MySQL 自动为该列添加 UNSIGNED 属性。

create table class2(id int unsigned,name varchar(128),teacher varchar(64));

添加一个zerofill属性。

(3)AUTO_INCREMENT

在需要产生唯一标识符或顺序值时,可利用此属性,这个属性只用于整数类型。AUTO_INCREMENT 值一般从 1 开始,每行增加 1。 一个表中最多只能有一个 AUTO_INCREMENT列 。对于任何想要使用 AUTO_INCREMENT 的列,应该定义为 NOT NULL,并定义为 PRIMARY KEY 或定义为 UNIQUE 键(不能有重复的)。 例如,可按下列任何一种方式定义 AUTO_INCREMENT 列:

mysql> create table class8(id integer auto_increment PRIMARY KEY , name varchar(128), teacher varchar(64) );         #创建表class8, id 具有自增长属性

mysql> create table class9(id integer auto_increment UNIQUE , name varchar(128), teacher varchar(64) );         	#创建表class9, id 具有自增长属性

设置的类型可以不指定值,但要在value前进行一个声明,声明一下哪个需要手动设定。

插入的第一个元素如果不指定的话就从1开始,指定的话,后面的元素不指定,就前一个的基础上+1。

如下图所示。

浮点类型和定点数类型

数据表中用浮点数类型和定点数类型来表示小数。浮点数类型包括单精度浮点数(FLOAT型)和双精度浮点数(DOUBLE型)。定点数类型就是DECIMAL型。下面从这三种类型的字节数、取值范围等方面进行对比,如下表所示。

三种类型的区别
float是单精度浮点型,double是双精度浮点型,decimal是定点型。

mysql> create table class10 (f1 float, do1 double, de1 decimal);  #创建表class10


MySQL 浮点型和定点型可以用类型名称后加**(M,D)**来表示,M表示该值的总共长度,D表示小数点后面的长度,M和D又称为精度和标度,如float(7,4)的 可显示为-999.9999,MySQL保存值时进行四舍五入(当数的长度超过所设置精度),如果插入999.00009,则结果为999.0001。

对于decimal,M是最大位数(精度),范围是1到65。可不指定,默认值是10。D是小数点右边的位数(小数位)。范围是0到30,并且不能大于M,可不指定,默认值是0

FLOAT和DOUBLE在不指定精度时,默认会按照实际的精度来显示,而DECIMAL在不指定精度时,默认整数为10,小数为0,即(10, 0)。


注意

当我们需要存储小数,并且有精度要求,比如存储金额时,通常会考虑使用DECIMAL字段类型!!!

日期和时间类型

日期与时间类型是为了方便在数据库中存储日期和时间而设计的,数据库有多种表示日期和时间的数据类型。其中,YEAR类型表示年,DATE类型表示日期,TIME类型表示时间,DATETIME和TIMESTAMP表示日期和时间。下面从这5种日期与时间类型的字节数、取值范围和零值等方面进行对比,如下表所示。

每种日期与时间类型都有一个有效范围。如果插入的值超过了这个范围,系统就会报错,并将零值插入到数据库中。不同的日期与时间类型均有不同的零值.

插入日期时间时,日期年月日和时间时分秒可以使用 “****: - _ /**** ”中的任意字符来分隔,如果单独插入时间,则会报错!!!

mysql> create table test(e_data date,e_datatime datetime,e_timestamp timestamp,e_time time,e_year year)

mysql> insert into test value('2021-10-25','2021-10-25 9:13:00','2021-10-25 9:13:00','9:13:00','2021');


常用的时间函数

CURDATE() - 获得当前的DATE, 可直接插入DATE 类型中.

NOW() - 获得当前的DATETIME, 可直接插入DATETIME 和TIMESTAMP类型中.

TIME() - 获取参数给定时间串中的时分秒,可直接插入TIME 类型中.

YEAR() - 获取参数给定时间串中的年份,可直接插入YEAR类型中.

MONTH() 、DAY()、HOUR()、MINUTE()、SECOND() 获取参数给定时间串中的月、日、时、分、秒值.


mysql> insert into date_example values(CURDATE(), NOW(), NOW(), time(NOW()), YEAR(NOW()) );
字符串类型
CHAR类型和VARCHAR类型

CHAR类型和VARCHAR类型都在创建表时指定了最大长度,其基本形式如下:

字符串类型(M)

其中,“字符串类型”参数指定了数据类型为CHAR类型还是VARCHAR类型;M参数指定了该字符串的最大长度为M。例如,CHAR(4)就是数据类型为CHAR类型,其最大长度为4。

CHAR类型的长度是固定的,在创建表时就指定了。其长度可以是0~255的任意值。例如,CHAR(100)就是指定CHAR类型的长度为100。CHAR 存储值时,它们会用空格右填充到指定的长度。

VARCHAR类型的长度是可变的,在创建表时指定了最大长度。定义时,其最大值可以取0~65535之间的任意值。指定VARCHAR类型的最大值以后,其长度可以在0到最大长度之间。例如,VARCHAR(100)的最大长度是100,但是不是每条记录都要占用100个字节,而是在这个最大值范围内使用多少就分配多少。VARCHAR类型实际占用的空间为字符串的实际长度加1或2,这样即可有效节约系统的空间。

mysql> use test;   #选择数据库test 
mysql> create table char_example(e_char char(5), v_char varchar(5)); #创建数据库表
mysql> insert into char_example values('12345','12345');  #正常插入数据
mysql> insert into char_example values('1 2  ','1 2  ');   #char类型会屏蔽后面隐藏的空格,varchar 不会
mysql>select concat('(',e_char, ')'), concat('(',v_char, ')')  from char_example ; #让char 后面屏蔽的空格原型毕露 

使用建议

  1. char一定会使用指定的空间,varchar是根据数据来定空间。
  2. char的数据查询效率比varchar高:varchar是需要通过后面的记录数来计算。
  3. 如果确定数据一定是占指定长度,那么使用char类型。
  4. 如果不确定数据到底有多少,那么使用varchar类型。
  5. 如果数据长度超过255个字符而在65535之内,直接使用varchar。
  6. 如果字符串尾部要保留空格,必须选择varchar。
TEXT类型

TEXT类型是一种特殊的字符串类型,包括TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT,其长度和存储空间的对比下表所示:

各种TEXT类型的区别在于允许的长度和存储空间不同。因此,在这几种TEXT类型中,根据需求选取既能满足需要又节省空间的类型即可。

注意

  1. 以上各类型无须指定长度
  2. 允许的长度是指实际存储的字节数,而不是实际的字符个数,比如假设一个中文字符占两个字节,那么TEXT 类型可存储65535/2 = 32767个中文字符,而varchar(100)可存储100个中文字符,实际占200个字节,但varchar(65535) 并不能存储65535个中文字符,因为已超出表达范围。

使用建议

  1. char长度固定,即每条数据占用等长字节空间,适合用在身份证号码、手机号码等。超过255字节的只能用varchar或者text。
  2. varchar可变长度,可以设置最大长度,适合用在长度可变的属性。
  3. text不设置长度,当不知道属性的最大长度来时,适合用text,能用varchar的地方不用text;
  4. 如果都可以选择,按照查询速度,char最快varchar次之text最慢。(跟数据库的设计有关,不同的类型有不同的特性。实现不用的功能都是有代价的。)
字符串类型选择练习

创建一个用户信息表,用来存储用户的如下信息:姓名,手机号码,家庭地址,个人简介,性别,年龄,身份证号。数据库表名可定义为userinfo, 同时增加一个列id 用来作为每一条记录的唯一标识,并设为主键,自加!

mysql> create table userinfo (
 id int(11) unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT ‘主键’,
 name   varchar(64) DEFAULT NULL COMMENT ‘姓名’,
 mobile  char(11)  DEFAULT NULL COMMENT ‘手机号码’,
 address varchar(128) DEFAULT NULL COMMENT ‘居住地址’,
 description text  DEFAULT NULL COMMENT ‘个人简介-不知道具体的范围,不常更新用text’,
 sex     char(1)  DEFAULT NULL COMMENT ‘性别 - 男或女’,
 age     tinyint unsigned DEFAULT 0 COMMENT ‘年龄’,
 idno    char(18) DEFAULT NULL COMENT ‘身份证号码’
);   


设计数据库内容的时候就想好它的使用场景


ENUM和SET类型

ENUM类型

ENUM类型又称为枚举类型。在创建表时,ENUM类型的取值范围以列表的形式指定,其基本形式如下:

属性名 ENUM(‘值1’, ‘值2’, …, ‘值n’)

其中,“属性名”参数指字段的名称,“值n”参数表示列表中的第n个值。ENUM类型的值只能取列表中的一个元素。其取值列表中最多能有65535个值。如果数据值列表在255个以内,那么一个字节就够,如果超过255但是小于65535,那么系统采用两个字节保存。列表中的每个值独有一个顺序排列的编号,MySQL中存入的是这个编号,而不是列表中的值。默认编号从1开始!

Enum(‘男’,’女’,‘选择保密’) # ‘男’=>1 ‘女’=>2 ‘选择保密’=> 3

mysql> use test;   #选择数据库test 
mysql> create table enum_example (e_enum enum('男','女','选择保密') ); #创建表 
mysql> insert into enum_example values('男');  #插入记录,必须是enum 选项中的值
mysql> insert into enum_example values(1);  #插入记录可以用数值表示
mysql>select e_enum + 0  from enum_example; #查询enum 选项对应的整数值(是当前表中已经存的内容,对应enum类型中的数值)

如果ENUM类型加上了NOT NULL属性,其默认值为取值列表的第一个元素。如果不加NOT NULL属性,ENUM类型将允许插入NULL,而且NULL为默认值。


SET类型

在创建表时,SET类型的取值范围就以列表的形式指定了,其基本形式如下:

属性名 SET(‘值1’, ‘值2’, …, ‘值n’)

其中,属性名参数指字段的名称,“值n”参数表示列表中的第n个值,这些值末尾的空格将会被系统直接删除。其基本形式与ENUM类型一样。SET类型的值可以取列表中的一个元素或者多个元素的组合。取多个元素时,不同元素之间用逗号隔开。SET类型的值最多只能是由64个元素构成的组合。

mysql> use test;   #选择数据库test 
mysql> create table set_example (interest set('足球','追剧','篮球','撩妹') ); #创建表 
mysql> insert into set_example values( '足球,撩妹' ); #插入记录,必须是enum 选项中的值
mysql> insert into enum_example values(9);  #插入相应位效果等同,9 =>1001 选择1,4
mysql>select interest+0 from set_example;  #以整数的方式查询

注意:对应二进制位计算的顺序是反过来的。

例:
选足球,其他的不选

足球 追剧 篮球 撩妹

1 0 0 0

与正常顺序的二进制不同,正常算结果为8

在mysql的顺序计算就是1,反过来了。


二进制类型

二级制数据和文本数据在mysql中的最大差距在于:

  • 二进制类型存储原始的二进制数据(如图片,视频,exe文件等)。文本类型(TEXT)用来存储字符字符串(如由英文字符、中文字符或其它语言字符组成的字符串)。
  • 二进制类型没有字符集,并且排序和比较基于列值字节的数值。而TEXT类型有字符集,并且根据字符集的校对规则对值进行排序和比较。

二进制类型是存储二进制数据的数据类型,包括BINARY、VARBINARY、BIT、TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB。二进制类型之间的对比如下表所示。

BINARY和VARBINARY

BINARY类型和VARBINARY类型都是在创建表时指定最大长度,其基本形式如下:
类型M

其中,“字符串类型”参数指定数据类型为BINARY类型还是VARBINARY类型;M参数指定该二进制数的最大字节长度为M。这与CHAR类型和VARCHAR类型相似。例如,BINARY(10)就是指数据类型为BINARY类型,其最大长度为10。

BINARY类型的长度是固定的,在创建表时就指定了,不足最大长度的空间由″\\0″补全。例如,BINARY(50)就是指定BINARY类型的长度为50。

VARBINARY类型的长度是可变的,在创建表时指定了最大的长度,其长度可以在0到最大长度之间,在这个最大值范围内使用多少就分配多少。

例如
都存ab


BIT类型

BIT类型在创建表时指定最大长度,其基本形式如下:
BIT(M)

其中,“M”指定该二进制数的最大存储长度为M,M的最大值为64。例如,BIT(4)就是指数据类型为BIT类型,长度为4。若字段的类型BIT(4)存储的数据是0~15,因为变成二进制之后15的值为1111,则其长度为4。如果插入的值为16,其二进制数为10000,长度为5,超过了最大长度,因此大于16的数是不能插入BIT(4)类型字段中的。

注意

  • 插入数据时,使用 b‘位串’的方式插入相应值!
  • 查询时,可以使用 bin() 、oct() 、hex() 函数讲字段的值转成相应的二进制、八进制和十六进制。

(二进制位串高位0会省略)


BLOB类型

  1. 以上各类型无需指定长度。
  2. 允许的长度是指实际存储的字节数,不用考虑字符编码。

使用建议

  1. binary长度固定,即每条数据占用等长字节空间;保存长度不超过255字节的二进制数据。
  2. varbinary可变长度,可以设置最大长度,最大长度65535;适合用在长度可变的二进制数据。
  3. blob不设置长度, 当不知道属性的最大长度时,适合用blob, 能用varbinary的地方不用blob。
  4. 如果都可以选择,按照查询速度: binary最快varbinary次之blob最慢
其他数据类型

JASON类型

SPATIAL数据类型

(略)

列的完整性约束

完整性约束条件是对字段进行限制,要求用户对该属性进行的操作符合特定的要去,如果不满足完整性约束条件,数据库系统将不再执行用户的操作。下表为完整性约束条件。

设置表字段的主键约束(PRIMARY KEY,PK)

主键是表的一个特殊字段,能唯一标识该表中的每条信息。主键和记录的关系,如同身份证和人的关系。主键用来标识每个记录,每个记录的主键值都不同。身份证用来表明人的身份,每个人都具有唯一的身份证号。设置表的主键是指在创建表时设置表的某个字段为该表的主键。

主键的主要目的是帮助数据库管理系统以最快的速度查找到表的某一条信息。主键必须满足的条件就是主键必须是唯一的,表中任意两条记录的主键字段的值不能相同,并且是非空值。主键可以是单一的字段,也可以是多个字段的组合。


主键是唯一的


单字段主键
单字段主键的语法规则如下:
CREATE TABLE tablename(
    propName propType PRIMARY KEY, ......
);
或
CREATE TABLE tablename(
    propName propType , ......
PRIMARY KEY(propType)
);
mysql> create database school;   #创建数据库school
mysql> use school;   #选择数据库school 
mysql> create table class(id int PRIMARY KEY, name varchar(128), teacher varchar(64));         #创建表class
mysql> desc class ;  #查询表class 的定义, describe class 效果等同
mysql> show create table class ;  #同样可以实现查询表class 的定义
mysql> insert into class VALUES(1,'一班','s1');  #插入成功
mysql> insert into class VALUES(1,'二班','s2');  #因主键约束,插入失败

MySQL支持给主键设置名字

CREATE TABLE tablename(
    propName propType , ......
CONSTRAINT pk_name PRIMARY KEY(propType)
);
多字节主键

主键是由多个属性组合而成时,在属性定义完之后统一设置主键。语法规则如下:

CREATE TABLE tablename(  
    propName1 propType , 
    propName2 propType , 
    ......                     
[CONSTRAINT pk_name]PRIMARY KEY(propName1, propName2)
);

例如:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3oM0bThT-1640525294346)(MySql.assets/image-20211026143246285.png)]

mysql> create table class3(id int, name varchar(128), teacher varchar(64), CONSTRAINT id_pk PRIMARY KEY(id, name));         #创建表class3,设置联合主键
mysql> insert into class VALUES(1,'一班','S1');  #插入成功
mysql> insert into class VALUES(1,'一班','S2');    #因联合主键约束,插入失败
设置表字段的外键约束(FORENIGN KEY,FK)

(就是外部的约束)

外键是表的一个特殊字段,外键约束是为了保证多个表(通常为两个表)之间的参照完整性,即构建两个表的字段之间的参照关系。

设置外键约束的两个表之间具有父子关系,即子表中某个字段的取值范围由父表决定。例如,表示一个班级和学生关系,即每个班级有多个学生。首先应该有两个表:班级表和学生表,然后学生表有一个表示班级编号的字段no,其依赖于班级表的主键,这样字段no就是学生表的外键,通过该字段班级表和学生表建立了关系。

在具体设置外键约束时,设置外键约束的字段必须依赖于数据库中已经存在的父表的主键,同时外键可以为空(NULL)。

设置表中某字段的外键约束非常简单,可以在MySQL数据库管理系统中通过SQL语句FOREIGN KEY来实现,其语法形式如下:

CREATE TABLE tablename_1(  
    propName1 propType , 
    propName2 propType , 
    ......                     
[CONSTRAINT fk_name]FOREIGN KEY(propName1) REFERENCES table2_name(table2_column)
);

例如:学生表的外键(班级id字段)依赖于父类班级表的主键(id),插入的学生信息班级id必须是父类班级表主键中有的。否则就会插入失败。


并且外键是可以为空的,不为空一定要受父类表主键的约束。(父类表一定要有主键,否则不能为子类表创建外键。)


设置列的非空约束(NOT NULL,NK)

当数据库表中的某个字段上的内容不希望设置为NULL时,可以使用NK约束进行设置。NK约束在创建数据库表时为某些字段上加上“NOT NULL”约束条件,保证所有记录中的该字段都有值。如果在用户插入的记录中该字段为空值,那么数据库管理系统会报错。

设置表中某字段的NK约束非常简单,查看帮助文档可以发现,在MySQL数据库管理系统中是通过SQL语句NOT NULL来实现的,其语法形式如下:

CREATE TABLE tablename(
    propName propType NOT NULL , ......
);
mysql> create database school;   #创建数据库school
mysql> use school;   #选择数据库school 
mysql> create table class(id int, name varchar(128) NOT NULL, teacher varchar(64));         #创建表class
mysql> desc class ;  #查询表class 的定义, describe class 效果等同 
mysql> show create table class ;  #同样可以实现查询表class 的定义

这个NULL的YES or NO,意思是是否可以为空。(可以为空也就是没有设置非空约束)

设置表字段唯一约束(UNIQUE,UK)

当数据库表中某个字段上的内容不允许重复时,可以使用UK约束进行设置。UK约束在创建数据库时为某些字段加上“UNIQUE”约束条件,保证所有记录中该字段上的值不重复。如果在用户插入的记录中该字段上的值与其他记录中该字段上的值重复,那么数据库管理系统会报错。

设置表中某字段的UK约束非常简单,可以在MySQL数据库管理系统中通过SQL语句UNIQUE来实现,其语法形式如下:

(该列被设为主键了,就没必要再设置UNIQUE了,因为主键就是不可重复,为了区分表中的每一行数据。)

CREATE TABLE tablename(
    propName propType UNIQUE, ......
);

unique 约束允许约束的字段出现多个空值NULL,不算重复。(mysql8.0)

mysql> create table class(id int, name varchar(128) UNIQUE, teacher varchar(64));         #创建表class
设置表字段值自动增加(AUTO_INCREMENT)

AUTO_INCREMENT是MySQL唯一扩展的完整性约束,当向数据库表中插入新记录时,字段上的值会自动生成唯一的ID。在具体设置AUTO_INCREMENT约束时,一个数据库表中只能有一个字段使用该约束该字段的数据类型必须是整数类型。由于设置AUTO_INCREMENT约束后的字段会生成唯一的ID,因此该字段也经常会同时设置成PK主键。

设置表中某字段值的自动增加约束非常简单,可以在MySQL数据库管理系统中通过SQL语句AUTO_INCREMENT来实现,其语法形式如下:

CREATE TABLE tablename(
    propName propType AUTO_INCREMENT, ......
);

在上述语句中,tablename参数表示所要设置非空约束的字段名字,propName参数为属性名,propType为属性类型,propName字段要设置自动增加约束。默认情况下,字段propName的值从1开始增加,每增加一条记录,记录中该字段的值就会在前一条记录(或已存在的最大值(包括曾经存在的))的基础上加1


(自增的列类型,需要被设置成主键。)如下图所示:


mysql> create table class(id int PRIMARY KEY AUTO_INCREMENT, name varchar(128) UNIQUE, teacher varchar(64));         #创建表class,设置字段id为自增长


默认是在上一个的数据的基础上+1


注意:mysql8中,AUTO_INCREMENT必须设为键(主键、外键和唯一键),否则会报错。


小细节:受外键约束的一个列设置为自增,其实是没用的,无法根据外键限制自己增加,就是没用。


设置表字段的默认值(DEFAULT)

当为数据库表中插入一条新记录时,如果没有为某个字段赋值,数据库系统就会自动为这个字段插入默认值。为了达到这种效果,可通过SQL语句关键字DEFAULT来设置。

设置数据库表中某字段的默认值非常简单,可以在MySQL数据库管理系统中通过SQL语句DEFAULT来实现,其语法形式如下:

CREATE TABLE tablename(
    propName propType DEFAULT defaultvalue, ......
);

如果没有设置,则默认为空。

调整列的完整性约束
修改主键PK、外键FK和 唯一键UK

新增

alter table [table_name] add constraint [constraint_name] [unique key| primary key|foreign key] ([column_name])

删除

  1. 通过如下命令查询键值的约束名:

    show index或keys from 表名;     
    
  2. 执行如下命令删除

主键: alter table 表名 drop primary key; (主键只有一个。直接通过限制名删除)

外键或唯一键:alter table 表名 drop index 约束名;


修改:先删除再新增。


修改默认值DEFAULT、自增长和非空NK
alter table 表名 modify 列名 类定义;

表索引

索引概述

帮助我们快速找到想要的内容。

索引是一种特殊的数据库结构,可以用来快速查询数据库表中的特定记录,是提高数据库性能的重要方式。MySQL中,所有的数据类型都可以被索引。

通过索引,查询数据时可以不必读完记录的所有信息,而只是查询索引列,否则数据库系统将读取每条记录的所有信息进行匹配。。使用索引可以在很大程度上提高数据库的查询速度,有效地提高了数据库系统的性能。

索引类型
  • 普通索引
  • 唯一性索引
  • 全文索引
  • 单列索引
  • 空间索引
索引存储

数据库底层索引实现主要有两种存储类型,B树(BTREE)和哈希(HASH)索引,InnoDB和MyISAM 使用BTREE索引;而MEMORY 存储引擎可以使用BTREE 和HASH 索引,默认用BTREE.在没有指定的情况下,数据库使用的引擎是 InnoDB。

索引优点

可以提高检索数据的速度。

索引缺点

创建和维护索引需要耗费时间,耗费时间的数量随着数据量的增加而增加;索引需要占用物理空间,每一个索引要占一定的物理空间;增加、删除和修改数据时,要动态地维护索引,造成数据的维护速度降低了。

注意

索引可以提高查询的速度,但是会影响插入记录的速度,因为向有索引的表中插入记录时,数据库系统会按照索引进行排序,这样就降低了插入记录的速度,插入大量记录时的速度影响更加明显。这种情况下,最好的办法是先删除表中的索引,然后插入数据,插入完成后再创建索引。

创建和查看索引

创建索引是指在某个表的一列或多列上建立一个索引,以便提高对表的访问速度。创建索引有3种方式,分别是创建表的时候创建索引、在已经存在的表上创建索引和使用ALTER TABLE语句来创建索引。

普通索引

就是在创建索引的时候不附加任何限制条件(唯一、非空等限制),给类型的索引可以创建在任何数据类型的字段上。

创建表时定义索引:

CREATE TABLE tablename(
    propname1 type1,
    propname2 type2,
    ……
    propnamen type..n,
     INDEX | KEY
    [indexname] (propnamen [(length)] [ ASC | DESC ] ) );

其中,参数INDEX和KEY是用来指定字段为索引的,两者选择其中之一就可以了,作用是一样的;

参数indexname是索引名字,可省略;

参数propnamen是索引对应的字段的名称,该字段必须为前面定义好的字段;

参数length是可选参数,其指索引的长度,必须是字符串类型才可以使用;

参数ASC和DESC都是可选参数,ASC表示升序排列,DESC表示降序排列,如果不指定,则为升序。

代码示例:

mysql> create database school;   #创建数据库school  
mysql> use school;   #选择数据库school  
mysql> create table class(id int, name varchar(128) UNIQUE, teacher varchar(64), INDEX index_no(id DESC));       #创建表class, 并建立为id 字段索引  
mysql> show create table class;  #查看表结构 
mysql> insert into class values(1, '一班', 'Martin');  # 插入记录1 
mysql> insert into class values(1, '二班', 'Rock');   # 插入记录2 
mysql> select * from class where id > 0 ;   #根据id查询记录,结果将降序排列  

或者,在已存在的表上面创建索引。

ALTER TABLE tablename ADD INDEX | KEY indexname  
     (propname [(length)] [ASC|DESC]);  

例如

alter table class1 add index index_id(id DESC);
查询索引执行情况

EXPLAIN 查询语句

在上述语句中,参数tablename是需要创建索引的表;关键字IDNEX或KEY用来指定创建普通索引;参数indexname用来指定所创建的索引名;参数propname用来指定索引所关联的字段的名称;参数length用来指定索引的长度;参数ASC用来指定升序排序;参数DESC用来指定降序排序。

输出结果:
key: 实际使用的索引。如果为NULL,则没有使用索引。

possible_keys:显示可能应用在这张表中的索引,一个或多个。查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询实际使用

key_len:表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度。此值越短越好!

唯一索引

所谓唯一索引,就是在创建索引时,限制索引的字段值必须是唯一的

通过该类型的索引可以比普通索引更快速地查询某条记录。


创建表时定义索引

CREATE TABLE tablename(
    propname1 type1,
    ……
    propnamen type..n,
    UNIQUE INDEX | KEY [indexname] (propnamen [(length)] [ ASC | DESC ] ) );  

示例

create table class(id int,name varchar(128) UNIQUE,teachar varchar(64),UNIQUE INDEX name_index (name(32)));

补充

%为通配符,例如%班。

索引的数据量很小,便于核对查询是否有重复的。

对于已经设置UNIQUE约束的字段,在设置UNIQUE KEY(唯一约束)是多余的。


注意

参数UNIQUE INDEX和UNIQUE KEY是用来指定字段为索引的,两者选择其中之一即可;

参数indexname是索引名字,可省略;

参数propnamen是索引对应的字段的名称,该字段必须为前面定义好的字段且必须定义为 UNIQUE 约束

参数length是可选参数,其指索引的长度,必须是字符串类型才可以使用;

参数ASC和DESC都是可选参数,ASC表示升序排列,DESC表示降序排列,如果不指定,则为升序。

**已存在的表上创建索引 **

方法1

CREATE UNIQUE INDEX indexname  
    ON tablename (propname [(length)] [ASC|DESC]);  

方法2

ALTER TABLE tablename ADD UNIQUE INDEX | KEY indexname (propname [(length)] [ASC|DESC]);  
全文索引

全文索引主要对字符串类型建立基于分词的索引,主要是基于CHAR、VARCHAR和TEXT的字段上,以便能够更加快速地查询数据量较大的字符串类型的字段。

全文索引以词为基础的MySQL默认的分词是所有非字母和数字的特殊符号都是分词符。

MySQL从3.23.23版本开始支持全文索引,MySQL5.6以前只能在存储引擎为MyISAM的数据表上创建全文索引,5.6之后InnoDB开始支持全文索引(5.7之后支持中文全文索引) 。在默认情况下,全文索引的搜索执行方式为不区分大小写,如果全文索引所关联的字段为二进制数据类型,就以区分大小写的搜索方式执行。


创建表时定义索引

CREATE TABLE tablename(
    propname1 type1,
    propname2 type2,
    ……
    propnamen type..n,
    FULLTEXT INDEX | KEY
    [indexname] (propnamen [(length)] ) );

示例

mysql> create database school;   #创建数据库school  
mysql> use school;   #选择数据库school  
mysql>create table class(id int, name varchar(128) UNIQUE, teacher varchar(64),comment varchar(1024),FULLTEXT INDEX index_comm(comment));       #创建表class, 并建立为comment 字段为全文索引  
mysql> insert into class values(1,'1班','Martin','我是一个兵,来自老百姓!');  # 插入记录1 
mysql> insert into class values(2,'2班','Rock','此班主任毕业自唐僧系');   # 插入记录2 
mysql> insert into class values(3,'3班','Janny','I''m Miss Zhang.');   #插入记录3  
mysql> select * from class where match(comment) AGAINST('我是一个兵');#利用全文检索索引快速查询记录

查找:

select* from tablename where match(propnamen)against('内容');

已经存在的表上创建索引

方法1:执行create语句

 CREATE FULLTEXT INDEX indexname
    ON tablename( propname1 [ ( length ) ] ); 
MySQL必知必会语法和基础知识大总结

MySQLMySQL复制与高可用水平扩展架构实战

MySQLMySQL 8 的 JSON 新特性详解JSON 数据类型

Mysql的命令总结

MySQLMySQL的索引结构为什么使用B+树?

mysql总结