MySQL快速入门学习笔记(下)

Posted by     Airmole on August 6, 2017

不到万不得已就将就着看本文吧,别看原文了.错别字多就算了,到后面还有还多语句的示例代码都张冠李戴了.当然,本文可能亦有错误,可以联系指正,不胜感激。

类型、字符集、引擎和索引

数据类型

数据库就是用来存储数据的,类似于编程语言一样数据也分数据类型。为什么要区分数据类型呢?全都用字符型岂不是通用通吃了吗?我觉得是跟执行效率有关的,能更好的分配管理内存,节省不必要的开支.限制数据类型也可以处理一些非法输入,总之数据类型非常有用。在插入的数据中就要使用对应的数据类型。并且,遵守数据类型的长度要求。

MySQL有的数据类型可以划分为五种,每种类型都还能继续细分,而且数据库的数据类型比编程语言区分的更细: 1.数值类型 2.字符串类型 3.时间日期类型 4.复合类型 5.空间类型(非科学性工作基本不用,不做讲解,或许是空间科学技术方面学的吧。高大上了。)

### 整型

数据类型 所占字节 值范围
tinyint 1字节 -128~127
smallint 2字节 -32768~32767
mediumint 3字节 -8388608~8388607
int 4字节 -2147483648~2147483647
bigint 8字节 ±9.22*10的18次方

整型的长度不同,在实际使用过程中的用途也不同,按照实际情况使用合适的数据类型可以提高数据库效率。 MySQL 以一个可选的显示宽度指示器的形式对 SQL 标准进行扩展,这样当从数据库检索一个值时,可以把这个值加长到指定的长度。例如,指定一个字段的类型为 INT(6), 就可以保证所包含数字少于 6 个的值从数据库中检索出来时能够自动地用空格填充。需要注意的是,使用一个宽度指示器不会影响字段的大小和它可以存储的值的范围。

也就是说INT(6)里的6是这个字段最大长度,小于这个长度,MySQL会用空格填充,使数据看起来更加直观;大于会被截取。实际上却是不会影响字段的大小和值范围。这个后面还会讲到。

注意:
1.在创建表字段时,性别可以使用无符号的微小整型(tinyint)表示。0女,1男,2未知。
//微小整型?那怎么不叫Microint呢?多好记?tiny是什么鬼?好吧tiny也是微小的,极小的。极小翻译过来更贴切。
2.同样人类年龄也是,在创建表字段时可用用无符号的整型。因为人类的年龄不会说负数。
3.在实际使用过程中。我们业务中最大需要存储多大的数值。我们创建表时,就选择什么样的类型来存储这样的值。

浮点类型

数据类型 所占字节 值范围
float(m,d) 4字节 单精度浮点型,m是总个数,d小数位
double(m,d) 8字节 双精度浮点型,m总个数,d小数位
decimal(m,d)   decimal是存储为字符串的浮点数

??decimal什么/??什么就字符串还成为浮点数了?? 查了一下,不复杂深究。精度比较高的东西,比如money,我会用decimal类型,不会考虑float,double,因为他们容易产生误差。也就是说对数值精度要求高的最好用decimal浮点型。可靠一点。

注意:
1.浮点是非精确值,会存在不太准确的情况
2.而decimal叫做定点数。在MySQL内部,本质上是用字符串存储的。
实际使用过程中如果存在金额、钱精度要求比较高的浮点数存储,建议使用decimal(定点数)这个类型。

字符类型

哇~我感觉字符类型绝对是最烦的。提前做好思想准备啊。 呃呃,怎么原文有莫名其妙突然用起了大写?我不管,我就要用小写。

数据类型 所占字节 值范围
char 0-255字节 定长字符串
varchar 0-255字节 变长字符串
tinyblob 0-255字节 不超过255个字符的二进制字符串
tinytext 0-255字节 短文本字符串
blob 0-65535字节 二进制形式的长文本数据
text 0-65535字节 长文本数据
mediumblob 0-16 777 215字节 二进制形式的中等长度文本数据
mediumtext 0-16 777 215字节 二进制形式的中等长度文本数据
longblob 0-4294967295字节 二进制形式的极大文本数据
longtext 0-4294967295字节 极大文本数据
varbinary(M) 允许长度0-M个字节的定长字节符串 值的长度+1字节
binary(M) M 允许长度0-M个字节的定长字节符串

这。。看着就烦。这么看起来应该能稍微好记点。 char varchar binary varbinary tinyblob blob mediumblob longblob tinytext text mediumtext longtext

CHAR 类型用于定长字符串,并且必须在圆括号内用一个大小修饰符来定义。这个大小修饰符的范围从 0-255。比指定长度大的值将被截短,而比指定长度小的值将会用空格作填补。 VARCHAR 而 VARCHAR 类型把它视为最大值并且只使用存储字符串实际需要的长度。不会被空格填补,但长于指示器的值仍然会被截短。

因为 VARCHAR类型可以根据实际内容动态改变存储值的长度,所以在不能确定字段需要多少字符时使用 VARCHAR 类型可以大大地节约磁盘空间、提高存储效率。

text类型与blob类型 字段长度要求超过 255 个的情况下,MySQL 提供了 TEXT 和 BLOB 两种类型。根据存储数据的大小,它们都有不同的子类型。这些大型的数据用于存储文本块或图像、声音文件等二进制数据类型。 TEXT 和 BLOB 类型在分类和比较上存在区别。BLOB 类型区分大小写,而 TEXT 不区分大小写。大小修饰符不用于各种 BLOB 和 TEXT 子类型。 //??前面看懂了,最后后这一句什么意思?什么是大小修饰符?? //还有,图像,声音这一类文件在数据库中到底是什么类型?怎么存的?

时间类型

|数据类型|所占字节|值范围| |———–|———-|———| |date|3字节|日期,格式:2017-08-04 |time|3字节|时间格式:08:42:30 |datetime|8字节|日期时间,格式:2017-08-04 08:42:30 |timestamp|4字节|自动存储记录修改的时间 |year|1字节|年份

注意

1.时间类型在web系统中用的比较少,很多时候很多人喜欢使用int来存储时间。
插入时插入的是unix时间戳,因为这种方式更方便计算。
在前端业务中用date类型的函数,再将unix时间戳转成人们可识别的时间。
2.上面的类型你可以根据实际情况实际进行选择
3.有些人为了在数据库管理中方便查看,也有人使用datetime类型来存储时间。

复合类型

数据类型 说明 举例
set 集合类型 set(“member”,”member2”,…“member64”)
enum 枚举类型 enum(“member1”,”member2”,…“member65535”)

一个 ENUM 类型只允许从一个集合中取得一个值;而 SET 类型允许从一个集合中取得任意多个值。

ENUM类型

ENUM类型因为只允许在集合中取得一个值,有点类似于单选项。处理多选一的数据时容易理解,比如选择性别。 ENUM类型字段可以从集合中取得一个值或使用null值,除此之外的输入会使 MySQL 在这个字段中插入一个空字符串。另外如果插入值的大小写与集合中值的大小写不匹配,MySQL会自动使用插入值的大小写转换成与集合中大小写一致的值。

貌似是说改变的是集合中的值的大小写,对吧?

ENUM 类型在系统内部可以存储为数字,并且从1开始用数字做索引。一个 ENUM 类型最多可以包含 65536 个元素,其中一个元素被 MySQL 保留,用来存储错误信息,这个错误值用索引 0 或者一个空字符串表示。

