• MySQL


    MySQL

    理论知识

    MySQL 是一个关系型数据库

    基本概念

    描述事物的符号称为数据。数据有多种表现形式,可以是数字,也可以是文字、图形、图像、声音、语言等。在数据库中数据表示记录,例如,在学生管理数据库中,记录学生的信息包括学号、姓名、性别、年龄、籍贯和联系电话等,这些信息就是数据

    DBS

    数据库系统(Database System,DBS)由硬件和软件共同构成。硬件主要用于存储数据库中的数据,包括计算机、存储设备等。软件部分主要包括数据库管理系统、支持数据库管理系统运行的操作系统,以及支持多种语言进行应用开发的访问技术等。
    数据库系统主要有以下 3 个组成部分:

    • 数据库:用于存储数据的地方。
    • 数据库管理系统:用于管理数据库的软件。
    • 数据库应用程序:为了提高数据库系统的处理能力所使用的管理数据库库的软件补充。

    DB

    数据库(DataBase,DB)提供了一个存储空间来存储各种数据,可以将数据库视为一个存储数据的容器。一个数据库可能包含许多文件,一个数据库系统中通常包含许多数据库。

    DBMS

    数据库管理系统(DBMS)是数据库系统的核心软件之一,是位于用户与操作系统之间的数据管理软件,用于建立,使用和维护数据库。它的主要功能包括数据定义、数据操作、数据库的运行管理、数据库的建立和维护等几个方面。

    DataBase Application

    数据库应用程序(DataBase Application)的使用可以满足对数据管理的更高要求,还可以使数据管理过程更加直观和友好。数据库应用程序负责与 DBMS 进行通信、访问和管理 DBMS 中存储的数据,允许用户插入、修改、删除数据库中的数据。

    DBA

    • DBA 是数据库管理员(Database Administrator)的简称,是从事管理和维护数据库管理系统(DBMS)的相关工作人员的统称,属于运维工程师的一个分支。
    • DBA 主要负责业务数据库从设计、测试到部署交付的全生命周期管理,它的核心目标是保证数据库管理系统的稳定性、安全性、完整性和高性能。

    SQL

    SQL 是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。与其他程序设计语言(如 C语言、Java 等)不同的是,SQL 由很少的关键字组成,每个 SQL 语句通过一个或多个关键字构成。
    SQL 具有如下优点。

    • 一体化:SQL 集数据定义、数据操作和数据控制于一体,可以完成数据库中的全部工作。
    • 使用方式灵活:SQL 具有两种使用方式,可以直接以命令方式交互使用;也可以嵌入使用,嵌入C、C++、Fortran、COBOL、Java 等语言中使用。
    • 非过程化:只提操作要求,不必描述操作步骤,也不需要导航。使用时只需要告诉计算机“做什么”,而不需要告诉它“怎么做”,存储路径的选择和操作的执行由数据库管理系统自动完成。
    • 语言简洁、语法简单:该语言的语句都是由描述性很强的英语单词组成,而且这些单词的数目不多

    存储特点

    MySQL 为关系型数据库(Relational Database Management System), 这种所谓的"关系型"可以理解为"表格"的概念, 一个关系型数据库由一个或数个表格组成

    数据库术语

    • 数据表: 表是数据的矩阵。在一个数据库中的表看起来像一个简单的电子表格。
    • : 一列(数据元素) 包含了相同类型的数据, 例如邮政编码的数据。
    • :一行(=元组,或记录)是一组相关的数据,例如一条用户订阅的数据。
    • 冗余:存储两倍数据,冗余降低了性能,但提高了数据的安全性。
    • 主键:主键是唯一的。一个数据表中只能包含一个主键。你可以使用主键来查询数据。
    • 外键:外键用于关联两个表。
    • 复合键:复合键(组合键)将多个列作为一个索引键,一般用于复合索引。
    • 索引:使用索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构。类似于书籍的目录。
    • 参照完整性: 参照的完整性要求关系中不允许引用不存在的实体。与实体完整性是关系模型必须满足的完整性约束条件,目的是保证数据的一致性。

    配置文件

    my.ini

    [mysql]
    # 设置mysql客户端默认字符集
    default-character-set=utf8
    [mysqld]
    # 设置3306端口
    port = 3306
    # 设置mysql的安装目录
    basedir=D:Program Files (x86)mysqlmysql-8.0.19-winx64  
    # 设置mysql数据库的数据的存放目录
    datadir= D:Program Files (x86)mysqlmysql-8.0.19-winx64data
    # 允许最大连接数
    max_connections=20
    # 服务端使用的字符集默认为8比特编码的latin1字符集
    character-set-server=utf8
    # 创建新表时将使用的默认存储引擎
    default-storage-engine=INNODB
    # 跳过登录密码验证
    skip-grant-tables
    

    操作命令

    启动mysql

    • oikmkmklnet start mysql
    • net stop mysql

    数据库连接和退出

    • mysql -h 127.0.0.1 -u root -p
      mysql -h localhost -u root -proot。这里的 -p 后面的 root 就是密码。此处特别注意 -p 和密码之间没有空格。如果出现空格,系统将不会把后面的字符串当成密码来对待。
    • exit

    查看版本号

    • 在没登录下mysql -V
    • 登录下status

    SQL语句

    • SQL 是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。与其他程序设计语言(如 C语言、Java 等)不同的是,SQL 由很少的关键字组成,每个 SQL 语句通过一个或多个关键字构成。
    • SQL 具有如下优点。
      • 一体化:SQL 集数据定义、数据操作和数据控制于一体,可以完成数据库中的全部工作。
      • 使用方式灵活:SQL 具有两种使用方式,可以直接以命令方式交互使用;也可以嵌入使用,嵌入C、C++、Fortran、COBOL、Java 等语言中使用。
      • 非过程化:只提操作要求,不必描述操作步骤,也不需要导航。使用时只需要告诉计算机“做什么”,而不需要告诉它“怎么做”,存储路径的选择和操作的执行由数据库管理系统自动完成。
      • 语言简洁、语法简单:该语言的语句都是由描述性很强的英语单词组成,而且这些单词的数目不多。

    1)数据定义语言(Data Definition Language,DDL)

    用来创建或删除数据库以及表等对象,主要包含以下几种命令:

    • DROP:删除数据库和表等对象
    • CREATE:创建数据库和表等对象
    • ALTER:修改数据库和表等对象的结构

    2)数据操作语言(Data Manipulation Language,DML)

    用来变更表中的记录,主要包含以下几种命令:

    • SELECT:查询表中的数据
    • INSERT:向表中插入新数据
    • UPDATE:更新表中的数据
    • DELETE:删除表中的数据

    3)数据查询语言(Data Query Language,DQL)

    用来查询表中的记录,主要包含 SELECT 命令,来查询表中的数据

    4)数据控制语言(Data Control Language,DCL)

    用来确认或者取消对数据库中的数据进行的变更。除此之外,还可以对数据库中的用户设定权限。主要包含以下几种命令:

    • GRANT:赋予用户操作权限
    • REVOKE:取消用户的操作权限
    • COMMIT:确认对数据库中的数据进行的变更
    • ROLLBACK:取消对数据库中的数据进行的变更

    语法规范

    • SQL 语句要以分号;结尾
    • SQL 语句不区分大小写
    • 常数的书写方式是固定的
    • 单词需要用半角空格或者换行来分隔

    数据库操作

    数据库可以看作是一个专门存储数据对象的容器,每一个数据库都有唯一的名称,并且数据库的名称都是有实际意义的,这样就可以清晰的看出每个数据库用来存放什么数据。在 MySQL 数据库中存在系统数据库和自定义数据库,系统数据库是在安装 MySQL 后系统自带的数据库,自定义数据库是由用户定义创建的数据库。

    查看数据库

    SHOW DATABASES [LIKE '数据库名'];

    创建数据库

    CREATE DATABASE [IF NOT EXISTS] <数据库名>
    [[DEFAULT] CHARACTER SET <字符集名>]
    [[DEFAULT] COLLATE <校对规则名>];

    [ ]中的内容是可选的。语法说明如下:

    • <数据库名>:创建数据库的名称。MySQL 的数据存储区将以目录方式表示 MySQL 数据库,因此数据库名称必须符合操作系统的文件夹命名规则,不能以数字开头,尽量要有实际意义。注意在 MySQL 中不区分大小写。
    • IF NOT EXISTS:在创建数据库之前进行判断,只有该数据库目前尚不存在时才能执行操作。此选项可以用来避免数据库已经存在而重复创建的错误。
    • [DEFAULT] CHARACTER SET:指定数据库的字符集。指定字符集的目的是为了避免在数据库中存储的数据出现乱码的情况。如果在创建数据库时不指定字符集,那么就使用系统的默认字符集。
    • [DEFAULT] COLLATE:指定字符集的默认校对规则。

    修改数据库

    ALTER DATABASE [数据库名] {
    [ DEFAULT] CHARACTER SET <字符集名> |
    [ DEFAULT ] COLLATE <校对规则名>}
    语法说明如下:
    ALTER DATA

    • BASE 用于更改数据库的全局特性。
    • 使用 ALTER DATABASE 需要获得数据库 ALTER 权限。
    • 数据库名称可以忽略,此时语句对应于默认数据库。
    • CHARACTER SET 子句用于更改默认的数据库字符集。

    删除数据库

    DROP DATABASE [ IF EXISTS ] <数据库名>

    语法说明如下:

    • <数据库名>:指定要删除的数据库名。
    • IF EXISTS:用于防止当数据库不存在时发生错误。
    • DROP DATABASE:删除数据库中的所有表格并同时删除数据库。使用此语句时要非常小心,以免错误删除。如果要使用 DROP DATABASE,需要获得数据库 DROP 权限。
      注意:MySQL 安装后,系统会自动创建名为 information_schema 和 mysql 的两个系统数据库,系统数据库存放一些和数据库相关的信息,如果删除了这两个数据库,MySQL 将不能正常工作。

    选择数据库

    USE <数据库名>

    查询当前所在库

    select database();

    数据表操作

    数据表是数据库的重要组成部分,每一个数据库都是由若干个数据表组成的。换句话说,没有数据表就无法在数据库中存放数据。

    创建表

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

    [表定义选项]的格式为:

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

    查看表结构

    desc 表名;
    show columns from 表名;
    describe 表名;
    show create table 表名;

    修改表

    ALTER TABLE <表名> [修改选项]

    修改选项的语法格式如下:

    { ADD COLUMN <列名> <类型>
    | CHANGE COLUMN <旧列名> <新列名> <新列类型>
    | ALTER COLUMN <列名> { SET DEFAULT <默认值> | DROP DEFAULT }
    | MODIFY COLUMN <列名> <类型>
    | DROP COLUMN <列名>
    | RENAME TO <新表名>
    | CHARACTER SET <字符集名>
    | COLLATE <校对规则名> }

    修改表名

    MySQL 通过 ALTER TABLE 语句来实现表名的修改,语法规则如下:

    ALTER TABLE <旧表名> RENAME [TO] <新表名>;

    提示:修改表名并不修改表的结构,因此修改名称后的表和修改名称前的表的结构是相同的。用户可以使用 DESC 命令查看修改后的表结构

    修改表字符集

    MySQL 通过 ALTER TABLE 语句来实现表字符集的修改,语法规则如下:

    ALTER TABLE 表名 [DEFAULT] CHARACTER SET <字符集名> [DEFAULT] COLLATE <校对规则名>;

    其中,DEFAULT 为可选参数,使用与否均不影响结果。

    修改字段名称

    ALTER TABLE <表名> CHANGE <旧字段名> <新字段名> <新数据类型>;

    • 旧字段名:指修改前的字段名;
    • 新字段名:指修改后的字段名;
    • 新数据类型:指修改后的数据类型,如果不需要修改字段的数据类型,可以将新数据类型设置成与原来一样,但数据类型不能为空。
    修改字段数据类型

    ALTER TABLE <表名> MODIFY <字段名> <数据类型>

    • 表名:指要修改数据类型的字段所在表的名称;
    • 字段名:指需要修改的字段;
    • 数据类型:指修改后字段的新数据类型。
    删除字段

    ALTER TABLE <表名> DROP <字段名>;

    删除表

    DROP TABLE [IF EXISTS] 表名1 [ ,表名2, 表名3 ...]

    对语法格式的说明如下:

    • 表名1, 表名2, 表名3 ...表示要被删除的数据表的名称。DROP TABLE 可以同时删除多个表,只要将表名依次写在后面,相互之间用逗号隔开即可。
    • IF EXISTS 用于在删除数据表之前判断该表是否存在。如果不加 IF EXISTS,当数据表不存在时 MySQL 将提示错误,中断 SQL 语句的执行;加上 IF EXISTS 后,当数据表不存在时 SQL 语句可以顺利执行,但是会发出警告(warning)。

    两点注意:

    • 用户必须拥有执行 DROP TABLE 命令的权限,否则数据表不会被删除。
    • 表被删除时,用户在该表上的权限不会自动删除。

    数据操作

    MySQL 数据表是由行和列构成的,通常把表的“列”称为字段(Field),把表的“行”称为记录(Record)。随着业务的变化,可能需要在已有的表中添加新的字段。

    MySQL 允许在开头、中间和结尾处添加字段。

    插入

    在末尾添加字段

    一个完整的字段包括字段名、数据类型和约束条件。MySQL 添加字段的语法格式如下:

    ALTER TABLE <表名> ADD <新字段名><数据类型>[约束条件];

    对语法格式的说明如下:

    • <表名> 为数据表的名字;
    • <新字段名> 为所要添加的字段的名字;
    • <数据类型> 为所要添加的字段能存储数据的数据类型;
    • [约束条件] 是可选的,用来对添加的字段进行约束。

    这种语法格式默认在表的最后位置(最后一列的后面)添加新字段。

    在开头添加字段

    MySQL 默认在表的最后位置添加新字段,如果希望在开头位置(第一列的前面)添加新字段,那么可以使用 FIRST 关键字,语法格式如下:

    ALTER TABLE <表名> ADD <新字段名> <数据类型> [约束条件] FIRST;

    FIRST 关键字一般放在语句的末尾。

    在中间位置添加字段
    MySQL 除了允许在表的开头位置和末尾位置添加字段外,还允许在中间位置(指定的字段之后)添加字段,此时需要使用 AFTER 关键字,语法格式如下:

    ALTER TABLE <表名> ADD <新字段名> <数据类型> [约束条件] AFTER <已经存在的字段名>;

    AFTER 的作用是将新字段添加到某个已有字段后面。

    注意,只能在某个已有字段的后面添加新字段,不能在它的前面添加新字段。

    删除

    使用 DELETE 语句从单个表中删除数据,语法格式为:

    DELETE FROM <表名> [WHERE 子句] [ORDER BY 子句] [LIMIT 子句]

    语法说明如下:

    • <表名>:指定要删除数据的表名。
    • ORDER BY 子句:可选项。表示删除时,表中各行将按照子句中指定的顺序进行删除。
    • WHERE 子句:可选项。表示为删除操作限定删除条件,若省略该子句,则代表删除该表中的所有行。
    • LIMIT 子句:可选项。用于告知服务器在控制命令被返回到客户端前被删除行的最大值。

    注意:在不使用 WHERE 条件的时候,将删除所有数据。

    修改

    使用 UPDATE 语句修改单个表,语法格式为:

    UPDATE <表名> SET 字段 1=值 1 [,字段 2=值 2… ] [WHERE 子句 ]
    [ORDER BY 子句] [LIMIT 子句]

    语法说明如下:

    • <表名>:用于指定要更新的表名称。
    • SET 子句:用于指定表中要修改的列名及其列值。其中,每个指定的列值可以是表达式,也可以是该列对应的默认值。如果指定的是默认值,可用关键字 DEFAULT 表示列值。
    • WHERE 子句:可选项。用于限定表中要修改的行。若不指定,则修改表中所有的行。
    • ORDER BY 子句:可选项。用于限定表中的行被修改的次序。
    • LIMIT 子句:可选项。用于限定被修改的行数。

    注意:修改一行数据的多个列值时,SET 子句的每个值用逗号分开即可。

    查询

    SELECT
    {* | <字段列名>}
    [
    FROM <表 1>, <表 2>…
    [WHERE <表达式>
    [GROUP BY
    [HAVING [{ }…]]
    [ORDER BY ]
    [LIMIT[,] ]
    ]
    其中,各条子句的含义如下:

    • {*|<字段列名>}包含星号通配符的字段列表,表示所要查询字段的名称。
    • <表 1>,<表 2>…,表 1 和表 2 表示查询数据的来源,可以是单个或多个。
    • WHERE <表达式>是可选项,如果选择该项,将限定查询数据必须满足该查询条件。
    • GROUP BY< 字段 >,该子句告诉 MySQL 如何显示查询出来的数据,并按照指定的字段分组。
    • [ORDER BY< 字段 >],该子句告诉 MySQL 按什么样的顺序显示查询出来的数据,可以进行的排序有升序(ASC)和降序(DESC),默认情况下是升序。
    • [LIMIT[,]],该子句告诉 MySQL 每次显示查询出来的数据条数。
    查询常量、计算
    • 1)使用*查询表的所有字段
      SELECT 可以使用*查找表中所有字段的数据,语法格式如下:

    SELECT * FROM 表名;

    • 2)查询表中的某一个字段的语法格式为:

    SELECT < 列名 > FROM < 表名 >;

    函数
    别名
    • 为表指定别名的基本语法格式为:

    <表名> [AS] <别名>

    其中各子句的含义如下:

    • <表名>:数据库中存储的数据表的名称。
    • <别名>:查询时指定的表的新名称。
    • AS关键字可以省略,省略后需要将表名和别名用空格隔开。
    • 为字段指定别名
      为字段指定别名的基本语法格式为:

    <字段名> [AS] <别名>

    其中,各子句的语法含义如下:

    • <字段名>:为数据表中字段定义的名称。
    • <字段别名>:字段新的名称。
    • AS关键字可以省略,省略后需要将字段名和别名用空格隔开。
    去重:distinct

    DISTINCT 关键字的语法格式为:

    SELECT DISTINCT <字段名> FROM <表名>;

    查询函数

    单一条件的查询语句
    使用 WHERE 关键字的语法格式如下:

    WHERE 查询条件

    查询条件可以是:

    • 带比较运算符和逻辑运算符的查询条件
    • 带 BETWEEN AND 关键字的查询条件
    • 带 IS NULL 关键字的查询条件
    • 带 IN 关键字的查询条件
    • 带 LIKE 关键字的查询条件
    • 当数据表中有上万条数据时,一次性查询出表中的全部数据会降低数据返回的速度,同时给数据库服务器造成很大的压力。这时就可以用 LIMIT 关键字来限制查询结果返回的条数。

    多条件的查询语句

    在 WHERE 关键词后可以有多个查询条件,这样能够使查询结果更加精确。多个查询条件时用逻辑运算符 AND(&&)、OR(||)或 XOR 隔开。

    • AND:记录满足所有查询条件时,才会被查询出来。
    • OR:记录满足任意一个查询条件时,才会被查询出来。
    • XOR:记录满足其中一个条件,并且不满足另一个条件时,才会被查询出来

    模糊查询
    LIKE 关键字主要用于搜索匹配字段中的指定内容。其语法格式如下:

    [NOT] LIKE '字符串'

    其中:

    • NOT :可选参数,字段中的内容与指定的字符串不匹配时满足条件。
    • 字符串:指定用来匹配的字符串。“字符串”可以是一个很完整的字符串,也可以包含通配符。

    LIKE 关键字支持百分号“%”和下划线“_”通配符。
    通配符是一种特殊语句,主要用来模糊查询。当不知道真正字符或者懒得输入完整名称时,可以使用通配符来代替一个或多个真正的字符。

    • %”是 MySQL 中最常用的通配符,它能代表任何长度的字符串,字符串的长度可以为 0。注意:匹配的字符串必须加单引号或双引号。
    • “_”只能代表单个字符,字符的长度不能为 0。
    • 默认情况下,LIKE 关键字匹配字符的时候是不区分大小写的。如果需要区分大小写,可以加入 BINARY 关键字。
      使用通配符的注意事项和技巧
      下面是使用通配符的一些注意事项:
    • 注意大小写。MySQL 默认是不区分大小写的。如果区分大小写,像“Tom”这样的数据就不能被“t%”所匹配到。
    • 注意尾部空格,尾部空格会干扰通配符的匹配。例如,“T% ”就不能匹配到“Tom”。
    • 注意 NULL。“%”通配符可以到匹配任意字符,但是不能匹配 NULL。也就是说 “%”匹配不到 tb_students_info 数据表中值为 NULL 的记录。

    下面是一些使用通配符要记住的技巧。

    • 不要过度使用通配符,如果其它操作符能达到相同的目的,应该使用其它操作符。因为 MySQL 对通配符的处理一般会比其他操作符花费更长的时间。
    • 在确定使用通配符后,除非绝对有必要,否则不要把它们用在字符串的开始处。把通配符置于搜索模式的开始处,搜索起来是最慢的。
    • 仔细注意通配符的位置。如果放错地方,可能不会返回想要的数据。

    如果查询内容中包含通配符,可以使用“”转义符。

    范围查询 BETWEEN AND
    使用 BETWEEN AND 的基本语法格式如下:

    [NOT] BETWEEN 取值1 AND 取值2

    其中:

    • NOT:可选参数,表示指定范围之外的值。如果字段值不满足指定范围内的值,则这些记录被返回。
    • 取值1:表示范围的起始值。
    • 取值2:表示范围的终止值。

    空值查询
    空值不同于 0,也不同于空字符串。

    如果字段的值是空值,则满足查询条件,该记录将被查询出来。如果字段的值不是空值,则不满足查询条件。

    使用 IS NULL 的基本语法格式如下:

    IS [NOT] NULL

    其中,“NOT”是可选参数,表示字段值不是空值时满足条件。
    注意:IS NULL 是一个整体,不能将 IS 换成“=”。如果将 IS 换成“=”将不能查询出任何结果,数据库系统会出现“Empty set(0.00 sec)”这样的提示。同理,IS NOT NULL 中的 IS NOT 不能换成“!=”或“<>”。

    限制查询结果的条数LIMIT

    LIMIT 是 MySQL 中的一个特殊关键字,用于指定查询结果从哪条记录开始显示,一共显示多少条记录。

    LIMIT 关键字有 3 种使用方式,即指定初始位置、不指定初始位置以及与 OFFSET 组合使用。

    • 指定初始位置
      LIMIT 关键字可以指定查询结果从哪条记录开始显示,显示多少条记录。

    LIMIT 指定初始位置的基本语法格式如下:

    • LIMIT 初始位置,记录数

    其中,“初始位置”表示从哪条记录开始显示;“记录数”表示显示记录的条数。第一条记录的位置是 0,第二条记录的位置是 1。后面的记录依次类推。

    注意:LIMIT 后的两个参数必须都是正整数。

    • 不指定初始位置
      LIMIT 关键字不指定初始位置时,记录从第一条记录开始显示。显示记录的条数由 LIMIT 关键字指定。

    LIMIT 记录数

    拼接:concat()

    函数用于将多个字符串连接成一个字符串,是最重要的mysql函数之一

    concat(str1, str2,...)

    排序:order by

    ORDER BY 关键字主要用来将查询结果中的数据按照一定的顺序进行排序。其语法格式如下:

    ORDER BY <字段名> [ASC|DESC]

    语法说明如下。

    • 字段名:表示需要排序的字段名称,多个字段时用逗号隔开。
    • ASC|DESC:ASC表示字段按升序排序;DESC表示字段按降序排序。其中ASC为默认值。
    • 使用 ORDER BY 关键字应该注意以下几个方面:
    • ORDER BY 关键字后可以跟子查询(关于子查询后面教程会详细讲解,这里了解即可)。
    • 当排序的字段中存在空值时,ORDER BY 会将该空值作为最小值来对待。
    • ORDER BY 指定多个字段进行排序时,MySQL 会按照字段的顺序从左到右依次进行排序。
    分组:group by

    使用 GROUP BY 关键字的语法格式如下:

    GROUP BY <字段名>

    其中,“字段名”表示需要分组的字段名称,多个字段时用逗号隔开。
    GROUP BY 与 GROUP_CONCAT()
    GROUP BY 关键字可以和 GROUP_CONCAT() 函数一起使用。GROUP_CONCAT() 函数会把每个分组的字段值都显示出来。

    SELECT sex, GROUP_CONCAT(name) FROM tb_students_info GROUP BY sex;

    分组后查询:having

    使用 HAVING 关键字的语法格式如下:

    HAVING <查询条件>

    HAVING 关键字和 WHERE 关键字都可以用来过滤数据,且 HAVING 支持 WHERE 关键字中所有的操作符和语法。

    但是 WHERE 和 HAVING 关键字也存在以下几点差异:

    • 一般情况下,WHERE 用于过滤数据行,而 HAVING 用于过滤分组。
    • WHERE 查询条件中不可以使用聚合函数,而 HAVING 查询条件中可以使用聚合函数。
    • WHERE 在数据分组前进行过滤,而 HAVING 在数据分组后进行过滤 。
    • WHERE 针对数据库文件进行过滤,而 HAVING 针对查询结果进行过滤。也就是说,WHERE 根据数据表中的字段直接进行过滤,而 HAVING 是根据前面已经查询出的字段进行过滤。
    • WHERE 查询条件中不可以使用字段别名,而 HAVING 查询条件中可以使用字段别名。

    多表查询

    多表查询就是同时查询两个或两个以上的表。

    等值连接

    在连接条件中使用等于号(=)运算符比较被连接列的列值,其查询结果中列出被连接表中的所有列,包括其中的重复列。

    SELECT <字段名> FROM <表1>, <表2> [WHERE子句]

    • 字段名:需要查询的字段名称。
    • <表1><表2>:需要交叉连接的表名。
    • WHERE 子句:用来设置交叉连接的查询条件。

    2个表会先进行笛卡尔乘积运算,生成一个新表格,占据在电脑内存里,当表的数据量很大时,很耗内存,这种方法效率比较低,尽量不用。

    笛卡尔积(Cartesian product)是指两个集合 X 和 Y 的乘积。

    非等值连接

    select * from B,B mm where B.成绩>mm.成绩

    自连接

    自己和自己做笛卡尔积,需要为表定义别名。

    查询和李军同性别并同班的同学SNAME

    select s1.sname,s1.ssex,s1.class fromstudent s1,student s2

    where s1.ssex=s2.ssex and s1.class=s2.classand s2.sname='张飞'

    内连接(重要)

    主要通过设置连接条件的方式,来移除查询结果中某些数据行的交叉连接。简单来说,就是利用条件表达式来消除交叉连接的某些数据行。

    内连接使用 INNER JOIN 关键字连接两张表,并使用 ON 子句来设置连接条件。如果没有连接条件,INNER JOIN 和 CROSS JOIN 在语法上是等同的,两者可以互换。

    SELECT <字段名> FROM <表1> INNER JOIN <表2> [ON子句](连接条件)

    语法说明如下。

    • 字段名:需要查询的字段名称。
    • <表1><表2>:需要内连接的表名。
    • INNER JOIN :内连接中可以省略 INNER 关键字,只用关键字 JOIN。
    • ON 子句:用来设置内连接的连接条件。

    INNER JOIN 也可以使用 WHERE 子句指定连接条件,但是 INNER JOIN ... ON 语法是官方的标准写法,而且 WHERE 子句在某些时候会影响查询的性能。

    多个表内连接时,在 FROM 后连续使用 INNER JOIN 或 JOIN 即可。

    内连接可以查询两个或两个以上的表。

    2个表根据共同ID进行逐条匹配,不会出现笛卡尔乘积的现象,效率比较高,优先使用这种方法。

    外连接

    外连接会先将连接的表分为基表和参考表,再以基表为依据返回满足和不满足条件的记录。

    左连接

    左外连接又称为左连接,使用 LEFT OUTER JOIN 关键字连接两个表,并使用 ON 子句来设置连接条件。

    左连接的语法格式如下:

    SELECT <字段名> FROM <表1> LEFT OUTER JOIN <表2> <ON子句>

    语法说明如下。

    • 字段名:需要查询的字段名称。
    • <表1><表2>:需要左连接的表名。
    • LEFT OUTER JOIN:左连接中可以省略 OUTER 关键字,只使用关键字 LEFT JOIN。
    • ON 子句:用来设置左连接的连接条件,不能省略。

    表1”为基表,“表2”为参考表。左连接查询时,可以查询出“表1”中的所有记录和“表2”中匹配连接条件的记录。如果“表1”的某行在“表2”中没有匹配行,那么在返回结果中,“表2”的字段值均为空值(NULL)。

    右连接

    右外连接又称为右连接,右连接是左连接的反向连接。使用 RIGHT OUTER JOIN 关键字连接两个表,并使用 ON 子句来设置连接条件。

    右连接的语法格式如下:

    SELECT <字段名> FROM <表1> RIGHT OUTER JOIN <表2> <ON子句>

    语法说明如下。

    • 字段名:需要查询的字段名称。
    • <表1><表2>:需要右连接的表名。
    • RIGHT OUTER JOIN:右连接中可以省略 OUTER 关键字,只使用关键字 RIGHT JOIN。
    • ON 子句:用来设置右连接的连接条件,不能省略。

    与左连接相反,右连接以“表2”为基表,“表1”为参考表。右连接查询时,可以查询出“表2”中的所有记录和“表1”中匹配连接条件的记录。如果“表2”的某行在“表1”中没有匹配行,那么在返回结果中,“表1”的字段值均为空值(NULL)。

    交叉连接

    交叉连接(CROSS JOIN)一般用来返回连接表的笛卡尔积。

    子查询

    子查询是 MySQL 中比较常用的查询方法,通过子查询可以实现多表查询。子查询指将一个查询语句嵌套在另一个查询语句中。子查询可以在 SELECT、UPDATE 和 DELETE 语句中使用,而且可以进行多层嵌套。在实际开发时,子查询经常出现在 WHERE 子句中。

    子查询在 WHERE 中的语法格式如下:

    WHERE <表达式> <操作符> (子查询)

    其中,操作符可以是比较运算符和 IN、NOT IN、EXISTS、NOT EXISTS 等关键字。

    1)IN | NOT IN

    当表达式与子查询返回的结果集中的某个值相等时,返回 TRUE,否则返回 FALSE;若使用关键字 NOT,则返回值正好相反。

    2)EXISTS | NOT EXISTS

    用于判断子查询的结果集是否为空,若子查询的结果集不为空,返回 TRUE,否则返回 FALSE;若使用关键字 NOT,则返回的值正好相反。

    子查询注意事项
      1. 子查询语句可以嵌套在 SQL 语句中任何表达式出现的位置

      在 SELECT 语句中,子查询可以被嵌套在 SELECT 语句的列、表和查询条件中,即 SELECT 子句,FROM 子句、WHERE 子句、GROUP BY 子句和 HAVING 子句。

      前面已经介绍了 WHERE 子句中嵌套子查询的使用方法,下面是子查询在 SELECT 子句和 FROM 子句中的使用语法。

      嵌套在 SELECT 语句的 SELECT 子句中的子查询语法格式如下。

      SELECT (子查询) FROM 表名;

      提示:子查询结果为单行单列,但不必指定列别名。

      嵌套在 SELECT 语句的 FROM 子句中的子查询语法格式如下。

      SELECT * FROM (子查询) AS 表的别名;

      注意:必须为表指定别名。一般返回多行多列数据记录,可以当作一张临时表。

      1. 只出现在子查询中而没有出现在父查询中的表不能包含在输出列中

      多层嵌套子查询的最终数据集只包含父查询(即最外层的查询)的 SELECT 子句中出现的字段,而子查询的输出结果通常会作为其外层子查询数据源或用于数据判断匹配。

      常见错误如下:

      SELECT * FROM (SELECT * FROM result);

      这个子查询语句产生语法错误的原因在于主查询语句的 FROM 子句是一个子查询语句,因此应该为子查询结果集指定别名。正确代码如下。

      SELECT * FROM (SELECT * FROM result) AS Temp;

    联合查询

    合并多个查询结果集

    union

    语法:

    select ……
    union
    select……
    1. 查询性别为女的学生信息或者或者1班的学生信息
    2. 查询学生姓名,性别以及老师姓名性别

    注意:

    • 多条查询语句的查询列数要求一致
    • 查询语句的每一列的类型和顺序最好一致
    • union默认去重,使用union all可以包含所有

    数据类型

    MySQL 的数据类型有大概可以分为 5 种,分别是整数类型、浮点数类型和定点数类型、日期和时间类型、字符串类型、二进制类型等。

      1. 数值类型

      整数类型包括 TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT,浮点数类型包括 FLOAT 和 DOUBLE,定点数类型为 DECIMAL。

      1. 日期/时间类型

      包括 YEAR、TIME、DATE、DATETIME 和 TIMESTAMP。

      1. 字符串类型

      包括 CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM 和 SET 等。

      1. 二进制类型

      包括 BIT、BINARY、VARBINARY、TINYBLOB、BLOB、MEDIUMBLOB 和 LONGBLOB。

    整数类型

    MySQL 主要提供的整数类型有 TINYINTSMALLINTMEDIUMINTINTBIGINT,其属性字段可以添加 AUTO_INCREMENT 自增约束条件。下表中列出了 MySQL 中的数值类型。

    类型名称 说明 存储需求
    TINYINT 很小的整数 1个字节
    SMALLINT 小的整数 2个宇节
    MEDIUMINT 中等大小的整数 3个字节
    INT (INTEGHR) 普通大小的整数 4个字节
    BIGINT 大整数 8个字节

    关键字:unsigned 无符号的

    浮点型

    MySQL 中使用浮点数和定点数来表示小数。

    浮点类型有两种,分别是单精度浮点数(FLOAT)和双精度浮点数(DOUBLE);定点类型只有一种,就是 DECIMAL

    浮点类型和定点类型都可以用(M, D)来表示,其中M称为精度,表示总共的位数;D称为标度,表示小数的位数。

    浮点数类型的取值范围为 M(1~255)和 D(1~30,且不能大于 M-2),分别表示显示宽度和小数位数。M 和 D 在 FLOAT 和DOUBLE 中是可选的,FLOAT 和 DOUBLE 类型将被保存为硬件所支持的最大精度。DECIMAL 的默认 D 值为 0、M 值为 10。

    下表中列出了 MySQL 中的小数类型和存储需求。

    类型名称 说明 存储需求
    FLOAT 单精度浮点数 4 个字节
    DOUBLE 双精度浮点数 8 个字节
    DECIMAL (M, D),DEC 压缩的“严格”定点数 M+2 个字节

    DECIMAL 类型不同于 FLOAT 和 DOUBLE。DOUBLE 实际上是以字符串的形式存放的,DECIMAL 可能的最大取值范围与 DOUBLE 相同,但是有效的取值范围由 M 和 D 决定。如果改变 M 而固定 D,则取值范围将随 M 的变大而变大。

    浮点数相对于定点数的优点是在长度一定的情况下,浮点数能够表示更大的范围;缺点是会引起精度问题。

    最后再强调一下:在 MySQL 中,定点数以字符串形式存储,在对精度要求比较高的时候(如货币、科学数据),使用 DECIMAL 的类型比较好,另外两个浮点数进行减法和比较运算时也容易出问题,所以在使用浮点数时需要注意,并尽量避免做浮点数比较。

    日期和时间

    类型名称 日期格式 日期范围 存储需求
    YEAR YYYY 1901 ~ 2155 1 个字节
    TIME HH:MM:SS -838:59:59 ~ 838:59:59 3 个字节
    DATE YYYY-MM-DD 1000-01-01 ~ 9999-12-3 3 个字节
    DATETIME YYYY-MM-DD HH:MM:SS 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 8 个字节
    TIMESTAMP YYYY-MM-DD HH:MM:SS 1980-01-01 00:00:01 UTC ~ 2040-01-19 03:14:07 UTC 4 个字节
    YEAR 类型

    YEAR 类型是一个单字节类型,用于表示年,在存储时只需要 1 个字节。可以使用各种格式指定 YEAR,如下所示:

    • 以 4 位字符串或者 4 位数字格式表示的 YEAR,范围为 '1901'~'2155'。输入格式为 'YYYY' 或者 YYYY,例如,输入 '2010' 或 2010,插入数据库的值均为 2010。
    • 以 2 位字符串格式表示的 YEAR,范围为 '00' 到 '99'。'00'~'69' 和 '70'~'99' 范围的值分别被转换为 2000~2069 和 1970~1999 范围的 YEAR 值。'0' 与 '00' 的作用相同。插入超过取值范围的值将被转换为 2000。
    • 以 2 位数字表示的 YEAR,范围为 1~99。1~99 和 70~99 范围的值分别被转换为 2001~2069 和 1970~1999 范围的 YEAR 值。注意,在这里 0 值将被转换为 0000,而不是 2000。

    提示:两位整数范围与两位字符串范围稍有不同。例如,插入 3000 年,读者可能会使用数字格式的 0 表示 YEAR,实际上,插入数据库的值为 0000,而不是所希望的 3000。只有使用字符串格式的 '0' 或 '00',才可以被正确解释为 3000,非法 YEAR值将被转换为 0000。

    TIME 类型

    TIME 类型用于只需要时间信息的值,在存储时需要 3 个字节。格式为 HH:MM:SS。HH 表示小时,MM 表示分钟,SS 表示秒。

    TIME 类型的取值范围为 -838:59:59~838:59:59,小时部分如此大的原因是 TIME 类型不仅可以用于表示一天的时间(必须小于 24 小时),还可能是某个事件过去的时间或两个事件之间的时间间隔(可大于 24 小时,或者甚至为负)。

    可以使用各种格式指定 TIME 值,如下所示。

    • 'D HH:MM:SS' 格式的字符串。还可以使用这些“非严格”的语法:'HH:MM:SS'、'HH:MM'、'D HH' 或 'SS'。这里的 D 表示日,可以取 0~34 之间的值。在插入数据库时,D 被转换为小时保存,格式为 “D*24+HH”。
    • 'HHMMSS' 格式、没有间隔符的字符串或者 HHMMSS 格式的数值,假定是有意义的时间。例如,'101112' 被理解为'10:11:12',但是 '106112' 是不合法的(它有一个没有意义的分钟部分),在存储时将变为 00:00:00。

    提示:为 TIME 列分配简写值时应注意:如果没有冒号,MySQL 解释值时,假定最右边的两位表示秒。(MySQL 解释 TIME 值为过去的时间而不是当前的时间)。例如,读者可能认为 '1112' 和 1112 表示 11:12:00(即 11 点过 12 分钟),但MySQL 将它们解释为 00:11:12(即 11 分 12 秒)。同样 '12' 和 12 被解释为00:00:12。相反,TIME 值中如果使用冒号则肯定被看作当天的时间,也就是说,'11:12' 表示 11:12:00,而不是 00:11:12。

    DATE 类型

    DATE 类型用于仅需要日期值时,没有时间部分,在存储时需要 3 个字节。日期格式为 'YYYY-MM-DD',其中 YYYY 表示年,MM 表示月,DD 表示日。

    在给 DATE 类型的字段赋值时,可以使用字符串类型或者数字类型的数据插入,只要符合 DATE 的日期格式即可。如下所示:

    • 以 'YYYY-MM-DD' 或者 'YYYYMMDD' 字符中格式表示的日期,取值范围为 '1000-01-01'~'9999-12-3'。例如,输入 '2015-12-31' 或者 '20151231',插入数据库的日期为2015-12-31。
    • 以 'YY-MM-DD' 或者 'YYMMDD' 字符串格式表示日期,在这里YY表示两位的年值。MySQL 解释两位年值的规则:'00~69' 范围的年值转换为 '20002069','7099' 范围的年值转换为 '1970~1999'。例如,输入 '15-12-31',插入数据库的日期为 2015-12-31;输入 '991231',插入数据库的日期为 1999-12-31。
    • 以 YYMMDD 数字格式表示的日期,与前面相似,00~69 范围的年值转换为 2000~2069,80~99 范围的年值转换为 1980~1999。例如,输入 151231,插入数据库的日期为 2015-12-31,输入 991231,插入数据库的日期为 1999-12-31。
    • 使用 CURRENT_DATE 或者 NOW(),插入当前系统日期。

    提示:MySQL 允许“不严格”语法:任何标点符号都可以用作日期部分之间的间隔符。例如,'98-11-31'、'98.11.31'、'98/11/31'和'98@11@31' 是等价的,这些值也可以正确地插入数据库。

    DATETIME 类型

    DATETIME 类型用于需要同时包含日期和时间信息的值,在存储时需要 8 个字节。日期格式为 'YYYY-MM-DD HH:MM:SS',其中 YYYY 表示年,MM 表示月,DD 表示日,HH 表示小时,MM 表示分钟,SS 表示秒。

    在给 DATETIME 类型的字段赋值时,可以使用字符串类型或者数字类型的数据插入,只要符合 DATETIME 的日期格式即可,如下所示。

    • 以 'YYYY-MM-DD HH:MM:SS' 或者 'YYYYMMDDHHMMSS' 字符串格式表示的日期,取值范围为 '1000-01-01 00:00:00'~'9999-12-3 23:59:59'。例如,输入 '2014-12-31 05:05:05' 或者 '20141231050505’,插入数据库的 DATETIME 值都为 2014-12-31 05:05:05。
    • 以 'YY-MM-DD HH:MM:SS' 或者 'YYMMDDHHMMSS' 字符串格式表示的日期,在这里 YY 表示两位的年值。与前面相同,'00~79' 范围的年值转换为 '2000~2079','80~99' 范围的年值转换为 '1980~1999'。例如,输入 '14-12-31 05:05:05',插入数据库的 DATETIME 为 2014-12-31 05:05:05;输入 141231050505,插入数据库的 DATETIME 为 2014-12-31 05:05:05。
    • 以 YYYYMMDDHHMMSS 或者 YYMMDDHHMMSS 数字格式表示的日期和时间。例如,输入 20141231050505,插入数据库的 DATETIME 为 2014-12-31 05:05:05;输入 140505050505,插入数据库的 DATETIME 为 2014-12-31 05:05:05。

    提示:MySQL 允许“不严格”语法:任何标点符号都可用作日期部分或时间部分之间的间隔符。例如,'98-12-31 11:30:45'、'98.12.31 11+30+35'、'98/12/31 113045' 和 '98@12@31 113045' 是等价的,这些值都可以正确地插入数据库。

    TIMESTAMP 类型

    TIMESTAMP 的显示格式与 DATETIME 相同,显示宽度固定在 19 个字符,日期格式为 YYYY-MM-DD HH:MM:SS,在存储时需要 4 个字节。但是 TIMESTAMP 列的取值范围小于 DATETIME 的取值范围,为 '1970-01-01 00:00:01'UTC~'2038-01-19 03:14:07'UTC。在插入数据时,要保证在合法的取值范围内。

    提示:协调世界时(英:Coordinated Universal Time,法:Temps Universel Coordonné)又称为世界统一时间、世界标准时间、国际协调时间。英文(CUT)和法文(TUC)的缩写不同,作为妥协,简称 UTC。

    TIMESTAMP 与 DATETIME 除了存储字节和支持的范围不同外,还有一个最大的区别是:

    • DATETIME 在存储日期数据时,按实际输入的格式存储,即输入什么就存储什么,与时区无关;
    • 而 TIMESTAMP 值的存储是以 UTC(世界标准时间)格式保存的,存储时对当前时区进行转换,检索时再转换回当前时区。即查询时,根据当前时区的不同,显示的时间值是不同的。

    提示:如果为一个 DATETIME 或 TIMESTAMP 对象分配一个 DATE 值,结果值的时间部分被设置为 '00:00:00',因此 DATE 值未包含时间信息。如果为一个 DATE 对象分配一个 DATETIME 或 TIMESTAMP 值,结果值的时间部分被删除,因此DATE 值未包含时间信息。

    字符型

    字符串类型用来存储字符串数据,还可以存储图片和声音的二进制数据。字符串可以区分或者不区分大小写的串比较,还可以进行正则表达式的匹配查找。

    MySQL 中的字符串类型有 CHARVARCHARTINYTEXTTEXTMEDIUMTEXTLONGTEXTENUMSET 等。

    下表中列出了 MySQL 中的字符串数据类型,括号中的M表示可以为其指定长度。

    类型名称 说明 存储需求
    CHAR(M) 固定长度非二进制字符串 M 字节,1<=M<=255
    VARCHAR(M) 变长非二进制字符串 L+1字节,在此,L< = M和 1<=M<=255
    TINYTEXT 非常小的非二进制字符串 L+1字节,在此,L<2^8
    TEXT 小的非二进制字符串 L+2字节,在此,L<2^16
    MEDIUMTEXT 中等大小的非二进制字符串 L+3字节,在此,L<2^24
    LONGTEXT 大的非二进制字符串 L+4字节,在此,L<2^32
    ENUM 枚举类型,只能有一个枚举字符串值 1或2个字节,取决于枚举值的数目 (最大值为65535)
    SET 一个设置,字符串对象可以有零个或 多个SET成员 1、2、3、4或8个字节,取决于集合 成员的数量(最多64个成员)

    VARCHAR 和 TEXT 类型是变长类型,其存储需求取决于列值的实际长度(在前面的表格中用 L 表示),而不是取决于类型的最大可能尺寸。

    例如,一个 VARCHAR(10) 列能保存一个最大长度为 10 个字符的字符串,实际的存储需要字符串的长度 L 加上一个字节以记录字符串的长度。对于字符 “abcd”,L 是 4,而存储要求 5 个字节。

    CHAR 和 VARCHAR 类型

    CHAR(M) 为固定长度字符串,在定义时指定字符串列长。当保存时,在右侧填充空格以达到指定的长度。M 表示列的长度,范围是 0~255 个字符。

    例如,CHAR(4) 定义了一个固定长度的字符串列,包含的字符个数最大为 4。当检索到 CHAR 值时,尾部的空格将被删除。

    VARCHAR(M) 是长度可变的字符串,M 表示最大列的长度,M 的范围是 0~65535。VARCHAR 的最大实际长度由最长的行的大小和使用的字符集确定,而实际占用的空间为字符串的实际长度加 1。

    例如,VARCHAR(50) 定义了一个最大长度为 50 的字符串,如果插入的字符串只有 10 个字符,则实际存储的字符串为 10 个字符和一个字符串结束字符。VARCHAR 在值保存和检索时尾部的空格仍保留。

    【实例】下面将不同的字符串保存到 CHAR(4) 和 VARCHAR(4) 列,说明 CHAR 和 VARCHAR 之间的差别,如下表所示。

    插入值 CHAR(4) 存储需求 VARCHAR(4) 存储需求
    ' ' ' ' 4字节 '' 1字节
    'ab' 'ab ' 4字节 'ab' 3字节
    'abc' 'abc ' 4字节 'abc' 4字节
    'abcd' 'abcd' 4字节 'abcd' 5字节
    'abcdef' 'abcd' 4字节 'abcd' 5字节

    对比结果可以看到,CHAR(4) 定义了固定长度为 4 的列,无论存入的数据长度为多少,所占用的空间均为 4 个字节。VARCHAR(4) 定义的列所占的字节数为实际长度加 1。

    TEXT 类型

    TEXT 列保存非二进制字符串,如文章内容、评论等。当保存或查询 TEXT 列的值时,不删除尾部空格。

    TEXT 类型分为 4 种:TINYTEXT、TEXT、MEDIUMTEXT 和 LONGTEXT。不同的 TEXT 类型的存储空间和数据长度不同。

    • TINYTEXT 表示长度为 255(28-1)字符的 TEXT 列。
    • TEXT 表示长度为 65535(216-1)字符的 TEXT 列。
    • MEDIUMTEXT 表示长度为 16777215(224-1)字符的 TEXT 列。
    • LONGTEXT 表示长度为 4294967295 或 4GB(232-1)字符的 TEXT 列。
    ENUM 类型

    ENUM 是一个字符串对象,值为表创建时列规定中枚举的一列值。其语法格式如下:

    <字段名> ENUM( '值1', '值1', …, '值n' )

    字段名指将要定义的字段,值 n 指枚举列表中第 n 个值。

    ENUM 类型的字段在取值时,能在指定的枚举列表中获取,而且一次只能取一个。如果创建的成员中有空格,尾部的空格将自动被删除。

    ENUM 值在内部用整数表示,每个枚举值均有一个索引值;列表值所允许的成员值从 1 开始编号,MySQL 存储的就是这个索引编号,枚举最多可以有 65535 个元素。

    提示:ENUM 列总有一个默认值。如果将 ENUM 列声明为 NULL,NULL 值则为该列的一个有效值,并且默认值为 NULL。如果 ENUM 列被声明为 NOT NULL,其默认值为允许的值列表的第 1 个元素。

    SET 类型

    SET 是一个字符串的对象,可以有零或多个值,SET 列最多可以有 64 个成员,值为表创建时规定的一列值。指定包括多个 SET 成员的 SET 列值时,各成员之间用逗号,隔开,语法格式如下:

    SET( '值1', '值2', …, '值n' )

    与 ENUM 类型相同,SET 值在内部用整数表示,列表中每个值都有一个索引编号。当创建表时,SET 成员值的尾部空格将自动删除。

    但与 ENUM 类型不同的是,ENUM 类型的字段只能从定义的列值中选择一个值插入,而 SET 类型的列可从定义的列值中选择多个字符的联合。

    提示:如果插入 SET 字段中的列值有重复,则 MySQL 自动删除重复的值;插入 SET 字段的值的顺序并不重要,MySQL 会在存入数据库时,按照定义的顺序显示;如果插入了不正确的值,默认情况下,MySQL 将忽视这些值,给出警告。

    二进制

    MySQL 支持两类字符型数据:文本字符串和二进制字符串。

    二进制字符串类型有时候也直接被称为“二进制类型”。

    MySQL 中的二进制字符串有 BITBINARYVARBINARYTINYBLOBBLOBMEDIUMBLOBLONGBLOB

    下表中列出了 MySQL 中的二进制数据类型,括号中的M表示可以为其指定长度。

    类型名称 说明 存储需求
    BIT(M) 位字段类型 大约 (M+7)/8 字节
    BINARY(M) 固定长度二进制字符串 M 字节
    VARBINARY (M) 可变长度二进制字符串 M+1 字节
    TINYBLOB (M) 非常小的BLOB L+1 字节,在此,L<2^8
    BLOB (M) 小 BLOB L+2 字节,在此,L<2^16
    MEDIUMBLOB (M) 中等大小的BLOB L+3 字节,在此,L<2^24
    LONGBLOB (M) 非常大的BLOB L+4 字节,在此,L<2^32
    数据类型 存储范围
    TINYBLOB 最大长度为255 (28-1)字节
    BLOB 最大长度为65535 (216-1)字节
    MEDIUMBLOB 最大长度为16777215 (224-1)字节
    LONGBLOB 最大长度为4294967295或4GB (231-1)字节

    转义字符

    转义字符 转义后的字符
    " 双引号(")
    ' 单引号(')
    反斜线()
    换行符
    回车符
    制表符
    ASCII 0(NUL)
     退格符

    约束

    1)主键约束 primary key

    主键约束是使用最频繁的约束。在设计数据表时,一般情况下,都会要求表中设置一个主键。

    主键是表的一个特殊字段,该字段能唯一标识该表中的每条信息。例如,学生信息表中的学号是唯一的。

    2)外键约束 foreign key

    外键约束经常和主键约束一起使用,用来确保数据的一致性。

    3)唯一约束 unique

    唯一约束与主键约束有一个相似的地方,就是它们都能够确保列的唯一性。与主键约束不同的是,唯一约束在一个表中可以有多个,并且设置唯一约束的列是允许有空值的,虽然只能有一个空值。

    4)检查约束 check(mysql不支持)

    检查约束是用来检查数据表中,字段值是否有效的一个手段。

    例如,学生信息表中的年龄字段是没有负数的,并且数值也是有限制的。如果是大学生,年龄一般应该在 18~30 岁之间。在设置字段的检查约束时要根据实际情况进行设置,这样能够减少无效数据的输入。

    5)非空约束 not null

    非空约束用来约束表中的字段不能为空。例如,在学生信息表中,如果不添加学生姓名,那么这条记录是没有用的。

    6)默认值约束 default

    非空约束用来约束表中的字段不能为空。例如,在学生信息表中,如果不添加学生姓名,那么这条记录是没有用的。

    分类

    • 列级约束
      • 都支持,但外键约束没效果
    • 表级约束
      • 除了非空、默认,其他都支持

    官方写法

    在定义字段的同时指定主键,语法格式如下:

    <字段名> <数据类型> PRIMARY KEY [默认值]

    在定义完所有字段之后指定主键,这是比较正规的写法,语法格式如下:

    [CONSTRAINT <约束名>] PRIMARY KEY [字段名]
    [CONSTRAINT <外键名>] FOREIGN KEY 字段名 [,字段名2,…] REFERENCES <主表名> 主键列1 [,主键列2,…]
    [CONSTRAINT <约束名>] UNIQUE [字段名]
    修改表时添加约束
    ALTER TABLE <数据表名> ADD PRIMARY KEY(<字段名>);
    ALTER TABLE <数据表名> ADD CONSTRAINT <外键名>
    FOREIGN KEY(<列名>) REFERENCES <主表名> (<列名>);
    ALTER TABLE <数据表名> ADD CONSTRAINT <唯一约束名> UNIQUE(<列名>);
    ALTER TABLE tb_emp7 ADD CONSTRAINT <检查约束名> CHECK(<检查约束>);
    ALTER TABLE <数据表名>
    CHANGE COLUMN <字段名> <数据类型> DEFAULT <默认值>;
    ALTER TABLE <数据表名>
    CHANGE COLUMN <字段名>
    <字段名> <数据类型> NOT NULL;
    
    ##### 删除约束
    
    ```sql
    ALTER TABLE <数据表名> DROP PRIMARY KEY;
    ALTER TABLE <表名> DROP FOREIGN KEY <外键约束名>;
    ALTER TABLE <表名> DROP INDEX <唯一约束名>;
    ALTER TABLE <数据表名> DROP CONSTRAINT <检查约束名>;
    ALTER TABLE <数据表名>
    CHANGE COLUMN <字段名> <字段名> <数据类型> DEFAULT NULL;
    ALTER TABLE <数据表名>
    CHANGE COLUMN <字段名> <字段名> <数据类型> NULL;

    查看表中约束:SHOW CREATE TABLE <数据表名>;

    事务

    transaction是一种机制,若干条数据库操作指令构成一个操作序列,该序列要么全部执行,要么全部不执行,事务是一个不可分割的逻辑单元。

    事务具有四个特性,简称为acid

    原子性(atomicity)

    事务是一个完整的操作。事务的各元素是不可分的(原子的)。事务中的所有元素必须作为一个整体提交或回滚。如果事务中的任何元素失败,则整个事务将失败。

    一致性(consistency)

    当事务完成时,数据必须处于一致状态。也就是说,在事务开始之前,数据库中存储的数据处于一致状态。在正在进行的事务中. 数据可能处于不一致的状态,如数据可能有部分被修改。然而,当事务成功完成时,数据必须再次回到已知的一致状态。通过事务对数据所做的修改不能损坏数据,或者说事务不能使数据存储处于不稳定的状态。

    隔离性(isolation)

    对数据进行修改的所有并发事务是彼此隔离的,这表明事务必须是独立的,它不应以任何方式依赖于或影响其他事务。修改数据的事务可以在另一个使用相同数据的事务开始之前访问这些数据,或者在另一个使用相同数据的事务结束之后访问这些数据。

    持久性(durability)

    事务的持久性指不管系统是否发生了故障,事务处理的结果都是永久的。一个事务成功完成之后,它对数据库所作的改变是永久性的,即使系统出现故障也是如此。也就是说,一旦事务被提交,事务对数据所做的任何变动都会被永久地保留在数据库中。

    执行流程

    # 开始事务
    begin;   或  start transaction;
    # 提交事务
    commit;
    # 回滚
    rollback;

    注意:

    1. 事务尽可能简短,事务的开启到结束会在数据库管理系统中保留大量资源,影响软件的性能
    2. 事务中访问的数据量尽量最少
    3. 查询数据时尽量不要使用事务,避免占用过多资源
    4. 在事务处理过程中尽量不要出现等待用户输入的操作

    设置自动提交事务

    通过命令查看事务当前状态

    SHOW VARIABLES LIKE 'autocommit';

    设置自动提交

    SET autocommit = 0|1|ON|OFF;

    0或off为关闭自动提交,即遇到commit或者rollback才会结束一个事务

    1或on表示开启自动提交,每一条sql语句即为一个事务

    默认都是开启,自动提交事务

    jdbc

    • 通过connection打开事务和提交
    • 同一个connection

    隔离级别(重要)

    如果没有隔离级别,并发访问会产生一些问题。

    并发:两件事在同一个时间段内执行 举例:十点钟,妈妈出门,十二点回来,写完作业并且做好饭

    并行:两件事同时刻执行 举例:边吃饭边洗脚

    • 脏读 dirty read:读取到另一个事务未提交的数据,也就是脏数据

    • 不可重复读 unrepeatable read:对同一记录的两次读取不一致,因为另外一个事务对该记录做了修改

    • 幻读 phantom read:对同一张表的两次查询不一致,因为另外一个事务插入了一条记录

      区别:

      不可重复读是读取到了另外一个事务的更新

      幻读是读取到了另外一个事务的插入

    四大隔离级别

    • read uncommitted 读未提交数据
      • 可能会出现任何并发问题
      • 性能最好
    • read committed 读已提交数据(oracle默认)
      • 防止脏读
      • 性能比下一个稍微好点
    • reaeatable read 可重复读(mysql默认)
      • 防止脏读和不可重复读
    • serializable 串行化
      • 不会出现任何问题,因为对数据库的访问是串行,非并发访问
      • 性能最低

    查看隔离级别

    select @@tx_isolation;
    show variables like'%tx_isolation';
    
    # 设置隔离级别
    set[session | clobal] transaction isolation level [read uncommitted|read committed|reaeatable read |serializable]
  • 相关阅读:
    golang中os/user包用法
    golang中os包用法
    与table有关的布局
    jQuery 从 1.9 版开始,移除了 $.browser 和 $.browser.version
    canvas里调用getImageData的报security的问题
    CSS样式覆盖规则
    windows7文件夹怎样默认图片大图显示?
    Jboss,Tomcat 远程调试配置
    IE(IE6/IE7/IE8)支持HTML5标签
    JS 继承(类式 与 原型式)
  • 原文地址:https://www.cnblogs.com/friend-c/p/14759785.html
Copyright © 2020-2023  润新知