MySQL 认为 ENUM 类型集合中出现的值是合法输入,除此之外其它任何输入都将失败。这说明通过搜索包含空字符串或对应数字索引为 0 的行就可以很容易地找到错误记录的位置。

*:就是说复合类型ENUM查错的话就去查索引为0或空的行即可。

SET类型

SET 类型与 ENUM 类型相似但不相同。SET类型可以从预定义的集合中取得任意数量的值。并且与 ENUM 类型相同的是任何试图在 SET 类型字段中插入非预定义的值都会使MySQL插入一个空字符串。如果插入一个即有合法的元素又有非法的元素的记录,MySQL 将会保留合法的元素,除去非法的元素。

一个 SET 类型最多可以包含 64 个元素。在 SET 元素中值被存储为一个分离的“位”序列,这些“位”表示与它相对应的元素。“位”是创建有序元素集合的一种简单而有效的方式。 并且它还去除了重复的元素,所以SET类型中不可能包含两个相同的元素。 希望从 SET 类型字段中找出非法的记录只需查找包含空字符串或二进制值为 0 的行。

两种复合类型查错的方法倒是都一样。

类型使用

这么多类型,在创建表的语句的时候使用对应的类型即可。

CREATE TABLE IF NOT EXISTS demo (     //如果不存在demo表,则创建
id int(11) NOT NULL,                     //字段id,11位整型,不为空
username varchar(50) NOT NULL,     //字段username,50个字符长度的varchar,不为空
password char(32) NOT NULL,   //字段password,32个字符长度的char类型,不为空。
content longtext NOT NULL,   //字段content,longtext型数据,不为空
createtime datetime NOT NULL,       //字段createtime,日期时间类型数据,不为空
sex tinyint(4) NOT NULL                   //字段sex,tinyint型数据,不为空
) ENGINE=InnoDB DEFAULT CHARSET=utf8;   //指定引擎InnoDB,默认字符集utf-8

字段其他属性设置

unsigned(无符号)

主要用于整型和浮点类型,使用无符号。即,没有前面面的-(负号)。 存储位数更长。tinyint整型的取值区间为,-128~127。而使用无符号后可存储0-255个长度。 创建时在整型或浮点字段语句后接上:unsigned 例如:

mysql> create table t(a int unsigned, b int unsigned);
Query OK, 0 rows affected (0.06 sec)

zerofill(0填充)

0(不是空格)可以用来真补输出的值。使用这个修饰符可以阻止 MySQL 数据库存储负值。 类似于unsigned属性一样,创建时在整型或浮点字段语句后接上:zerofill属性即可。这里不再举例示范。

default

default属性确保在没有任何值可用的情况下,赋予某个常量值,这个值必须是常量,因为MySQL不允许插入函数或表达式值。此外,此属性无法用于BLOB或TEXT列。如果已经为此列指定了NULL属性,没有指定默认值时默认值将为NULL,否则默认值将依赖于字段的数据类型。 创建时在整型或浮点字段语句后接上:

default ‘值’

not null

上边那个实例那会儿不就用到了吗。不为空,即不允许在该列(字段)插入null值。建议在重要情况下始终使用not null属性,因为它提供了一个基本验证,确保已经向查询传递了所有必要的值。

这个属性怎么用,不必再 赘述了吧。

null

为列指定null属性时,该列可以保持为空,而不论行中其它列是否已经被填充。记住,null精确的说法是“无”,而不是空字符串或0。 创建时在整型或浮点字段语句后不要声明not null即可。

字符集

何为字符集

啥是字符集??学计算机一定会接触到字符集这个概念的。别的不说,ANSCII码你总听说过吧。他就是一种字符集。类似的还有什么GBK,GB-2312,Unicode。。。什么的,还有这两天文中出现的UTF-8。

字符集是为了更好的识别中文、日文、英文、希腊语等各种不同的语言在计算机设备上展示。对于常用的字符进行了编码,这个编码就是字符集。字符集确定了文字的存储方式。不同的字符集编码可能不同,但也有相同。例如我国的GBK字符集是GB-2312字符集的超集,其中包含有GB-2312的字符编码。

字符集相当于是计算机中人类的语言。举个例子:

我说的是英文,所以我存储的时候要用英文文字来存储。 如果我说的是中文,用英文字符来存储的话。那么人们就看不懂也看不明白,就是我们所说的乱码。 因为字符集太多了,足够有几十种上百种之多。所以我们不需要了解太多的字符集的知识,甚至不需要了解字符集到底是如何编成人类可见字符的。

学习MySQL需要掌握的字符集知识

我们只需要了解:

  • 常用字符集
  • 数据库中我们用什么字符集

常用英文字符集:

字符集 说明 字节长度
ASCII 美国标准信息交换码 单字节
GBK 汉字内码扩展规范 双字节
Unicode 万国码 4字节
UTF-8 Unicode的可变长度字符编码 1到6个字节

*:把GBK放着这里英文字符集里面应该是因为GBK字符集中有完整的英文字符吧。

ASCII码

虽然经常说,但还是再稍微了解下吧。当然,这部分也可以跳过,其实我感觉关系不大。

ASCII 码使用指定的7 位或8 位二进制数组合来表示128 或256 种可能的字符。标准ASCII 码也叫基础ASCII码,使用7 位二进制数来表示所有的大写和小写字母,数字0 到9、标点符号, 以及在美式英语中使用的特殊控制字符。 其中: 0~31及127(共33个)是控制字符或通信专用字符(其余为可显示字符),如控制符:LF(换行)、CR(回车)、FF(换页)、DEL(删除)、BS(退格)、BEL(响铃)等;通信专用字符:SOH(文头)、EOT(文尾)、ACK(确认)等;ASCII值为8、9、10 和13 分别转换为退格、制表、换行和回车字符。它们并没有特定的图形显示,但会依不同的应用程序,而对文本显示有不同的影响。 32~126(共95个)是字符(32是空格),其中48~57为0到9十个阿拉伯数字。 65~90为26个大写英文字母,97~122号为26个小写英文字母,其余为一些标点符号、运算符号等。

GBK

GBK 向下与 GB 2312 编码兼容。是中华人民共和国定义的汉字计算机编码规范。早期版本为GB2312。所以之前说GBK是GB-2312的超集。、除了兼容GB2312外,它还能显示繁体中文,还有日文的假名等。

Unicode

Unicode(统一码、万国码、单一码)Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。以满足跨语言、跨平台进行文本转换、处理的要求。

UTF-8

是一种针对Unicode的可变长度字符编码,也是万国码。因为UNICODE比ASCII占用大一倍的空间,而对ASCII来说高字节的0对他毫无用处。为了解决这个问题,就出现了一些中间格式的字符集,他们被称为通用转换格式,即UTF(Universal Transformation Format)

实际工作中要使用的编码

在中文中常用的字符集分为utf-8和GBK

实际使用的如下:

字符集 说明
gbk_chinese_ci 简体中文, 不区分大小写
utf8_general_ci Unicode (多语言), 不区分大小写

观察(图一)的特点你会发现,MySQL字符集由三个部分组成: 1.字符集 2.语言 3.类型

最后的bin是指二进制字符集,后面的ci是指存储排序时不区分字符的大小写。

注意:
mysql在写utf-8的时候写的是utf8。不加中间的中横线。
不信自己回头去看,前面的实例代码里全都是utf8

图一

big5什么鬼??大五码?? 好吧,百度了下还真是。大五码。。台湾、香港用的编码

utf8_general_ci像这种名称的编码集,貌似意思就是把utf-8这个字符集具体再细分了,目的应该 也是为了提高数据库效率吧。

表引擎

MySQL的强大之处在于它的插件式存储引擎,我们可以基于表的特点使用不同的存储引擎,从而达到最好的性能。

如果你足够熟悉,并且有一定工作经验后。你还可以使用阿里巴巴和网易开源出来的MySQL引擎在自己的服务器中使用。

mysql在创建表的时候,可以指定对应的引擎。

在mysql命令中使用:

show engines;

show engines;

可以查看到当前服务器支持的所有引擎。

我们介绍几种常用的引擎和了解几个不常用的引擎。避免未来在实际工作中看到一些引擎不知道概念。

引擎名称 说明
MyISAM 常用,读取效率很高的引擎。
InnoDB 常用。写入,InnoDB的最大特色就是支持了ACID兼容的事务(Transaction)功能,类似于PostgreSQL
Archive 不常用,归档引擎,压缩比高达1:10,用于数据归档。
NDB 不常用,主要在MySQL集群服务器中使用。

MyISAM

不支持事务,表锁(表级锁,加锁会锁住整个表),支持全文索引,操作速度快。常用于读取多的业务。 myisam存储引擎表由myd和myi组成。.myd用来存放数据文件,.myi用来存放索引文件。 对于myisam存储引擎表,mysql数据库只缓存其索引文件,数据文件的缓存由操作系统本身来完成。

InnoDB

1.支持事务,主要面向在线事务处理(OLTP)方面的应用。 2.行锁设计,支持外键,即默认情况下读取操作不加锁。

InnoDB是为处理巨大数据量时的最大性能设计。

注:
行锁:写入、更新操作的时候将这一行锁起来,不让其他人再操作了。
表锁:写入、更新操作时,将表给锁起来不让其他人再操作了。
事务:同时操作多个数据,若其中的一个数据操作失败。可回滚到操作之前。常用于银行、电商、金融等系统中。

索引

使用索引的优点

索引看着挺高大上的一个名字,说白了就是我们书目录。

假如你用新华字典来查找“张”这个汉字,不使用目录的话,你可能要从新华字典的第一页找到最后一页,可能要花二个小时。字典越厚呢,你花的时间就越多。现在你使用目录来查找“张”这个汉字,张的首字母是z,z开头的汉字从900多页开始,有了这条线索,你查找一个汉字可能只要一分钟,由此可见索引的重要性。

索引用于快速找出在某个列中有一特定值的行。

不使用索引,MySQL必须从第1条记录开始然后读完整个表直到找出相关的行。表越大,花费的时间越多。如果表中查询的列有一个索引,MySQL能快速到达一个位置去搜寻到数据文件的中间,没有必要看所有数据。

当然索引也不易过多,索引越多写入,修改的速度越慢。因为,写入修改数据时,也要修改索引。

MySQL的索引类型

索引类型 功能说明
普通索引 最最最基本的索引,无任何限制
唯一索引 某一行启用了唯一索引则不准许这一列的行数据中有重复的值。针对这一列的每一行数据都要求是唯一的
主键索引 它是一种特殊的唯一索引,不允许有空值。一般是在建表的时候同时创建主键索引,常用于用户ID。类似于书中的页码
全文索引 对于需要全局搜索的数据,进行全文索引

增加普通索引(index)

类型 说明
基础语法 alter table 表 add index(字段);
代码示例 alter table money add index(username);
示例解释 为money表的username字段增加索引

增加唯一索引(unique)

类型 说明
基础语法 alter table 表名 add unique(字段);
代码示例 alter table money add unique(email);
示例解释 为money表的email字段增加唯一索引

增加全文索引(fulltext)

……我都懒得说了,跟上两个一模一样,自己举一反三,套吧。

增加主键索引(primary key)

同上。。。

类型 说明
基础语法 alter table 表 add primary key(字段);
代码示例 alter table money add primary key(id);
示例解释 为money表的id字段增加主键索引

创建表时也可以声明索引

创建表时可在创建表语句后加上对应的类型即可声明索引:

PRIMARY KEY(字段)
INDEX [索引名] (字段)
FULLTEXT [索引名] (字段)
UNIQUE[索引名] (字段)

注:中括号中的索引名,代表可选。

整体示例如下:

CREATE TABLE test (
id INT NOT NULL ,
username VARCHAR(20) NOT NULL ,
password INT NOT NULL ,
content INT NOT NULL ,
PRIMARY KEY (id),
INDEX pw (password),
UNIQUE (username),
FULLTEXT (content)
) ENGINE = InnoDB;

看这段代码的意思貌似是说创建表语句中加索引时,索引不分先后顺序。

增删改查

增 - 插入记录

插入记录有两个基本的语法。

插入记录语句一

类型 说明
基础语法 insert into 表名 values(值1,值2,值n);
代码示例 insert into user values(2,‘段志斌’,’女’);
示例说明 向user表中插入id为2,姓名为段志斌,性别女的一条记录。

插入记录语句二

类型 说明
基础语法 insert into 表名(字段1,字段2,字段n) values(值1,值2,值n);
代码示例 insert into user(id,user,sex) values(213,’段志斌’,1);
示例说明 向user表中插入id为213,username为段志斌,性别为1

基本语法1和基本语法2的区别是: 1.基本语法1的插入语句,表中有多少个字段就必须要插入多少个值。一个不能多,一个也不能少。若有默认值,不想传,可以写上null。 2.基本语法2中,除非有必填字段必须要写入值外。如果有默认值的不想写可以忽略不写。mysql会自动补主默认值。 3.基本语法2中,以user(id,username,sex)字段顺序为值的顺序。

假设有一张user表,我们对字段、字段说明、类型和字段选填和必须状态进行说明,表结构如下:

字段 id username email password sex
中文说明 编号 用户名 邮箱 密码 性别
类型说明 int varchar(50) varchar(60) varchar(32) tinyint
默认值说明 自增 必填 选填字段,默认值为123@mumu0934.cn 选填字段 必填字段

按照基本语法一写上表中的插入语句:

insert into user values(null,‘李文凯’,‘liwenkai@phpxy.com’,null ,1);

注意 1.可以不指定字段名称,但是 values 后面的顺序应该和表字段的排序一致。 2.有默认值的字段可以不写,则为默认值。 3.如果有默认值或者可空字段不想传入具体值,可写入null。 4.数据格式必须要与表规定的数据格式一致。

按照基本语法二写上表中的插入语句:

insert into user(username,sex) values(‘李文凯’,1);

注意 1.ID为自增的自段可以不用传入值,每插入一次这个字段的值会自动向上加1。 2.有默认值和可为空的字段可不传 3.以表user(username,sex)的插入顺序为准 4.基本语法二为更常用的用法

基本语法变形:一次插入多条记录

insert into user(username,password,sex)
values(‘黄晓明’, ‘abcdef’, 1),
( ‘angelababy’, ‘bcdeef’, 0),
( ‘陈赫’, ‘123456’, 1),
(‘王宝强’, ‘987654’, 1);

查询记录

在讲解查询前,我为大家准备了一个数据表。这个表中存放着银行的余额和用户的基本信息。

我们定义了一个表结构,表名为money。

创建表的语句如下:

CREATE TABLE money (
id INT NOT NULL AUTO_INCREMENT ,
username VARCHAR(50) NOT NULL ,
balance FLOAT NOT NULL ,
province VARCHAR(20) NOT NULL ,
age TINYINT UNSIGNED NOT NULL ,
sex TINYINT NOT NULL ,
PRIMARY KEY (id(10))
) ENGINE = InnoDB CHARACTER SET utf8;

表结构和数据展示如下: 懒得敲表格了,直接截图。。嘻嘻嘻

注: balance 是指余额 province 是指省份

基础查询

类别 说明
基本语法 select * from 表名;
代码示例 select * from money;
示例说明 查询money表中所有字段中的所有结果

注:”*” 是一种正则表达式的写法,表示匹配所有,上面的查询语句和下面的是等价:

mysql> select * from money;
±—±----------±--------±----------±----±----+
| id | username | balance | province | age | sex |
±—±----------±--------±----------±----±----+
| 1 | 李文凯 | 120.02 | 湖北 | 29 | 1 |
| 2 | 范冰冰 | 260.23 | 山东 | 40 | 0 |
| 3 | 黄晓明 | 150.86 | 山东 | 40 | 1 |
| 4 | 井柏然 | 810 | 辽宁 | 27 | 1 |
| 5 | 李冰冰 | 20.15 | 黑龙江 | 43 | 0 |
| 6 | 成龙 | 313 | 山东 | 63 | 1 |
| 7 | 杨幂 | 123 | 北京 | 30 | 0 |
| 8 | 刘诗诗 | 456 | 北京 | 29 | 1 |
| 9 | 柳岩 | 23.4 | 湖南 | 36 | 0 |
| 10 | 赵本山 | 3456 | 辽宁 | 63 | 1 |
| 11 | 汪峰 | 34.32 | 北京 | 44 | 1 |
| 12 | 郭德纲 | 212 | 天津 | 43 | 1 |
±—±----------±--------±----------±----±----+
12 rows in set (0.00 sec)

指定字段查询

类别 详细解释
基本语法 select 字段 from 表名;
代码示例 select id,username,balance from money;
示例说明 查询money 表中id,username,balance字段中的所有结果。

可以看出来,其实select * from money;命令其实也是本命令的一种形式而已。

mysql> select id,username, balance from money;
±—±----------±--------+
| id | username | balance |
±—±----------±--------+
| 1 | 李文凯 | 120.02 |
| 2 | 范冰冰 | 260.23 |
| 3 | 黄晓明 | 150.86 |
| 4 | 井柏然 | 810 |
| 5 | 李冰冰 | 20.15 |
| 6 | 成龙 | 313 |
| 7 | 杨幂 | 123 |
| 8 | 刘诗诗 | 456 |
| 9 | 柳岩 | 23.4 |
| 10 | 赵本山 | 3456 |
| 11 | 汪峰 | 34.32 |
| 12 | 郭德纲 | 212 |
±—±----------±--------+
12 rows in set (0.00 sec)

查询单个字段不重复记录distinct

类别 详解
基本语法 select distinct 字段 from表名;
代码示例 select distinct age from money;
示例说明 查询money表中年龄唯一的所有结果
mysql> select distinct age deptno from money;
±-------+
| deptno |
±-------+
| 29 |
| 40 |
| 27 |
| 43 |
| 63 |
| 30 |
| 36 |
| 44 |
±-------+
8 rows in set (0.00 sec)

条件查询Where

类别 详解
基本语法 select 字段 from 表名 where 条件;
代码示例 select * from money where age = 29;
示例说明 查询money表中年龄为29的所有结果
mysql> select * from money where age = 29;
±—±----------±--------±---------±----±----+
| id | username | balance | province | age | sex |
±—±----------±--------±---------±----±----+
| 1 | 李文凯 | 120.02 | 湖北 | 29 | 1 |
| 8 | 刘诗诗 | 456 | 北京 | 29 | 1 |
±—±----------±--------±---------±----±----+
2 rows in set (0.00 sec)

where后可加条件

比较运算符

结果集中将符合条件的记录列出来。上面的例子中,where 后面的条件是一个字段的 ‘=’。 除此之外,还可以使用>、<、>=、<=、!=等比较运算符;

符号 说明
> 大于
< 小于
>= 大于等于
<= 小于等于
!= 不等于
= 等于

是的没错,只要你学过任何一门编程语言,这个基本通用的。基础好的都懂。

逻辑运算符

多个条件还可以使用 or 、 and 等逻辑运算符进行多条件联合查询

符号 说明
or 或者
and 并且

我们来看一下多个条件的例子:

类型 详细内容
示例 select * from money where id<10 and province = ‘湖北’;
说明 查询所有id小于10并且province是湖北的记录。
mysql> select * from money where id <10 and province=‘湖北’;
±—±----------±--------±---------±----±----+
| id | username | balance | province | age | sex |
±—±----------±--------±---------±----±----+
| 1 | 李文凯 | 120.02 | 湖北 | 29 | 1 |
±—±----------±--------±---------±----±----+
1 row in set (0.00 sec)

结果集排序

类别 详解
基本语法 select 字段 from 表名 order by 字段 排序关键词
代码示例 select id,username,balance from money order by balance desc;

排序用到的关键词:

关键字 说明
asc 升序排列,从小到大(默认)
desc 降序排列,从大到小

在 select 出来之后的结果集中排序使用 order by ,其中 desc 和 asc 是排序顺序中的关键字。desc 表示按照指定字段进行降序排列,asc 表示升序排列,如果不写关键字默认升序排列。

mysql> select id,username, balance from money order by balance desc;
±—±----------±--------+
| id | username | balance |
±—±----------±--------+
| 10 | 赵本山 | 3456 |
| 4 | 井柏然 | 810 |
| 8 | 刘诗诗 | 456 |
| 6 | 成龙 | 313 |
| 2 | 范冰冰 | 260.23 |
| 12 | 郭德纲 | 212 |
| 3 | 黄晓明 | 150.86 |
| 7 | 杨幂 | 123 |
| 1 | 李文凯 | 120.02 |
| 11 | 汪峰 | 34.32 |
| 9 | 柳岩 | 23.4 |
| 5 | 李冰冰 | 20.15 |
±—±----------±--------+
12 rows in set (0.00 sec)

多字段排序

order by后面其实还可以跟多个不同的字段排序,并且排序字段的不同结果集的顺序也不同,如果排序字段的值一样,则值相同的字段按照第二个排序字段进行排序。

类别 详细解释  
基本语法 select 字段 from 表 order by 字段1 排序关键词,… …字段n desc asc;
代码示例 select id,username, balance from money order by balance desc,age asc;  
实例详解 查询money表中的id,username,balance字段,按照余额进行降序排序,若余额全都一样,则再使用age进行升序排序  

注:如果第一个字段已经将结果给排好。第二个字段排序字段不生效。本例中,第二个字段无效

mysql> select id,username, balance from money order by balance desc,age asc;
±—±----------±--------+
| id | username | balance |
±—±----------±--------+
| 10 | 赵本山 | 3456 |
| 4 | 井柏然 | 810 |
| 8 | 刘诗诗 | 456 |
| 6 | 成龙 | 313 |
| 2 | 范冰冰 | 260.23 |
| 12 | 郭德纲 | 212 |
| 3 | 黄晓明 | 150.86 |
| 7 | 杨幂 | 123 |
| 1 | 李文凯 | 120.02 |
| 11 | 汪峰 | 34.32 |
| 9 | 柳岩 | 23.4 |
| 5 | 李冰冰 | 20.15 |
±—±----------±--------+
12 rows in set (0.00 sec)

结果集限制limit

对于查询或者排序后的结果集,如果希望只显示一部分而不是全部,则可以使用 limit 关键字对结果集进行数量限制。

类别 详细解释
基本语法 select 字段 from 表 limit 数量;
示例 select id,username, balance from money limit 5;
示例说明 显示money表中前五个用户的id,username, balance字段
mysql> select * from money limit 5;
±—±----------±--------±----------±----±----+
| id | username | balance | province | age | sex |
±—±----------±--------±----------±----±----+
| 1 | 李文凯 | 120.02 | 湖北 | 29 | 1 |
| 2 | 范冰冰 | 260.23 | 山东 | 40 | 0 |
| 3 | 黄晓明 | 150.86 | 山东 | 40 | 1 |
| 4 | 井柏然 | 810 | 辽宁 | 27 | 1 |
| 5 | 李冰冰 | 20.15 | 黑龙江 | 43 | 0 |
±—±----------±--------±----------±----±----+
5 rows in set (0.00 sec)

限制结果集排序

|类别|详细解释| |—–|———–| |基本语法|select 字段 from 表 order by 字段 关键词 limit 数量 |代码示例|select id,username, balance from money order by balance desc limit 5; |示例说明|按照钱来排序,显示前五个最有钱的用户的id,username, balance

不过是排序和限制结果集的同时使用而已。

mysql> select id,username, balance from money order by balance desc limit 5;
±—±----------±--------+
| id | username | balance |
±—±----------±--------+
| 10 | 赵本山 | 3456 |
| 4 | 井柏然 | 810 |
| 8 | 刘诗诗 | 456 |
| 6 | 成龙 | 313 |
| 2 | 范冰冰 | 260.23 |
±—±----------±--------+
5 rows in set (0.00 sec)

结果集区间选择

假设我从第0条开始取了3条记录。又想再从第3条开始取3条记录。再想从第6条开始取4条记录怎么办?

这时候就需要使用到结果集区间选择。

类型 详解
基本语法 select 字段 from 表 limit 偏移量,数量
代码示例 select id,username, balance from money limit 0,3;
示例说明 从第一条开始取三条记录

注:第一条记录为0。

mysql> select id,username, balance from money limit 0,3;
±—±----------±--------+
| id | username | balance |
±—±----------±--------+
| 1 | 李文凯 | 120.02 |
| 2 | 范冰冰 | 260.23 |
| 3 | 黄晓明 | 150.86 |
±—±----------±--------+
3 rows in set (0.00 sec)

从第三条开始再取三条呢?

mysql> select id,username, balance from money limit 3,3;
±—±----------±--------+
| id | username | balance |
±—±----------±--------+
| 4 | 井柏然 | 810 |
| 5 | 李冰冰 | 20.15 |
| 6 | 成龙 | 313 |
±—±----------±--------+
3 rows in set (0.00 sec)

通过上面的这个思路,显示就完成了分页。 难道说我要做一个html页面实现分页,要用PHP这样操作数据库来完成吗? 每页显示10条记录,那么:

第1页为 limit 0,10 第2页为 limit 10,10 第3页为 limit 20,10 依此类推… …

统计类函数的使用

1.如果我们想知道总用户数怎么办? 2.查询谁是数据表里的首富怎么办? 3.如果我们想知道用户的平均金额怎么办? 4.如果我们想知道所有用户的总金额怎么办?

统计类函数最常用的我们有四个:

函数 说明
sum 求和
count 统计总数
max 最大值
min 最小值
avg 平均值

注:当然你知道其他的mysql函数也可以使用。不过,在实际工作中,大公司的很多大中型项上很少使用,他们都有专门的计数服务器。因为,mysql的计算量本身很大,为了减少压力通常我们将实际的计算任务交给业务服务器或其他服务器来完成。

类别 详解
基本语法 select 函数(字段) from 表
代码示例 select count(id) from money;
示例说明 查询money表的id总数

sum max min avg函数同理

count函数

mysql> select count(id) from money;
±----------+
| count(id) |
±----------+
| 12 |
±----------+
1 row in set (0.00 sec)

你还可以给字段取别名哟!使用as关键字。

mysql> select count(id) as zongshu from money;
±--------+
| zongshu |
±--------+
| 12 |
±--------+
1 row in set (0.00 sec)

zongshu = count(id) 的意思吧。可以这么理解,但是这种写法只是纯粹的方便理解。

查询平均金额

mysql> select avg(balance) from money;
±-------------------+
| avg(balance) |
±-------------------+
| 498.24833393096924 |
±-------------------+
1 row in set (0.00 sec)

查询总金额

mysql> select sum(balance) from money;
±------------------+
| sum(balance) |
±------------------+
| 5978.980007171631 |
±------------------+
1 row in set (0.00 sec)

查询最大金额

mysql> select max(balance) from money;
±-------------+
| max(balance) |
±-------------+
| 3456 |
±-------------+
1 row in set (0.00 sec)

查询最小金额

mysql> select min(balance) from money;
±-------------------+
| min(balance) |
±-------------------+
| 20.149999618530273 |
±-------------------+
1 row in set (0.00 sec)

分组 group by

我们拿金额表里面的省份进行分组数据,分组数据后你会发现。有相同的省份会去掉。即,一个省份为一个组。

类别 详解
基本语法 select * from 表名 group by 字段;
代码示例 select * from money group by province;
示例说明 按照地区进行分组
mysql> select * from money group by province;
±—±----------±--------±----------±----±----+
| id | username | balance | province | age | sex |
±—±----------±--------±----------±----±----+
| 7 | 杨幂 | 123 | 北京 | 30 | 0 |
| 12 | 郭德纲 | 212 | 天津 | 43 | 1 |
| 2 | 范冰冰 | 260.23 | 山东 | 40 | 0 |
| 1 | 李文凯 | 120.02 | 湖北 | 29 | 1 |
| 9 | 柳岩 | 23.4 | 湖南 | 36 | 0 |
| 4 | 井柏然 | 810 | 辽宁 | 27 | 1 |
| 5 | 李冰冰 | 20.15 | 黑龙江 | 43 | 0 |
±—±----------±--------±----------±----±----+

统计分组(分类)各总数:

mysql> select deptno, count(1) from emp group by deptno;
±-------±---------+
| deptno | count(1) |
±-------±---------+
| 1 | 1 |
| 2 | 5 |
| 3 | 1 |
| 5 | 4 |
±-------±---------+
4 rows in set (0.04 sec)

统计省份数量后再进行分组显示

mysql> select count(province),province from money group by province;
±----------------±----------+
| count(province) | province |
±----------------±----------+
| 3 | 北京 |
| 1 | 天津 |
| 3 | 山东 |
| 1 | 湖北 |
| 1 | 湖南 |
| 2 | 辽宁 |
| 1 | 黑龙江 |
±----------------±----------+
7 rows in set (0.00 sec)

在分组基础上进行统计

with rollup用的很少。这个知识点设置为了解级别。 它的主要功能是对于分组的数据进行统计后,再进行一次总数统计。

意思是有点儿难吗???

类别 详解
基本语法 select * from 表名 group by 字段 with roll up;
代码示例 select count(province),province from money group by province with rollup;
示例说明 对分组的数再次进行统计

这个到这里我还是没怎么看明白,看看实际执行效果应该会懂吧。

在上面的基础上统计总数,下例结果中,最后多了一个12 NULL。

//为什么会多啊12 Null????

mysql> select count(province),province from money group by province with rollup;
±----------------±----------+
| count(province) | province |
±----------------±----------+
| 3 | 北京 |
| 1 | 天津 |
| 3 | 山东 |
| 1 | 湖北 |
| 1 | 湖南 |
| 2 | 辽宁 |
| 1 | 黑龙江 |
| 12 | NULL |
±----------------±----------+
8 rows in set (0.00 sec)

为什么最后一行会多个12 NULL呢?? 貌似,12=3+1+3+1+1+2+1 也就是显示出来的这一列数值之和,而province字段由于都是字符,所以值是null。 这就是上面说的的总数统计啊。。。懂了~

结果再过滤having

having语句与where有相似之处但也有区别,都是设定条件的语句。

having 是筛选组 而where是筛选记录。 //怎么理解???

类别 详解
基本语法 select* from 表名 group by 字段 having 条件;
代码示例 select count(province) as result ,province from money group by province having result > 2;
示例说明 对地区分组并统计总数,将分组结果中大于2的分组地区显示出来
mysql> select count(province) as result ,province from money group by province having result >2;
±-------±---------+
| result | province |
±-------±---------+
| 3 | 北京 |
| 3 | 山东 |
±-------±---------+
2 rows in set (0.00 sec)

这是筛选出了省份数大于2的。其过程简易理解为: result = 省份出现次数 province字段来自于money表 用provincegroup by分组 然后having条件限制为只显示result>2的记录。。 嗯,应该就是这么理解的。。

整体使用SQL

我们在上面的语句中都是单一使用的某些语句,没有整体使用过。

我们现在将语句进行整合后,配合使用一次。整体的SQL语句配合使用的语法结构如下:

SELECT
[字段1 [as 别名1],[函数(字段2) ,]…字段n]
FROM 表名
[WHERE where条件]
[GROUP BY 字段]
[HAVING where_contition]
[order 条件]
[limit 条件]
//注:上面的语句中可以[] 代表可选。

最终的语法总结如下:

关键词 说明
select 选择的列
from 表名
where 查询的条件
group by 分组属性,having 分组过滤的条件
order by 排序属性
limit 起始记录位置,取记录的条数

我们进行一次整体的给合使用,查询money表字段:id,username,balance,province 要求id>1 余额大于50,使用地区进行分组。我们使用用户id进行降序,要求只准显示3条。

最后将SQL语句写成,查询出来的结果如下:

mysql> select id,username,balance,province from money where id > 1 and balance > 50 group by province order by id desc limit 3;
±—±----------±--------±---------+
| id | username | balance | province |
±—±----------±--------±---------+
| 12 | 郭德纲 | 212 | 天津 |
| 7 | 杨幂 | 123 | 北京 |
| 4 | 井柏然 | 810 | 辽宁 |
±—±----------±--------±---------+
3 rows in set (0.00 sec)

多表联合查询

很多时候在实际的业务中我们不只是查询一张表。 1.在电子商务系统中,查询哪些用户没有购买过产品。 2.银行中可能查询违规记录,同时查询出用户的 ??账户信息?? 3.查询中奖信息和中奖人员的基本信息。

//别问我第二条后半句要查询用户的什么?我也不知道。原文资料缺失,我也没办法。。。

以上列出的情况我们就需要把两张表在一起进行查询。

而上述业务中需要多表联合在一起查询才能有结果,而多表联合查询的本质是:表连接

表连接

当需要查询多个表中的字段时,就可以使用表连接来实现。表联接分为内连接外连接

1.内连接:将两个表中存在联结关系的字段符合联结关系的那些记录形成记录集的联结。 2.外连接:会选出其他不匹配的记录,分为外左联结外右联结

准备了两个模拟的数据表: 1.用户表,存放用户信息 2.订单表,存放哪个用户购买过哪个商品

user表创建语句

CREATE TABLE IF NOT EXISTS user (
uid int(11) NOT NULL,
username varchar(30) NOT NULL,
password char(32) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS order_goods (
oid int(11) NOT NULL,
uid int(11) NOT NULL,
name varchar(50) NOT NULL,
buytime int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

user表数据如下:

uid username password
1 景甜 123456
2 王小二 245667
3 李文凯 1235531
4 井柏然 123455
5 范冰冰 5abcwa
6 黄晓明 abcdeef
7 anglebaby caption
8 TFBOYS abcdwww
9 安小超 12tfddwd
10 高小峰 3124qwqw
11 李小强 323fxfvdvd
12 李小超 311aqqee
13 韩小平 121rcfwrfq
14 宋小康 123123tcsd
15 佟小刚 3cxvdfs

order_goods数据如下:

oid uid name buytime
1 10 苹果鼠标 1212313
2 3 iPhone 12S 123121241
3 12 雪碧 13232333
4 15   34242123
5 3 iPhone 键盘 12123413

注意: 在上表order_goods表中uid是指user表中的uid字段。上表中oid为1的数据行,uid为10的用户。为user表中uid为10的用户:高小峰。该用户购买了商品为苹果鼠标。购买时间buytime为一个unix时间戳。

看来unix时间戳也有必要看下

内连接

基本语法一:

类别 详解
基本语法 select 表1.字段 [as 别名],表n.字段 from 表1 [别名],表n where 条件;
代码示例 select user.uid,user.username as username,order_goods.oid,order_goods.uid,order_goods.name as shopname from user,order_goods where user.uid = order_goods.uid;
示例说明 查询商品表中哪些用户购买过商品,并将用户信息显示出来

注:下例中from 表使用到了表别名,注意仔细看,理解。 由于表名太长,每次写的时候容易写错。我们可以在(from处开始)表名后直接跟上一个简写英文字符串。然后在前面拼接字段时,直接使用简写字符串.字段即可。比如下面这段代码这样。。

mysql> select u.uid ,u.username as username,o.oid,o.uid,o.name as shopname from user u,order_goods o where u.uid = o.uid;
±----±----------±----±----±--------------+
| uid | username | oid | uid | shopname |
±----±----------±----±----±--------------+
| 10 | 高小峰 | 1 | 10 | 苹果鼠标 |
| 3 | 李文凯 | 2 | 3 | iphone 12s |
| 12 | 李小超 | 3 | 12 | 雪碧 |
| 15 | 佟小刚 | 4 | 15 | |
| 3 | 李文凯 | 5 | 3 | iphone 键盘 |
±----±----------±----±----±--------------+
5 rows in set (0.00 sec)

就这样,这就显示出了所有买过东西的用户以及他们买的商品信息。

基本语法二:

类别 详解
基本语法 select 表1.字段 [as 别名],表n.字段 from 表1 INNER JOIN 表n on 条件;
代码示例 select user.uid ,user.username as username,order_goods.oid,order_goods.uid,order_goods.name as shopname from user inner join order_goods on user.uid = order_goods.uid;
示例说明 查询商品表中哪些用户购买过商品,并将用户信息显示出来

结果与基本语法1中一致。

mysql> select user.uid ,user.username as username,order_goods.oid,order_goods.uid,order_goods.name as shopname from user inner join order_goods on user.uid = order_goods.uid;
±----±----------±----±----±--------------+
| uid | username | oid | uid | shopname |
±----±----------±----±----±--------------+
| 10 | 高小峰 | 1 | 10 | 苹果鼠标 |
| 3 | 李文凯 | 2 | 3 | iphone 12s |
| 12 | 李小超 | 3 | 12 | 雪碧 |
| 15 | 佟小刚 | 4 | 15 | |
| 3 | 李文凯 | 5 | 3 | iphone 键盘 |
±----±----------±----±----±--------------+
5 rows in set (0.00 sec)

个人更倾向于语法一,感觉语法一更为简单、好记、容易理解点。。

外连接

类别 详解
基本语法 select 表1.字段 [as 别名],表n.字段 from 表1 LEFT JOIN 表n on 条件;
代码示例 select * from user left join order_goods on user.uid = order_goods.uid;
示例说明 以左边为主,查询哪些用户未购买过商品,并将用户信息显示出来

//什么叫做左边表?? 第一个表吗?语句里面左边的表??

外连接又分为左连接和右连接,具体定义如下。

左连接:显示出来的结果表中除了匹配行外,还包括左表有的但右表中不匹配的行,对于这样的行,从右表被选择的列设置为NULL

LEFT JOIN或LEFT OUTER JOIN 左外连接的结果集包括 LEFT OUTER子句中指定的左表的所有行,而不仅仅是联接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值。

那么这条命令,凡是满足user.uid = order_goods.uid这一条件的,都会显示出来,不论在order_goods表中有无匹配的记录。

关于内连接、左外连接、右外连接、交叉连接区别可以参考这篇文章,讲的很清楚了。

mysql> select * from user left join order_goods on user.uid = order_goods.uid;
±----±----------±-----------±-----±-----±--------------±----------+
| uid | username | password | oid | uid | name | buytime |
±----±----------±-----------±-----±-----±--------------±----------+
| 10 | 高小峰 | 3124qwqw | 1 | 10 | 苹果鼠标 | 1212313 |
| 3 | 李文凯 | 1235531 | 2 | 3 | iphone 12s | 123121241 |
| 12 | 李小超 | 311aqqee | 3 | 12 | 雪碧 | 13232333 |
| 15 | 佟小刚 | 3cxvdfs | 4 | 15 | | 34242123 |
| 3 | 李文凯 | 1235531 | 5 | 3 | iphone 键盘 | 12123413 |
| 1 | 景甜 | 123456 | NULL | NULL | NULL | NULL |
| 2 | 王小二 | 245667 | NULL | NULL | NULL | NULL |
| 4 | 井柏然 | 123455 | NULL | NULL | NULL | NULL |
| 5 | 范冰冰 | 5abcwa | NULL | NULL | NULL | NULL |
| 6 | 黄晓明 | abcdeef | NULL | NULL | NULL | NULL |
| 7 | anglebaby | caption | NULL | NULL | NULL | NULL |
| 8 | TFBOYS | abcdwww | NULL | NULL | NULL | NULL |
| 9 | 安小超 | 12tfddwd | NULL | NULL | NULL | NULL |
| 11 | 李小强 | 323fxfvdvd | NULL | NULL | NULL | NULL |
| 13 | 韩小平 | 121rcfwrfq | NULL | NULL | NULL | NULL |
| 14 | 宋小康 | 123123tcsd | NULL | NULL | NULL | NULL |
±----±----------±-----------±-----±-----±--------------±----------+
16 rows in set (0.00 sec)

右连接:显示出来的结果表中除了匹配行外,还包括右表有的但左表中不匹配的行,对于这样的行,从左表被选择的列设置为NULL

类别 详解
基本语法 select 表1.字段 [as 别名],表n.字段 from 表1 right JOIN 表n on 条件;
代码示例 select * from user right join order_goods on user.uid = order_goods.uid;
示例说明 查询商品表中哪些用户购买过商品,并将用户信息显示出来
mysql> select * from user right join order_goods on user.uid = order_goods.uid;
±-----±----------±---------±----±----±--------------±----------+
| uid | username | password | oid | uid | name | buytime |
±-----±----------±---------±----±----±--------------±----------+
| 10 | 高小峰 | 3124qwqw | 1 | 10 | 苹果鼠标 | 1212313 |
| 3 | 李文凯 | 1235531 | 2 | 3 | iphone 12s | 123121241 |
| 12 | 李小超 | 311aqqee | 3 | 12 | 雪碧 | 13232333 |
| 15 | 佟小刚 | 3cxvdfs | 4 | 15 | | 34242123 |
| 3 | 李文凯 | 1235531 | 5 | 3 | iphone 键盘 | 12123413 |
±-----±----------±---------±----±----±--------------±----------+
5 rows in set (0.00 sec)

子查询

有时候,当我们查询的时候,需要的条件是另外一个select语句的结果,这时就需要使用子查询。用于子查询的关键字包括in、not in、=、!=、exists、not exists等。

这个概念貌似还好理解点。就是一层查询还套着一层查询呗。

类别 详解
基本语法 select 字段 from 表 where 字段 in(条件)
示例1 select * from user where uid in (1,3,4);
示例1说明 按照id 查询指定用户
示例2 select * from user where uid in (select uid from order_goods);
示例2说明 将购买过商品的用户信息显示出来

示例1:

mysql> select * from user where uid in (1,3,4);
±----±----------±---------+
| uid | username | password |
±----±----------±---------+
| 1 | 景甜 | 123456 |
| 3 | 李文凯 | 1235531 |
| 4 | 井柏然 | 123455 |
±----±----------±---------+
3 rows in set (0.00 sec)

示例2:

mysql> select * from user where uid in (select uid from order_goods);
±----±----------±---------+
| uid | username | password |
±----±----------±---------+
| 10 | 高小峰 | 3124qwqw |
| 3 | 李文凯 | 1235531 |
| 12 | 李小超 | 311aqqee |
| 15 | 佟小刚 | 3cxvdfs |
±----±----------±---------+
4 rows in set (0.00 sec)

记录联合

使用 union 和 union all 关键字,将两个表的数据按照一定的查询条件查询出来后,将结果合并到一起显示。两者主要的区别是把结果直接合并在一起,而 union 是将 union all 后的结果进行一次distinct,去除重复记录后的结果。

UNION用的比较多,union all是直接连接,取到得是所有值,记录可能有重复 union 是取唯一值,记录没有重复

类别 详解
基本语法 select语句1 union[all] select语句2
代码示例 select * from user where uid in (1,3,4);
示例说明 将商品表中的用户信息和用户表中的用户信息的结果组合在一起
mysql> select uid from user union select uid from order_goods;
±----+
| uid |
±----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
| 10 |
| 11 |
| 12 |
| 13 |
| 14 |
| 15 |
±----+
15 rows in set (0.00 sec)

今天太晚了。多表联合查询没好好看。明天一大早再看一遍吧。。。看懂才行。今晚有点儿敷衍了事了。。

预告:明天的知识点少了很多。会容易理解和学习。哈哈哈。最难熬的阶段就要过去了。。。

今天又花了五六个小时,才把这些基本都弄懂了。。。

更新记录(修改内容)

更新数据我们已经说过。需要修改内容,修改银行卡余额,修改装备信息的时候都需要使用到update,修改语句。

修改(也叫更新)语句的基本语语法如下:

类别 详解
基本语法 update 表名 set 字段1=值1,字段2=值2,字段n=值n where 条件;
代码示例 update money set balance=balance-500 where userid = 15;
示例说明 修改money表中,userid为15的余额在原余额上-500

假设下面这一个表,表结构如下:

userid username balance
1 李文凯 50000.00
2 黄晓明 150000000.00
15 马云 15000.00
16 段志斌 1234131.00
mysql> select * from money where userid=15;
±-----±---------±---------+
| userid |username| balance |
±-----±---------±---------+
| 15 | 马云 | 15000.00 |
±-----±------±------------+
1 row in set (0.00 sec)

###使用 update 语句进行记录更新

先执行下试试

update money set balance=balance-500 where userid = 15;

mysql> update money set balance=balance-500 where userid = 15;
Query OK, 1 row affected (0.35 sec)
Rows matched: 1 Changed: 1 Warnings: 0

这样,这个userid是15的,他的balance就会减少500 不信看看

mysql> select * from money where userid=15;
±-----±---------±---------+
| userid |username| balance |
±-----±---------±---------+
| 15 | 马云 | 14500.00 |
±-----±------±------------+
1 row in set (0.00 sec)

多字段修改更新

这个直接上示例:

mysql> update money set balance=balance-500,username=‘李文凯’ where userid = 15;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0

好简单的吧,在字段后面加,继续写就行了。。。

mysql> select * from money where userid=15;
±-----±---------±---------+
| userid |username| balance |
±-----±---------±---------+
| 15 |李文凯 | 14500.00 |
±-----±------±------------+
1 row in set (0.00 sec)

同时对两个表进行更新

类别 详解
基本语法 update 表1.表2 set 字段1=值1,字段2=值2,字段n=值n where 条件;
代码示例 update money m,user u m.balance=m.balance*u.age where m.useid=u.id;
代码详解 修改表money,令m为money表的别名;u为user表的别名,将表m的余额改为m表的balance*用户表的age。执行条件是:m.userid = u.id
mysql> update money m,user u m.balance=m.balance*u.age where m.userid=u.id;

注解: ①:money和user是要同时更新的两张表,money后的m是money表的别名;user后的u同理。 ②:m.balance=m.balance*u.age 一句是将money表中balance的值重新赋值为money表中balance的值与user表中age的值的积。

删除记录

哈哈哈哈哈,最最最简单的来了。这才是最爽的。MySQL从删库到跑路。。。😄

使用 delete 删除记录

类别 详解
基本语法 delete from 表 [where 条件];
代码示例 delete from user where id>10;
示例说明 删除掉用户表中id大于10的所有用户

user表结构如下:

id username balance
1 李文凯 50000.00
2 黄晓明 150000000.00
15 马云 15000.00
16 段志斌 1234131.00
mysql> delete from user where id = 1;
Query OK, 1 row affected (0.08 sec)

删除掉了id为1的,李文凯这一行的记录。

清空整表记录

delete和truncate是一样的,但它们有一点不同,那就是DELETE可以返回被删除的记录数,而TRUNCATE TABLE返回的是0。

如果一个表中有自增字段,使用truncate table 这个自增字段将起始值恢复成1.

更清楚的直观解释:

truncate table命令将快速删除数据表中的所有记录,但保留数据表结构。这种快速删除与delete from 数据表的删除全部数据表记录不一样,delete命令删除的数据将存储在系统回滚段中,需要的时候,数据可以回滚恢复,而truncate命令删除的数据是不可以恢复的

详细原文

类别 详解
基本语法 truncate table 表名;
代码示例 truncate table user;
示例说明 情况表的数据,并且让自增的id从1开始自增

切记 1.删除时一定要记住加上where条件,不然会清空掉整个表的记录。 2.删除重要数据前一定要备份、备份、备份。

数据库控制语句(DCL)

创建库用户

数据库用户管理在简书另一文中有详细讲解,并有强行数据库root用户密码方法。在此不再赘述。文中还穿插了不少数据库的其他知识。亦可自己通过其他渠道了解学习。

添加权限(grant)

类别 详解
基本语法 grant 权限 on 库.表 to ‘用户’@’主机’ ;
代码示例 grant select,insert on test.* to ‘duan’@’localhost’;
示例说明 给予用户duan,在本机连接test库查询权限和写入权限

注:可以针对一个用户增加多条权限。

删除权限(revoke)

类别 详解
基本语法 revoke 权限 on 库.表 from ‘用户’@’主机’;
代码示例 revoke select, insert on test.* from ‘duan’@‘localhost’;
代码说明 撤销用户duan,在本机数据库连接test库中查询权限和写入权限

参数说明

符号 详解
grant all 授予所有权限
revoke all 撤销所有权限
权限 on 指定与这些权限相关的库.表
‘用户’@’主机’ 主机里面若为%。任意来源的主机均可以使用这个用户来访问

创建数据库用户duan ,具有对test数据库中所有标的 select / insert 权限

示例:增加权限

mysql> grant select, insert on test.* to ‘liwenkai’@‘localhost’ identified by ‘4311’;
Query OK, 0 rows affected (0.00 sec)

示例:移除权限

mysql> revoke insert on test.* from ‘liwenkai’@‘localhost’;
Query OK, 0 rows affected (0.30 sec)

注: 上面的一些语句用的较少。你可以将知识点的掌握级别设置为了解级别。 更多的时候,权限设置项特别多,记不住具体的命令。更多的时候使用专门的工具来操作权限。

常用工具简介

纯文字介绍性内容,可以作为扩展了解。可看可不看。我也就照搬复制了,错别字也不会管的。。。

MySQL我们可以使用官方提供的工具和第三方工具来进行管理。工具各有优缺点。 并且工具的使用办法也各有不同,工具的使用,中文、可视化、窗口操作简单。所以我们不会专门花几十页去讲解工具的使用。 有一些复杂的SQL语句完成不用再记忆。例如:权限、建表、备份等。直接使用可视化的工具更加有利于提高工作效率。

我们会为大家推荐最方便使用的几个工具。

常用的工具有:

  1. phpMyAdmin(中文,推荐)
  2. Navicat(中文,推荐)
  3. mysql workbench(英文,官方出品,在设计E-R图时推荐)

phpMyAdmin

phpMyAdmin 是一个以PHP为基础,以Web-Base方式架构在网站主机上的MySQL的数据库管理工具,让管理者可用Web接口管理MySQL数据库。借由此Web接口可以成为一个简易方式输入繁杂SQL语法的较佳途径,尤其要处理大量资料的汇入及汇出更为方便。其中一个更大的优势在于由于phpMyAdmin跟其他PHP程式一样在网页服务器上执行,但是您可以在任何地方使用这些程式产生的HTML页面,也就是于远端管理MySQL数据库,方便的建立、修改、删除数据库及资料表。也可借由phpMyAdmin建立常用的php语法,方便编写网页时所需要的sql语法正确性。 你的服务器直接php运行环境。下载安装包,解压访问地址即可开始使用。

Navicat

Navicat提供多达 7 种语言供客户选择,被公认为全球最受欢迎的数据库前端用户界面工具。 它可以用来对本机或远程的 MySQL、SQL Server、SQLite、Oracle 及 PostgreSQL 数据库进行管理及开发。 Navicat的功能足以符合专业开发人员的所有需求,而且对数据库服务器的新手来说又相当容易学习。有了极完备的图形用户界面 (GUI),Navicat 让你可以以安全且简单的方法创建、组织、访问和共享信息。 Navicat适用于三种平台 - Microsoft Windows、Mac OS X 及Linux。它可以让用户连接到任何本机或远程服务器、提供一些实用的数据库工具如数据模型、数据传输、数据同步、结构同步、导入、导出、备份、还原、报表创建工具及计划以协助管理数据。

MySQL WorkBench

MySQL Workbench是一款专为MySQL设计的ER/数据库建模工具。它是著名的数据库设计工具DBDesigner4的继任者。你可以用MySQL Workbench设计和创建新的数据库图示,建立数据库文档,以及进行复杂的MySQL 迁移。

原文后面还有个附录:学习MySQL常用的英文单词 但是完全就是列出了一些单词而已,连个超链接都没。还不如大家遇到了自己去百度。。所以就不用啦。