第1章 初识MySQL
1什么是收据库
(数据库DataBase,DB)是一个长期存储在计算机内的、有组织的、有共享的、统一管理的数据集合,
在关系数据库中,数据库表是一系列二维数组的集合。
主键:用于唯一地标识表中的每一条记录。可以定义表中一列后者多列为主键,主键列上的值唯一且不为空。
数据定义语言(DDL):DROP、CREATE、ALTER
数据操作语言(DML):INSERT、UPDATE、DELETE
数据查询语言(DQL):SELECT
数据控制语言(DCL):GRANT、REVOKE、COMMIT、ROLLBACK
第3章 数据库的基本操作
3.1 创建数据库
创建数据库是在系统磁盘中划分一块区域用于数据的存储和管理。
n 语法:CREATE DATABASE database_name;
n 查看数据库的定义:SHOW CREATE DATABASE database_name;
3.2 删除数据库
删除数据库就是将已存在的库从磁盘删除。且不能恢复
DROP DATABASE database_name;
3.3 数据库存储引擎
数据库管理系统(DBMS)使用数据引擎进行创建、查询、更新和删除数据的操作。不同的存储引擎提供不同的存储机制。索引技巧、锁定水平
查看系统所有存储引擎 SHOW ENGINES
MySQL的存储引擎:
InnoDB
MyISAM
MeMory
Merge
Archive
FeDerated
CSV
BLACKHOLE
3.3.2 InnoDB存储引擎
1) InnoDB给MySQl提交了具有提交、回滚和崩溃恢复能力的事务安全(ACID兼容)存储引擎。InnoDB锁定在行级别并且也是在SELECT语句中提供一个类似Oracle的非锁定读[l1] 。在SQL查询中,可以自由的将InnoDB类型的表与其他MySQL的表混合起来。甚至在同一个查询中也可以混合。
2) InnoDB是处理巨大数据量的最大性能设计。他的CPU效率可能是任何其他基于磁盘的关系数据库引擎所不能匹配的
3) InnoDB存储引擎完全与MySQl服务器整合,InnoDB存储引擎为在主内存中缓存数据和索引而维护它自己的缓冲池。InnoDB将它的表和索引存在一个逻辑表中,表空间可以包含数个文件
4) InnoDB支持外键完整性约束。创建表时,如果没有显形在表定义时指定主键,InnoDB会为每一行生成一个6B的ROWID,并以此为主键。
5) InnoDB被用在众多需要高性能的大型数据库站点。InnoDB不创建目录,使用InnoDB时,MySQl将在MySQL数目下创建一个名为ibdata1的10MB[l2] 大小的自动扩展数据文件,以及两个名为ib_logfile0和ib_logfile1的5MB大小的日志文件
3.3.3 MyISAM存储引擎
MyISAM基于ISAM的存储引擎,并对其进行扩展。它是在Web、数据存储和其他应用环境下常用的存储引擎之一。MyISAM拥有较高的插入、查询速度,但不支持事物。
n 特性:
1) 在支持大文件的文件系统和操作系统上被支持
2) 当把删除、更新及插入操作混合使用的时候,动态尺寸的行产生更少碎片。这要通过合并相邻被删除的块,以及若下一个块被删除,就扩展到下一个块来自动完成。
3) 每个MyISAM表的最大索引数是64,这可以通过重新编译来改变。每个索引最大的列数是16个。
4) 最大键长度是1000B,也可以通过编译来改变。对于键长度超过250B的情况,一个超过1024B的键将被用上
5) BLOB和TEXT列可以被索引。
6) NULL值被允许在索引的列中。这个值占每个键的0~1个字节。
7) 所有数字键值以高字节优先被存储以允许一个更高的索引压缩。
8) 每表一个AUTO_INCREMENT列的内部处理。MyISAM为INSERt和UPDATE操作自动更新这一列。这使得AUTO_INCREMENT列更快。在序列顶的值被删除后就不能再使用。
9) 可以将数据文件和索引文件放在不同目录
10) 每个字符列可以有不同的字符集
11) 有VARCHAR的表可以固定或动态记录长度
12) VARCHAR和CHAR列可以多达64KB
使用MyISAM引擎创建数据库,将生产3个文件。文件的名称以表的名字开始,扩展名支出文件类型:frm 文件存储表定义,数据文件的扩展名为.MYD,索引文件的扩展名.MYI
3.3.4 MEMORY存储引擎
MEMORY存储引擎将表中的数据存储到内存,为查询和引用其他表数据提供快速访问。
特性:
1) MEMORY表的每个表可以可以有多达32个索引,每个索引16列,以及500B的最大键长度。
2) MEMORY存储引擎执行HASH和BTREE索引
3) 可以在一个MEMORY表中有非唯一键
4) MEMORY表使用一个固定的记录长度格式
5) MEMORY不支持BLOB或TEXT列
6) MEMORY支持AUTO_INCREMENT列和对可包含NULL值的列的索引
7) MEMORY表在所有客户端之间共享
8) MEMORY表内容被存在内容中,内存时MEMORY表和服务器在查询处理时的空闲中创建的内部表共享。
9) 当不再需要MEMORY表的内容时,要释放被MEMORy表使用的内存,应该执行 DELETE FROM 或 TRUNCATE TABLE,或者删除整个表
3.3.5 存储引擎的选择
功能 |
MyISAM |
Memory |
InnoDB |
Archive |
存储限制 |
256TB |
RAM |
64TB |
None |
支持事物 |
NO |
NO |
YES |
NO |
支持全文搜索 |
YES |
NO |
NO |
NO |
支持数索引 |
YES |
YES |
YES |
NO |
支持哈希索引 |
NO |
YES |
NO |
NO |
支持数据缓存 |
NO |
N/A |
YES |
NO |
支持外检 |
NO |
NO |
YES |
NO |
- 如果要提供提交、回滚和崩溃恢复能力的事物安全能力,并要求实现并发控制,选择InnoDB
- 如果数据表主要用来插入和查询记录,则选择MyISAM
- 如果存放临时数据,数据量不大,且对数据安全性要求不高可以选择将数据保存在内存中的Memory引擎,MySQL中使用该引擎作为临时表,存放查询的中间结果,
- 如果只有INSERT和SELECT操作,可以选择Archive引擎,Archive支持高并发的插入操作,但不是事物安全的,Archive适合存储归档数据如记录日志
3.4 数据库的增、删
CREATE DATABASE database_name
DROP DATABASE database_name;
查看系统中所有的存储引擎:
SHOW ENGINES;
查看默认存储引擎
SHOW VARIABLES LIKE 'storage_engine'
第4章 数据表的基本操作
4.1创建表
CREATE TABLE <表名>
(
字段1 数据类型 [列级别的约束条件] [默认值],
字段2 数据类型 [列级别的约束条件] [默认值],
字段3 数据类型 [列级别的约束条件] [默认值],
. .
.
[表级别约束条件]
)engine='engine_name',charset=’字符集’;
- 使用主键
在定义时使用主键
字段名 数据类型 PRIMARY KEY [默认值]
在定义完所有列之后指定主键
[CONSTRAINT <约束名>] PRIMARY KEY [字段名]
多字段联合主键
PRIMARY KEY [字段1,字段2,。。。。。。]
- 使用外键
外键是用来在两个表之间创建关联的,可以是一列,或者多列,一个表可以有一个或者多个外键。 一个表的外键可以为空值,若不为空值,则每一个外键值必须等于另一个表中主键的某个值。
外键对应另外一个表的主键。外键的主要作用是保证数据引用的完整性,定义外键后,不允许删除 另一个表中具有关联关系的行
[CONSTRAINT <外键名>] FOREIGN KEY <字段名1>[,字段名2,。。。。]
REFERENCES <主表名> 主键列1 [主键列2,.....]
- 使用非空约束
字段名 数据类型 NOT NULL
- 使用唯一性约束
定义完直接使用唯一约束
字段名 数据类型 UNIQUE
定义完所有列之后指定唯一约束
[CONSTRAINT <约束名>] UNIQUE (<字段>)
- 使用默认约束
如果插入一条新纪录时没有为这个字段赋值,那么系统就会自动为这个字段赋值
字段名 数据类型 DEFAULT 默认值
- 设置表的属性值自动增加
字段名 数据类型 AUTO_INCREMENT
4.2 查看数据表结构
desc table_name;
show CREATE TABLE table_name;
NULL:表示该列是否可存储null值
Key:表示该列是否已经有索引
Default:表示是否有默认值,默认值是多少
Extra:获取给定列的有关信息,如自增。
4.3 修改表
- 修改表明
ALTER TABLE <旧表名> RENAME [TO] 新表明
- 修改字段的数据类型
ALTER TABLE <表名> MODIFY <字段名> <数据类型>
- 修改字段名
ALTER TABLE <表名> CHANGE <旧字段名> <新字段名> <新数据类型>
- 添加字段
ALTER TABLE <表名> ADD <新字段名> <数据类型> [约束条件] [FIRST | AFTER 已存在字段名]
- 删除字段
ALTER TABLE <表名> DORP <字段名>
- 修改字段的排列位置
ALTER TABLE <表名> MODIFY <字段1> <数据类型> FIRST | AFTER <字段2>;
- 更改表的存储引擎
查看当前表的存储引擎:SHOW CREATE TABLE table_name;
修改:ALTER TABLE <表名> ENGINE = <更改后的存储引擎>
外键约束是用来保证数据的参照完整性,如果表之间需要关联外键,却指定了不同的存储引擎,这些表之间是不能创建外键约束的。
- 删除表的外键约束
ALTER TABLE <表名> DROP FOREIGN KEY <外键约束名>
4.4 删除表
- 删除没有被关联的表
DROP TABLE [IF EXISTS] 表1,表2,表3.....
- 删除被其他表关联的主表
关联表的情况下,如果直接删除父表,会失败,是因为直接删除,将会破坏表的参照完整性。 如果必须删除,可以删除出字表,再删除父表。如果想单独删除父表。只需要将关联表的外键约束 取消,就可删除父表
1.删除字表中的外键列
2.删除父表
第5章 数据类和运算符
5.1 数据类型介绍
5.1.1整数类型
数值型数据主要用来存数字。整数类型的属性字段可以添加AUTO_INCREMENT自增约束条件。
TINYINT 1个字节。
SMALLINT 2个字节。
MEDIUMINT 3个字节。
INT(INTEGER) 4个字节。
BIGINT(大整数) 8个字节。
INT(11)这11表示的是该数据类型指定的显示宽度,数值的位数小于指定的宽度时,会由空格填充,如果插入大于显示宽度,只要该值不超过该类型整数的取值范围,数值依然可以插入而且能够显示出来
5.1.2浮点数类型和定点数类型
浮点数分为两种:单精度浮点类型(FLOAT)和双精度浮点类型(DOUBLE)。定点类型只有一种:DECIMAL。浮点类型和定点类型都可以用(M,N)来表示,其中M称为精度,表示总共的位数;N称为标度,是表示最小数的位数。DECIMAL实际上是以串存放。
在MySQL中,定点数以字符串形式存储,在对精度要求比较高的时候(如货币,科学数据等)
使用DECIMAL的类型比较好。另外两个浮点数进行减法和比较运算时也容易出问题,所以在使用浮点型时要注意
5.1.3 日期与时间类型
YEAR
YEAR存储时只需要一个字节,
以4位字符串或者4位数字格式表示YEAR 范围为 1901~2155
以2位字符串表示 "00"~"69" 代表2000~2069 "70"~"99" 带包1970~1999
以2位数字表示表示YEAR 1-69代表 2001~2069 70~99 代表 1970~1999
TIME:
TIME类型用于只需要时间信息的值,在存储时需要3个字节。格式"HH:MM:SS"的字符串,TIME类型的取值范围为-838:59:59~838:59:59,TIME类型不仅可以用于表示一天的时间,还可能是某个事件过去的时间或者两个事件之间的时间间隔。TIME可以是“HHMMSS”格式的、没有间隔的字符串,或者,HHMMSS格式的数据,假定是有意义的时间。
为TIME分配简写值时注意啊例如数值1122
如果没有冒号,MySQL解释值时,假定最右边的两位是秒,解释为过去的时间1122 解释为00:11:22
如果有冒号则解释为当天的时间则解释为11:22:00
DATE:
DATE类型用在仅需要日期值时,没有时间部分,在存储时需要3个字节。在给DATE类型的字段赋值时,可以使用字符串类型或者数字类型的数据插入,但要符合DATE的日期格式
格式:
字符串类型 ""、""、""、""
数字类型YY-MM-DD 或者YYMMDD
函数 CURRENT_DATE 和NOW() 插入当前系统日期
DATETIME
DATETIME类型用在需要同时包含日期和事件信息的值,存储时需要8个字节,格式"YYYY-MM-DD HH:MM:SS",在给DATETIME类型的字段赋值时,可以 使用字符串类型或者数字类型的数据插入。
MySQL允许“不严格” 语法。任何标点符号都可以用作日期部分或者时间部分之间的间隔符。
TIMESTAMP
TIMESTAMP的显示格式与DATETIME相同,但是TIMESTAMP列的取值范围小于DATETIME的取值范围。
DATETIME存储日期数据时,按实际输入的格式存储,与时区无关,而TIMESTAMP值的存储时以UTC格式保存的,存储时对当前时区进行转换,检索时再转回当前时区。就是说,查询时,根据当前时区的不同,显示的时间值不同。
5.1.4 文本字符串类型
字符串类型除了存储字符串数据外,还可以存储比如图片、声音的二进制数据。
MySQL中支持两类字符串数据:文本字符串、二进制字符串。
MySQl中文本字符串有:CHAR、VARCHAR、TEXT、ENUM、SET
VARCHAR和TEXT类型是变长类型,对于其存储需求取决于列值的实际长度,而不是取决于类型的最大可能尺寸。
1.CHAR和VARCHAR
CHAR(M)为固定长度字符串,在定义是指定字符串列长。导尿管保存时再右侧填充空格以达到指定的长度。M表示类长度。当检索CHAR值时,尾部的空格被删除。
VARCAHR(M)的长度可变的字符串,M表示最大列长度。M的返回时0~65535。VARCHAR的最大实际长度由最长的行的大小和使用的字符集确定,而其实际上占用的空间为字符串的实际长度加1.VARCHAR在值保存和检索时尾部的空格仍保留
2.TEXT类型
保存如 文章内容,评论等。当保存或查询时,不删除尾部空格。
3.ENUM类型
是一个字符串对象,其值在创建时再列规定中枚举一个值
语法:字段名 ENUM ('值1','值2','值3'......)
ENUM类型的字段在取值时,只能在制定的枚举列表中取(insert的值的枚举 的索引),而且一次只能去一个,如果创建的成员中有空格时,其尾部的空格将自动被删除,ENUM值在内部用整数表示,每一个枚举值均有一个索引,列表值所允许的成员值从1开始编号。ENUM值一种列索引顺序排列,并且空字符串排在飞空字符串前,NULL值排在其他所有枚举值前
4.SET类型
SET是一个字符串对象,可以有零个或多个值,最多可以有64个成员。
语法:字段名 SET('值1','值2','值3'.....'值n')
与ENUM类型形同,SET值在内部用整数表示,列表中每一个值有一个索引编号。当创建表时,SET成员值的尾部空格将会自动删除。ENUM类型字段只能从定的列中选择一个值插入,SET类型的列可以从定义的列值中选择多个字符,如果插入SET字段中的列值重复,则MySQL自动删除重复的值,插入SET字段值的顺序并并不重要,MySQL会在存入数据时,按照定义的顺序显示。
5.1.5二进制字符串类型
1.BIT类型
BIT类型是位字段类型。M表示每个值的位数,范围为1~64如果M省略,默认为1.如果为BIT(M)列分配的值的长度小于M位,在值的左边用0填充。
2.BINARY和VARBINARY类型
列名称 BINNARY(M)或者VARBINARY(M)
BINNARY长度固定,不足长度右边用\0补齐
VARBINARY长度可变
3.BLOB
是一个二进制大对象,用来存储可变两的数据。
5.2 如何选择数据类型
1.CHAR 和VARCHAR之间的选择
1) 区别:
CHAR是固定长度字符,VARCHAR是可变长度字符。
检索时CHAR会自动删除插入数据的尾部空格,VARCHAR不会删除尾部空格
CAHR是固定长度,索引它的处理速度比VARCHAR的速度快,但是缺点就是浪费空间,对存储不大,速度有要求的则用CHAR反之用VARCHAR
2) 存储引擎对CHAR和VARCAHR的影响
对于MyISAM存储引擎:最好使用固定长度的数据列代替可变长度的数据列。这样可以是整个表静态化,从而使数据检索更快,用空间换时间
对于InnoDB存储引擎:使用可变长度的数据列,因为InnoDB数据表的存储格式不分固定长度和可变长度,因此使用CHAR不一定比使用VARCHAR更好,单由于VARCHAR是按照实际的长度存储的,比较节省空间,所以对磁盘I/O和数据存储总量比较好
2.ENUM 和SET
ENUM 是存储在多选一类型 SET是多选多类型
ENUM和SET的值是一字符串形式出现的,但在内部,MySQL以数值的形式存储。
3.BLOB和TEXT
都是存储大容量信息的。BLOB主要存储图片、音频文件。TEXT只能存储纯文本
5.3 比较云算符
1.等于运算符 =
等号用来判断 数字、字符串、和表达式是否相等。相等返回1 不等返回0;比较字符串不区分大小 写,不能用空值NULL的判断。
2完全等于 <=>
比等于加个判空处理,两边都为空则返回1,否则0,
3.不等于 != 后者<>
用来判断 数字、字符串、和表达式是否不相等,相等返回0 不等返回1
4.ISNUll和IS NOT NULL 检验值是否为空
5.BETWEEN..AND...
6.LEAST语法 LEAST(值1,值2,......,值n);返回最小值。
7.GREATEST(值1,值2,.....);返回最大值。
8.IN 、NOT IN
9.LIKE
10.REGEXP用来匹配字符串 expr REGEXP 匹配条件
通配符:
'^' 匹配以该字符后面字符开头的字符串
'$' 匹配以该字符后面的字符结尾的字符串。
'.'匹配任意单个字符
'[...]' 匹配在方括号内的任意字符。[abc] 匹配a,b,c[a-z]匹配任一字母,[0-9]匹配任意数字
'*'匹配零个多多个在他前面的字符。例如X*,匹配人一多个X.[0-9]*,匹配任意多个数字。
在MySQL中需要输入特殊符号如单引号、双引号、或者反斜线时 注意使用转义字符\
第6章 MySQL函数
6.1 数学函数
n 绝对值函数ABS(X)
n 返回圆周率的函数PI();
n 平方根SQRT(X)
n 求余MOD(X,Y);
n 获取整数的函数
CEIL(X)返回不小于X的最小整数值
CEILING(X)返回不小于X的最小整数值
FLOOR(X) 返回不小大X的最小整数值
n 获取随机数的函数
RAND()
RAND(X)返回一个随机浮点数值v,范围在0到1,、
不带参数的RAND()每次产生的随机数值不同,当参数x相同时,将产生相同的随机 数,不同参数产生不同随机数
n ROUND(x)返回最接近参数x的整数
n ROUND(X,Y)返回最接近参数x的整数,其值保留到小数点后面y位
n TRUNCATE(X,Y) 返回别舍去至小数点后y位的数字x
n 符号函数SIGN(x):返回参数的符号,x的值为负、零或正时返回结果一次为-1、0或1.
n 幂运算
POW(X,y)、POWER(X,y)返回x的y次乘方的结果值
EXP(X)返回e的x乘方后的值
对数运算
LOG(X)LOG10(X)
6.3字符串函数
n CHAR_LENGTH(str):返回字符串中的字符个数
n LENGTH(str):返回字符串的字节长度。
n CONCAT(s1,s2....)连接参数产生新字符串
n CONCAT_WS (X,s1,s2):拼接 X为分隔符
n INSERT(s1,x,len,s2):替换字符串,返回s1
n 返回指定长度的字符串
LEFT(s,n):返回字符串s开始的最左边n个字符
RIGHT(s,n)
n 填充字符串
LPAD(s1,len,s2)
RPAD(s1,len,s2)
在s1左/右拼接s2
n 删除空格LTRIM(s)RTRIM(s)TRIM(s)
n 删除指定字符串的函数TRIM(s1 FROM s):删除s中两端所有的字符串s1,
n 重复生成字符:REPEAT(s,n)
n 空格函数SPACE(n):返回一个有n个空格组成的字符串
n 替换函数REPLACE(s,s1,s2)使用字符串s2代替字符串s中所有的字符串s1.
n 比较字符串大小的函数STRCMP(s1,s2):如所有的字符串均相同,则返回0,如根据当前分类次序,第一个参数小于第二个,则返回-1,其他返回1.
n 获取字符串函数SUBSTRING(s,n,len)、MID(s,n,len):两个作用相同,从字符创的s的n位置开始截取长度为len的字符。
n 匹配子串开始的函数:LOCATE(str1,str)、POSITION(str1 IN str)、INSTR(str,str1):3个函数作用相同。返回字符串str1在字符串str中的开始位置。
n 字符串逆序的函数REVERSE(s):将字符串反转。
n 返回指定位置的字符串的函数:ELT(N,值1,值2,值3.....);N为数字类型几返回该位置的值。
n 返回指定字符串的位置的函数:FIELD(s,s1,s2,s3......);返回字符串s在列表s1,s2...中第一次出现位置。
n 返回子串位置的函数FILD_IN_SET(s1,s2):返回字符串s1在字符串列表s2中出现的位置,字符串列表是一个由多个逗号分开的字符串组成的列表;
n 选取字符串的函数MAKE_SET(X,s1,s2,....):返回由X的二进制数指定的相应位置的字符串组成的字符串。
6.4 日期函数
n 获取当前日期/当前时间
CURDATE()/CURRENT_DATE()作用相同,返回当前日期 YYYYMMDD
CURTIME()/CURRENT_TIME()作用相同,返回当前时间 HHMMSS
CURRENT_TIME()/CURRENT_DATE()+0将日期/时间转成数值型
CURRENT_TIMESTAMP()/LOCALTIME()/NOW()/SYSDATE(); YYYYMMDD HHMMSS
n 获取月份的函数
MONTH(date)返回date对应的月份
MONTH(date)返回date对应的月份的应为全名
n 获取星期的函数
DAYNAME(d)返回d对应的工作日的英文名称
DAYOFWEEK(d)返回d对应的一周中的索引
WEEKDAY(d)返回d对应的工作日的索引
n 获取星期数的函数
WEEK(d):计算日期d是一年中的第几周
WEEKOFYEAR(d):计算某天是一年中的第几周
n 获取天数的函数
DAYOFWEEK(d)返回d是一年中的第几天
DAYOFMONTH(d)返回是一个月中的第几天
n 获取年份、季度、小时、分钟和秒钟的函数
YEAR(date) 返回date对应的年份
QUARTER(date) 返回date对应一年中的季度值。
MINUTE(time) 返回time对应的分钟数。
SECOND(time) 返回time对应的秒数
n 获取日起指定值的函数
EXTRACT(type FORM date): type取值 YEAR YEAR_MONTH
时间和描红转换函数
TIME_TOS_SEC(time): 转成秒
SEC_TO_TIME(seconds):转成HH:MM:SS
n 计算日期和时间的函数
DATE_ADD
n 将日期和事件格式转化的函数
DATE_FORMAT(date,format)
TIME_FORMAT(time,format)
GET_FORMAT(val_type,format_type);
6.5 条件判断函数
n IF(expr,v1,v2):如果表达式expr是TRUE则返回v1,否则返回v2
n IFNULL(v1,v2):假如v1不为null,则返回v1,否则返回v2。
n CASE expr WHEN v1 THEN r1 [WHEN v2 THEN r2] [ELSE rn] END:如果表达式expr值等某个vn则返回对应位置THEN后面的结果。
6.6 系统信息
n VERSION()返回指定MySQL服务器版本的字符串。
n CONNECTION_ID():返回MySQL服务器当前连接的次数。每个连接都有唯一的ID
n SHOW PROCESSLIST;/SHOW FULL PROCESSLIST: 显示有哪些线程在运行,不仅可以查看当前所有的连接数,还可以查看当前的连接状态,帮助识别出那些有问题的查询语句等。DATABASE()和SCHEMA()函数返回使用utf8字符集的默认(当前)数据库名称。
n 获取用户名函数:USER(),CURRENT_USER、SYSTEM_USER()、SESSION_USER()
n 获取字符串的字符集合排序方式:CHARSET(str) 返回字符串 str自变量的字符集;COLLATION(str)返回字符串str的字符排列方式
n 获取最后一个自动生成的ID值的函数
LAST_INSERT_ID()
6.7 加/解密函数
n 加密函数:PASSWORD(str)/MD(str),ENCODE(str,pswd_str);ENCODE使用pwsd_str作为密码加密str。
n 解密函数:DNCODE(crypt_str,pswd_str);
6.8 其他函数
n 不同进制转化函数:CONV(N,from_base,to_base)
n IP地址和数字相互转换的函数:INET_ATON(expr)
n 加锁函数和解锁函数:
GET_LOCk(str,timeout)设法使用字符串str给定的名字得到一个锁,持续时间timeout秒。
RELEASE_LOCK(str)解开被GET_LOCK()获取的,用字符串str所命名的锁,
IS_FREE_LOCK(str)检查锁是否可用
IS_USED_LOCK(str) 检查锁是否正在使用
n 重复执行指定操作的函数
BENCHMARK(count,expr)重复count次执行表达式expr
n 改变字符集的函数
CONVERT(str USING 字符集)
n 改变数据类型的函数
CAST(x,AS type) CONVERT(X,type)
第7章 查询数据
- 条件查询中where后面同时有AND和OR时,AND的优先级高于OR
- 查询结果去重distinct
- 在分组查询时,使用GROUP_CONCAT(column_name);将每个分组中column_name字段的所有种类值显示出来;
- HAVING和WHERE区别?
HAVING在数据分组后进行过滤来分组,而WHERE在分组之前用来选择记录。
GROUP BY子句中使用WITH ROLLUP
- 使用WITH ROLLUOP 关键字之后,在所有查询出的分组记录之后增加一条记录,该记录计算查询出的所有记录的总和
limit
limit [偏移量] 行数
偏移量:从什么位置开始,如果偏移量没有,则默认从0开始
正则查询
选项 |
说明 |
例子 |
^ |
匹配文本的开始字符 |
‘^b’ 匹配以b开头的字符串 |
$ |
匹配文本的结束字符 |
‘st$’匹配以st结尾的字符串 |
. |
匹配任意一个字符 |
‘b.t’匹配任何b和t之间有一个字符的字符串 |
* |
匹配0个或者多个在它前面的字符 |
‘f*n’匹配字符串n前面有任意个字符串f |
+ |
匹配前面的字符1次后者多次 |
ba+匹配以b开头后面紧跟至少有一个a |
<字符串> |
匹配包含指定字符串的文本 |
|
[字符集] |
匹配字符集中的任何一个字符 |
[az] 匹配 a或者z |
[^] |
匹配不在括号中的任何字符 |
[^abc]匹配任意不含a、b、c的字符串 |
字符串{n,} |
匹配前面的字符串至少n次 |
b{2}匹配2个或者更多个b |
字符串{n,m} |
匹配前面的字符串至少n次,至多m次。如果n为0,此参数为可选参数。 |
b{2,4}匹配最少2个,最多4个b |
第8章 插入删除数据
n 插入数据
insert into table_name(column_list) values (values_list);
n 同时插入语多条记录
insert into table_name(column_list) values (values_list1),(values_list2),(values_list3)....;
n 将查询结果插入列表中
insert into table_name1(column_list1) select (column_list2) from table_name2 where (condition)
n 更新数据
update table_name set column_name1=value1,column_name2=value2..... where (condition);
n 删除数据
delete from table_name [where
删除表中的所有记录还可以使用TRUNCATE TABLE语句,truncate将直接删除原来的表,并重新 创建一个表,其语法是truncate table table_name.truncate直接删除的是表,而不是记录,因此执行速 度比delete快
第9章 索引
索引是用于快速找出在某一列中有一个特定值的行。不使用索引,MySQL必须从第一条记录开始读完整个表,直到找出相关的行。
9.1 索引简介
索引是对数据库表一列或者多列的值进行排序的一种结构,使用索引可以提高数据库中特定数据的查询速度。
9.1.1 索引的含义特定
索引是一个单独的、存储在磁盘上的数据库结构,它们包含着对数据表里所有记录的引用指针。使用索引用于快速找出某个或多个列中有一特定值的行,所有MySQl列类型都可以被索引,对相关列使用索引是提高查询操作速度的最佳途径。
索引是在存储引擎中实现的,因此,每种存储引擎的索引都不一定完全相同,并且每种存储引擎也不一定支持所有索引类型。根据存储引擎定义每个表的最大索引数和最大索引长度。所有的存储引擎支持每个表至少 16个索引。总索引的长度至少为256字节。MySQL的存储类型有两种BTREE和HASH
MyISAM和InnoDB存储引擎只支持BTREE索引,MEMORY/HEAP存储引擎可以支持HASH和BTREE索引。
n 索引的优点:
1.创建唯一索引,保证数据库中每条数据的唯一性。
2.加快查询速度。
3.实现数据的参考完整性方面,可以加速表和表之间的连接。
4.在分组和排序查询时,可以显著减少查询中分组和排序的时间。
n 索引的不足:
1.随着数据量增加创建、维护索引耗费时间。
2.索引耗费磁盘空间,如果有大量的索引,索引文件可能比数据文件更快达到最大文件尺寸。
3.当表中的数据进行增加,删除,修改时,索引也要动态地维护,降低了数据的维护速度。
n 索引的分类
1.普通索引和唯一索引
普通索引是MySQL中的基本索引类型,允许在定义所以的列表中插入重复的值和空值。
唯一索引的值必须唯一,允许有空值。如果是组合索引,则列值的组合必须唯一。主见索引是一种 特殊的唯一索引,不允许有空值。
2.单列索引和组合索引
单列索引即一个索引只包含单个列,一个表可以有多个单列索引。
组合索引指在表的多个字段组合上创建的索引,只有在查询条件
3.全文索引
全文索引类型为FULLTEXT,在定义索引的列上支持值的全文查找,允许在这些索引列中插入重复 值和空值。全文索引可以在CHAR、VARCHAR或者TEXT类型的列上创建。MySQL中只有MyISAM 存储引擎支持全文索引。
4.空间索引
空间索引是对空间数据类型的字段建立索引,MySQL中的空间类型数据有4中
geometry、point、linestring、polygon,MySQL使用SPATIAL关键字进行扩展,使得能够用于创建正 规索引类似的语法创建空间索引,创建空间索引的列,必须将其声明为 NOT NULL,空间索引只能在存 储引擎为MyISAM的表中创建。
9.1.3索引的设计原则。
1.索引并非越多越好,一个表中如果有大量的索引,不仅占用磁盘空间,而且会影响INSERT、DELETE、 UPDATE的语句的性能,因为当表中的数据更改的同时,索引也会进行调整和更改。
2.避免对经常更新的表进行过多的索引,并且索引中的列尽可能少。而对经常用于查询的字段创建索引。
3.数据量小尽量不用索引。
4.在条件表达式中经常用到的不同值较多的列建立索引。
5.当唯一性是某种数据本身的特征时,指定唯一的索引
6.在频繁进行排序和分组的列上建立索引。
9.2 创建索引
9.2.1 创建表的时候创建索引
n 语法
CREATE TABLE table_name [col_name data_type]
[UNIQUE|FULLTEXT|SPATIAL] [INDEX|KEY] [index_name] (col_name [length]) [ASC|DESC]
n 参数解释
- UNIQUE、FULLTEXT、SPATIAL:为可选参数,分别表示唯一索引、全文索引、空间索引。
- INDEX、KEY:为同义词,两者作用相同,用来指定创建索引,
- col_name:需要创建索引的字段列,
- index_name:索引名称
1.创建普通索引
CREATE TABLE table_name(
col_name data_type,
..
INDEX(col_name)
);
使用 explain 语句查看索引是否正确使用,explain语句输出结果的各行解释如下:
select_type:指定所使用的查询类型。取值用SIMPLE、PRIMARY、UNION、SUBQUERY
table:指定数据库读取数据表的字段
type:指定本数据表和其他数据表之间的关系,可能取值有system、const、eq_ref、ref、range、index、 All
prossible_keys:给出MySQL在搜索数据记录时可选用的各个索引。
key:MySQL实际使用得索引。
key_len:索引按字节计算的长度,key_len数值越小,表示越快
ref:给出关联关系中另一个数据表里的数据列的名字。
rows:mysql在执行这个查询时预计会在从这个数据表中读出的数据的个数。
extra:有关联操作有关的信息。
2.创建唯一索引
唯一索引能减少查询索引列操作的执行时间,尤其是对比较庞大的数据表,它与前面的普通索 引类似,不同的就是:索引的值位置,单允许有空值,如果是组合索引,则列值的组合必须唯一。
CREATE TABLE table_name(
col_name data_type,
..
UNIQUE INDEX index_name(col_name)
);
3.创建单列索引
单列索引是指在数据表中某一个字段上创建索引,一张表中可以同时创建多个单列索引。
CREATE TABLE table_name(
col_name data_type,
..
INDEX index_name(col_name)
);
4.创建组合索引
CREATE TABLE table_name(
col_name data_type,
..
INDEX index_name(col_name1,col_name2)
);
组合索引可起几个索引的作用,但是使用时并不是随便查询哪个字段都可使用组合索引,而是遵循 "最左前缀":利用索引最左边的列集来匹配行,这样的列集称为最左前缀。例如id、name、age这三个 字段构成组合索引。索引行中按id/name/age的顺序存放,索引可以搜素下面的字段组合(id,name,age)、 (id,name)、(id)。如果列不构成索引最左的前缀,MySQL不能使用局部索引,如(age)或者(name,age)组合 则不能使用索引。
5.创建全文索引:
FULLTEXT(全文索引)可以用于全文搜索。只有MyISAM存储引擎支持FULLTEXT索引。并且只 为CHAR、VARCHAR、和TEXT列创建索引。
CREATE TABLE table_name(
col_name data_type,
..
FULLTEXT INDEX index_name(col_name1,col_name2)
);
6创建空间索引
CREATE TABLE table_name(
col_name data_type,
..
SPATIAL INDEX index_name(col_name1,col_name2)
);
9.2.2在已经存在的表上创建索引
方式一:
ALTER TABLE table_name ADD [UNIQUE|FULLTEXT|SPATIAL] [INDEX|KEY] [index_name] (col_name[length],....) [ASC|DESC]
方式二:
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name ON table_name (col_name[length],...) [ASC|DESC]
9.3删除索引
方式一:
ALTER TABLE table_name DROP index_name;
方式二:
DROP INDEX index_name ON table_name;
第10章存储过程和函数
一、 存储过程[l5]
含义:一组预先编译好的SQL语句的集合,理解成批处理语句
1、提高代码的重用性
2、简化操作
3、减少了编译次数并且减少了和数据库服务器的连接次数,提高了效率
(一) 、创建语法
DELIMITER $
CREATE PROCEDURE 存储过程名(参数列表)
BEGIN
存储过程体(一组合法的SQL语句)
END
DELIMITER ;
注意:
1、参数列表包含三部分
参数模式 参数名 参数类型
举例:
in stuname varchar(20)
参数模式:
in:该参数可以作为输入,也就是该参数需要调用方传入值
out:该参数可以作为输出,也就是该参数可以作为返回值
inout:该参数既可以作为输入又可以作为输出,也就是该参数既需要传入值,又可以返回值
2、如果存储过程体仅仅只有一句话,begin end可以省略
存储过程体中的每条sql语句的结尾要求必须加分号。
存储过程的结尾可以使用 delimiter 重新设置
语法:
delimiter 结束标记
案例:
delimiter $
(二) 、调用语法
CALL 存储过程名(实参列表);
1.空参列表
#案例:插入到admin表中五条记录
创建存储过程
DELIMITER $
CREATE PROCEDURE myp1()
BEGIN
INSERT INTO admin(username,`password`)
VALUES('john1','0000'),('lily','0000'),('rose','0000'),('jack','0000'),('tom','0000');
END $
DELIMITER ;
调用
CALL myp1()$
2.创建带in模式参数的存储过程
案例1:创建存储过程实现 根据女神名,查询对应的男神信息
CREATE PROCEDURE myp2(IN beautyName VARCHAR(20))
BEGIN
SELECT bo.*
FROM boys bo
RIGHT JOIN beauty b ON bo.id = b.boyfriend_id
WHERE b.name=beautyName;
END $
#调用
CALL myp2('柳岩')$
#案例2 :创建存储过程实现,用户是否登录成功
CREATE PROCEDURE myp4(IN username VARCHAR(20),IN PASSWORD VARCHAR(20))
BEGIN
DECLARE result INT DEFAULT 0;#声明并初始化
SELECT COUNT(*) INTO result#赋值
FROM admin
WHERE admin.username = username
AND admin.password = PASSWORD;
SELECT IF(result>0,'成功','失败');#使用
END $
#调用
CALL myp3('张飞','8888')$
3.创建out 模式参数的存储过程
#案例1:根据输入的女神名,返回对应的男神名
CREATE PROCEDURE myp6(IN beautyName VARCHAR(20),OUT boyName VARCHAR(20))
BEGIN
SELECT bo.boyname INTO boyname
FROM boys bo
RIGHT JOIN
beauty b ON b.boyfriend_id = bo.id
WHERE b.name=beautyName ;
END $
#案例2:根据输入的女神名,返回对应的男神名和魅力值
CREATE PROCEDURE myp7(IN beautyName VARCHAR(20),OUT boyName VARCHAR(20),OUT usercp INT)
BEGIN
SELECT boys.boyname ,boys.usercp INTO boyname,usercp
FROM boys
RIGHT JOIN
beauty b ON b.boyfriend_id = boys.id
WHERE b.name=beautyName ;
END $
#调用
CALL myp7('小昭',@name,@cp)$
SELECT @name,@cp$
4.创建带inout模式参数的存储过程
#案例1:传入a和b两个值,最终a和b都翻倍并返回
CREATE PROCEDURE myp8(INOUT a INT ,INOUT b INT)
BEGIN
SET a=a*2;
SET b=b*2;
END $
#调用
SET @m=10$
SET @n=20$
CALL myp8(@m,@n)$
SELECT @m,@n$
(三) 、删除存储过程
#语法:drop procedure 存储过程名
DROP PROCEDURE p1;
DROP PROCEDURE p2,p3;
(四) 、查看存储过程的信息
DESC myp2;
SHOW CREATE PROCEDURE myp2;
二、 函数
含义:一组预先编译好的SQL语句的集合,理解成批处理语句
1、提高代码的重用性
2、简化操作
3、减少了编译次数并且减少了和数据库服务器的连接次数,提高了效率
区别:
存储过程:可以有0个返回,也可以有多个返回,适合做批量插入、批量更新
函数:有且仅有1 个返回,适合做处理数据后返回一个结果
(一) 创建语法
CREATE FUNCTION 函数名(参数列表) RETURNS 返回类型
BEGIN
函数体
END
注意:
1.参数列表 包含两部分:
参数名 参数类型
2.函数体:肯定会有return语句,如果没有会报错
如果return语句没有放在函数体的最后也不报错,但不建议return 值;
3.函数体中仅有一句话,则可以省略begin end
4.使用 delimiter语句设置结束标记
(二) 调用语法
SELECT 函数名(参数列表)
1.无参有返回
#案例:返回公司的员工个数
CREATE FUNCTION myf1() RETURNS INT
BEGIN
DECLARE c INT DEFAULT 0;#定义局部变量
SELECT COUNT(*) INTO c#赋值
FROM employees;
RETURN c;
END $
SELECT myf1()$
2.有参有返回
#案例1:根据员工名,返回它的工资
CREATE FUNCTION myf2(empName VARCHAR(20)) RETURNS DOUBLE
BEGIN
SET @sal=0;#定义用户变量
SELECT salary INTO @sal #赋值
FROM employees
WHERE last_name = empName;
RETURN @sal;
END $
SELECT myf2('k_ing') $
#案例2:根据部门名,返回该部门的平均工资
CREATE FUNCTION myf3(deptName VARCHAR(20)) RETURNS DOUBLE
BEGIN
DECLARE sal DOUBLE ;
SELECT AVG(salary) INTO sal
FROM employees e
JOIN departments d ON e.department_id = d.department_id
WHERE d.department_name=deptName;
RETURN sal;
END $
SELECT myf3('IT')$
(三) 查看函数
SHOW CREATE FUNCTION myf3;
(四) 删除函数
DROP FUNCTION myf3;
#案例
#一、创建函数,实现传入两个float,返回二者之和
CREATE FUNCTION test_fun1(num1 FLOAT,num2 FLOAT) RETURNS FLOAT
BEGIN
DECLARE SUM FLOAT DEFAULT 0;
SET SUM=num1+num2;
RETURN SUM;
END $
SELECT test_fun1(1,2)$
三、 变量的使用
系统变量:
全局变量
会话变量
自定义变量:
用户变量
局部变量
(一) 系统变量
说明:变量由系统定义,不是用户定义,属于服务器层面
注意:全局变量需要添加global关键字,会话变量需要添加session关键字,如果不写,默认会话级别
使用步骤:
1、查看所有系统变量
show global | [session] variables;
2、查看满足条件的部分系统变量
show global|[session] variables like '%char%';
3、查看指定的系统变量的值
select @@global|[session]系统变量名;
4、为某个系统变量赋值
方式一:
set global|[session]系统变量名=值;
方式二:
set @@global|[session]系统变量名=值;
1) 全局变量
作用域:针对于所有会话(连接)有效,但不能跨重启
①查看所有全局变量
SHOW GLOBAL VARIABLES;
②查看满足条件的部分系统变量
SHOW GLOBAL VARIABLES LIKE '%char%';
③查看指定的系统变量的值
SELECT @@global.autocommit;
④为某个系统变量赋值
SET @@global.autocommit=0;
SET GLOBAL autocommit=0;
2) 会话变量
作用域:针对于当前会话(连接)有效
①查看所有会话变量
SHOW SESSION VARIABLES;
②查看满足条件的部分会话变量
SHOW SESSION VARIABLES LIKE '%char%';
③查看指定的会话变量的值
SELECT @@autocommit;
SELECT @@session.tx_isolation;
④为某个会话变量赋值
SET @@session.tx_isolation='read-uncommitted';
SET SESSION tx_isolation='read-committed';
(二) 自定义变量
说明:变量由用户自定义,而不是系统提供的
使用步骤:
1、声明
2、赋值
3、使用(查看、比较、运算等)
1. 用户变量
作用域:针对于当前会话(连接)有效,作用域同于会话变量
赋值操作符:=或:=
①声明并初始化
SET @变量名=值;
SET @变量名:=值;
SELECT @变量名:=值;
②赋值(更新变量的值)
方式一:
SET @变量名=值;
SET @变量名:=值;
SELECT @变量名:=值;
方式二:
SELECT 字段 INTO @变量名 FROM 表;
③使用(查看变量的值)
SELECT @变量名;
2. 局部变量
作用域:仅仅在定义它的begin end块中有效
应用在 begin end中的第一句话
①声明
DECLARE 变量名 类型;
DECLARE 变量名 类型 [DEFAULT 值];
②赋值(更新变量的值)
方式一:
SET 局部变量名=值;
SET 局部变量名:=值;
SELECT 局部变量名:=值;
方式二:
SELECT 字段 INTO 具备变量名
FROM 表;
③使用(查看变量的值)
SELECT 局部变量名;
#案例:声明两个变量,求和并打印
用户变量
SET @m=1;
SET @n=1;
SET @sum=@m+@n;
SELECT @sum;
局部变量
DECLARE m INT DEFAULT 1;
DECLARE n INT DEFAULT 1;
DECLARE SUM INT;
SET SUM=m+n;
SELECT SUM;
用户变量和局部变量的对比
|
作用域 |
定义位置 |
语法 |
用户变量 |
当前会话 |
会话的任何地方 |
加@符号,不用指定类型 |
局部变量 |
定义它的BEGIN END中 |
BEGIN END的第一句话 |
一般不用加@,需要指定类型 |
四、 流程控制结构
顺序、分支、循环
(一) 分支结构
1.if函数
语法:if(条件,值1,值2)
功能:实现双分支
应用在begin end中或外面
2.case结构
语法:
情况1:类似于switch
case 变量或表达式
when 值1 then 语句1;
when 值2 then 语句2;
...
else 语句n;
end
情况2:
case
when 条件1 then 语句1;
when 条件2 then 语句2;
...
else 语句n;
end
应用在begin end 中或外面
3.if结构
语法:
if 条件1 then 语句1;
elseif 条件2 then 语句2;
....
else 语句n;
end if;
功能:类似于多重if
只能应用在begin end 中
案例1:创建函数,实现传入成绩,如果成绩>90,返回A,如果成绩>80,返回B,如果成绩>60,返回C,否则返回D
CREATE FUNCTION test_if(score FLOAT) RETURNS CHAR
BEGIN
DECLARE ch CHAR DEFAULT 'A';
IF score>90 THEN SET ch='A';
ELSEIF score>80 THEN SET ch='B';
ELSEIF score>60 THEN SET ch='C';
ELSE SET ch='D';
END IF;
RETURN ch;
END $
SELECT test_if(87)$
#案例2:创建存储过程,如果工资<2000,则删除,如果5000>工资>2000,则涨工资1000,否则涨工资500
CREATE PROCEDURE test_if_pro(IN sal DOUBLE)
BEGIN
IF sal<2000 THEN DELETE FROM employees WHERE employees.salary=sal;
ELSEIF sal>=2000 AND sal<5000 THEN UPDATE employees SET salary=salary+1000 WHERE employees.`salary`=sal;
ELSE UPDATE employees SET salary=salary+500 WHERE employees.`salary`=sal;
END IF;
END $
CALL test_if_pro(2100)$
#案例1:创建函数,实现传入成绩,如果成绩>90,返回A,如果成绩>80,返回B,如果成绩>60,返回C,否则返回D
CREATE FUNCTION test_case(score FLOAT) RETURNS CHAR
BEGIN
DECLARE ch CHAR DEFAULT 'A';
CASE
WHEN score>90 THEN SET ch='A';
WHEN score>80 THEN SET ch='B';
WHEN score>60 THEN SET ch='C';
ELSE SET ch='D';
END CASE;
RETURN ch;
END $
SELECT test_case(56)$
(二) 循环结构
分类:
while、loop、repeat
循环控制:
iterate类似于 continue,继续,结束本次循环,继续下一次
leave 类似于 break,跳出,结束当前所在的循环
1.while
语法:
[标签:]while 循环条件 do
循环体;
end while[ 标签];
联想:
while(循环条件){
循环体;
}
2.loop
语法:
[标签:]loop
循环体;
end loop [标签];
可以用来模拟简单的死循环
3.repeat
语法:
[标签:]repeat
循环体;
until 结束循环的条件
end repeat [标签];
#1.没有添加循环控制语句
#案例:批量插入,根据次数插入到admin表中多条记录
DROP PROCEDURE pro_while1$
CREATE PROCEDURE pro_while1(IN insertCount INT)
BEGIN
DECLARE i INT DEFAULT 1;
WHILE i<=insertCount DO
INSERT INTO admin(username,`password`) VALUES(CONCAT('Rose',i),'666');
SET i=i+1;
END WHILE;
END $
CALL pro_while1(100)$
/*
int i=1;
while(i<=insertcount){
//插入
i++;
}
2.添加leave语句
#案例:批量插入,根据次数插入到admin表中多条记录,如果次数>20则停止
TRUNCATE TABLE admin$
DROP PROCEDURE test_while1$
CREATE PROCEDURE test_while1(IN insertCount INT)
BEGIN
DECLARE i INT DEFAULT 1;
a:WHILE i<=insertCount DO
INSERT INTO admin(username,`password`) VALUES(CONCAT('xiaohua',i),'0000');
IF i>=20 THEN LEAVE a;
END IF;
SET i=i+1;
END WHILE a;
END $
CALL test_while1(100)$
3.添加iterate语句
#案例:批量插入,根据次数插入到admin表中多条记录,只插入偶数次
TRUNCATE TABLE admin$
DROP PROCEDURE test_while1$
CREATE PROCEDURE test_while1(IN insertCount INT)
BEGIN
DECLARE i INT DEFAULT 0;
a:WHILE i<=insertCount DO
SET i=i+1;
IF MOD(i,2)!=0 THEN ITERATE a;
END IF;
INSERT INTO admin(username,`password`) VALUES(CONCAT('xiaohua',i),'0000');
END WHILE a;
END $
CALL test_while1(100)$
/*
int i=0;
while(i<=insertCount){
i++;
if(i%2==0){
continue;
}
插入
}
第11章 视图
11.1 视图概述
从一个或者多个表中导出的一个虚表。
11.1.1视图的含义
视图是一个虚表,是从数据库中一个或者多个表中导出来的表。还可以从已存在的视图的基础上定义。通过视图看到的数据只是存放在基本表中的数据,若基本表的数据发生变化,则这种变化也可以自动地反映到视图中。
11.1.2视图的作用
1,简单化
看到的就是需要的,可以对经常被使用的查询定义为视图,从而使得用户不必为以后的操作每次指定全部的条件。
2.安全性
通过视图用户只能查询和修改它们所能见到的数据。数据库中的其他数据则既看不见也取不到。数据库授权命令可以使每个用户对数据库的检索先知道特定的数据库对象上,但不能授权到数据库特定行和特定列上。
(1)使用权限可被限制在基表的行、列的子集上
(2)使用权限可被限制在多个基表的连接所限定的行上
(3)使用权限可被限制在基表中的数据的统计汇总上。
(4)使用权限可被限制在另一个视图的子集上,或是一些视图和基表合并后的子集上。
3.逻辑数据独立性
视图可以帮助用户屏蔽真实表结构变化带来的影响。
11.2 创建视图
创建视图基于SELECT查询的结果
11.2.1创建视图的语法
CREATE [OR REPLACE] [ALGORITHM= {UNDEFINED |MERGE |TEMPTABLE}]
VIEW view_name [(column_list)]
AS SELECT_statement
[WITH [CASCADED | LOCAL] CHECK OPTION]
REPLACE:表示替换已创建的视图
ALGORITHM:表示视图选择的算法,
UNDEFINED:表示MySQL将自动选择算法。
MERGE:表示将使用的视图语句与视图定义合并起来,使得视图定义的某一部分取代语句对应部分
TEMPTABLE:表示将视图的结果存入临时表,然后用临时表来执行语句。
SELECT_statement:表示SELECT 语句
[WITH [CASCADED | LOCAL] CHECK OPTION]:表示视图在更新时保证在视图的权限范围之内。
CASCADED:为默认值,表示更新视图时要满足所有相关视图和表的条件
LOCAL表示更新视图时满足该视图本身定义的条件即可。
11.3 查看视图
DESC view_name
SHOW TABLE STATUS LIKE '视图名'
SHOW CREATE VIEW view_name;
SELECT * FROM informatiom_schema.views;
11.4 修改视图
视图的CRUD 和表基本一样
11.5视图和表的区别和联系
区别:
- 视图是已经编译好的SQL语句,是基于SQL语句的结果集的可视化表,而表不是。
- 视图没有实际的物理记录,而表有。
- 表是内容,视图是窗口
- 表占用物理空间而视图不占用物理空间,视图只是逻辑概念的存在,表可以及时对它进行修改,但视图只能用创建的语句来修改
- 视图是查看数据表的一种方法,可以查询数据表中某一个字段构成的数据,只是一些SQL语句的集合。从安全角度来说,视图可以防止用户接触数据表,因而用户不知道表结构。
- 表属于全局模式中的表,是实表;视图属于局部模式的表,是虚表。
- 视图的建立和删除只影响试图本身,不影响对应的基本表。
联系:
视图是基本表之上建立的表,它的结构和内容都来自基本表,它依据基本表存在而存在。一个视图可以对应一个基本表,也可以对应多个基本表。视图是基本表的抽象和在逻辑意义上建立的新关系。
第12章 MySQL触发器
12.1 创建触发器
触发器(trigger)是个特殊的存储过程,触发器可以包含复杂的SQL语句,主要用于满足复杂业务规则和要求
12.1.1 创建只有一个执行语句的触发器
创建触发器的语法:
CREATE TRIGGER trigger_name trigger_time trigger_event
ON table_name FOR EACH ROW trigger_stmt
trigger_time:触发时机,before 、after
trigger_event:触发事件 INSERT、UPDATE、DELETE、
table_name:建立触发器的表明,即在那张表上创建触发器
trigger_stmt:触发器执行语句
[l1] 一致性非锁定读(consistent nonlocking read)是指InnoDB存储引擎通过多版本控制(multi versionning)的方式来读取当前执行时间数据库中行的数据,如果读取的行正在执行DELETE或UPDATE操作,这是读取操作不会因此等待行上锁的释放。相反的,InnoDB会去读取行的一个快照数据
快照数据是指该行之前版本的数据,该实现是通过undo段来完成。而undo用来事务中的回滚数据,因此快照数据本身没有额外的开销,此外,读取快照数据不需要上锁,因为没有事务需要对历史数据进行修改操作
可以看到,非锁定读机制极大地提高了数据库的并发性,在InnoDB存储引擎的默认设置下,这是默认的读写方式,即读不会占用和等待表上的锁
[l2]
[l3]2,分表和分区不矛盾,可以相互配合的,对于那些大访问量,并且表数据比较多的表,我们可以采取分表和分区结合的方式(如果merge这种分表方式,不能和分区配合的话,可以用其他的分表试),访问量不大,但是表数据很多的表,我们可以采取分区的方式等。
分库分表区别:
1 基本思想之什么是分库分表?
从字面上简单理解,就是把原本存储于一个库的数据分块存储到多个库上,把原本存储于一个表的数据分块存储到多个表上。
2 基本思想之为什么要分库分表?
数据库中的数据量不一定是可控的,在未进行分库分表的情况下,随着时间和业务的发展,库中的表会越来越多,表中的数据量也会越来越大,相应地,数据操作,增删改查的开销也会越来越大;另外,一台服务器的资源(CPU、磁盘、内存、IO等)是有限的,最终数据库所能承载的数据量、数据处理能力都将遭遇瓶颈,。
3 分库分表的实施策略。
如果你的单机性能很低了,那可以尝试分库。分库,业务透明,在物理实现上分成多个服务器,不同的分库在不同服务器上。分区可以把表分到不同的硬盘上,但不能分配到不同服务器上。一台机器的性能是有限制的,用分库可以解决单台服务器性能不够,或者成本过高问题。
当分区之后,表还是很大,处理不过来,这时候可以用分库。
orderid,userid,ordertime,.....
userid%4=0,用分库1
userid%4=1,用分库2
userid%4=2, 用分库3
userid%4=3,用分库4
上面这个就是一个简单的分库路由,根据userid选择分库,即不同的服务器
分库分表有垂直切分和水平切分两种。
3.1 何谓垂直切分,即将表按照功能模块、关系密切程度划分出来,部署到不同的库上。例如,我们会建立定义数据库workDB、商品数据库payDB、用户数据库userDB、日志数据库logDB等,分别用于存储项目数据定义表、商品定义表、用户数据表、日志数据表等。
如userid,name,addr一个表,为了防止表过大,分成2个表。
userid,name
userid,addr
3.2 何谓水平切分,当一个表中的数据量过大时,我们可以把该表的数据按照某种规则,例如userID散列、按性别、按省,进行划分,然后存储到多个结构相同的表,和不同的库上。例如,我们的userDB中的用户数据表中,每一个表的数据量都很大,就可以把userDB切分为结构相同的多个userDB:part0DB、part1DB等,再将userDB上的用户数据表userTable,切分为很多userTable:userTable0、userTable1等,然后将这些表按照一定的规则存储到多个userDB上。
3.3 应该使用哪一种方式来实施数据库分库分表,这要看数据库中数据量的瓶颈所在,并综合项目的业务类型进行考虑。
如果数据库是因为表太多而造成海量数据,并且项目的各项业务逻辑划分清晰、低耦合,那么规则简单明了、容易实施的垂直切分必是首选。
而如果数据库中的表并不多,但单表的数据量很大、或数据热度很高,这种情况之下就应该选择水平切分,水平切分比垂直切分要复杂一些,它将原本逻辑上属于一体的数据进行了物理分割,除了在分割时要对分割的粒度做好评估,考虑数据平均和负载平均,后期也将对项目人员及应用程序产生额外的数据管理负担。
在现实项目中,往往是这两种情况兼而有之,这就需要做出权衡,甚至既需要垂直切分,又需要水平切分。我们的游戏项目便综合使用了垂直与水平切分,我们首先对数据库进行垂直切分,然后,再针对一部分表,通常是用户数据表,进行水平切分。
4 分库分表存在的问题。
4.1 事务问题。
在执行分库分表之后,由于数据存储到了不同的库上,数据库事务管理出现了困难。如果依赖数据库本身的分布式事务管理功能去执行事务,将付出高昂的性能代价;如果由应用程序去协助控制,形成程序逻辑上的事务,又会造成编程方面的负担。
4.2 跨库跨表的join问题。
在执行了分库分表之后,难以避免会将原本逻辑关联性很强的数据划分到不同的表、不同的库上,这时,表的关联操作将受到限制,我们无法join位于不同分库的表,也无法join分表粒度不同的表,结果原本一次查询能够完成的业务,可能需要多次查询才能完成。
4.3 额外的数据管理负担和数据运算压力。
额外的数据管理负担,最显而易见的就是数据的定位问题和数据的增删改查的重复执行问题,这些都可以通过应用程序解决,但必然引起额外的逻辑运算,例如,对于一个记录用户成绩的用户数据表userTable,业务要求查出成绩最好的100位,在进行分表之前,只需一个order by语句就可以搞定,但是在进行分表之后,将需要n个or
der by语句,分别查出每一个分表的前100名用户数据,然后再对这些数据进行合并计算,才能得出结果。
[l4]分表和分区的区别:
一,什么是mysql分表,分区
什么是分表,从表面意思上看呢,就是把一张表分成N多个小表,具体请看:mysql分表的3种方法
什么是分区,分区呢就是把一张表的数据分成N多个区块,这些区块可以在同一个磁盘上,也可以在不同的磁盘上,具体请参考mysql分区功能详细介绍,以及实例
二,mysql分表和分区有什么区别呢
1,实现方式上
a),mysql的分表是真正的分表,一张表分成很多表后,每一个小表都是完正的一张表,都对应三个文件,一个.MYD数据文件,.MYI索引文件,.frm表结构文件。
Sql代码
[root@BlackGhost test]# ls |grep user
alluser.MRG
alluser.frm
user1.MYD
user1.MYI
user1.frm
user2.MYD
user2.MYI
user2.frm
简 单说明一下,上面的分表呢是利用了merge存储引擎(分表的一种),alluser是总表,下面有二个分表,user1,user2。他们二个都是独立 的表,取数据的时候,我们可以通过总表来取。这里总表是没有.MYD,.MYI这二个文件的,也就是说,总表他不是一张表,没有数据,数据都放在分表里面。我们来看看.MRG到底是什么东西
Sql代码
[root@BlackGhost test]# cat alluser.MRG |more
user1
user2
#INSERT_METHOD=LAST
从上面我们可以看出,alluser.MRG里面就存了一些分表的关系,以及插入数据的方式。可以把总表理解成一个外壳,或者是联接池。
b),分区不一样,一张大表进行分区后,他还是一张表,不会变成二张表,但是他存放数据的区块变多了。
Sql代码
[root@BlackGhost test]# ls |grep aa
aa#P#p1.MYD
aa#P#p1.MYI
aa#P#p3.MYD
aa#P#p3.MYI
aa.frm
aa.par
从 上面我们可以看出,aa这张表,分为二个区,p1和p3,本来是三个区,被我删了一个区。我们都知道一张表对应三个文件.MYD,.MYI,.frm。分 区呢根据一定的规则把数据文件和索引文件进行了分割,还多出了一个.par文件,打开.par文件后你可以看出他记录了,这张表的分区信息,根分表中 的.MRG有点像。分区后,还是一张,而不是多张表。
如orderid,userid,ordertime,.....
ordertime<2015-01-01 #p0
ordertime<2015-04-01 #p1
ordertime<2015-07-01 #p2
ordertime<2015-10-01 #p3
ordertime<2016-01-01 #p4
按照时间分区。大部分只查询最近的订单数据,那么大部分只访问一个分区,比整个表小多了,数据库可以更加好的缓存,性能也提高了。这个是数据库分的,应用程序透明,无需修改。
2,数据处理上
a),分表后,数据都是存放在分表里,总表只是一个外壳,存取数据发生在一个一个的分表里面。看下面的例子:
select * from alluser where id='12'表面上看,是对表alluser进行操作的,其实不是的。是对alluser里面的分表进行了操作。
b),分区呢,不存在分表的概念,分区只不过把存放数据的文件分成了许多小块,分区后的表呢,还是一张表。数据处理还是由自己来完成。
3,提高性能上
a), 分表后,单表的并发能力提高了,磁盘I/O性能也提高了。并发能力为什么提高了呢,因为查寻一次所花的时间变短了,如果出现高并发的话,总表可以根据不同 的查询,将并发压力分到不同的小表里面。磁盘I/O性能怎么搞高了呢,本来一个非常大的.MYD文件现在也分摊到各个小表的.MYD中去了。
b),mysql提出了分区的概念,我觉得就想突破磁盘I/O瓶颈,想提高磁盘的读写能力,来增加mysql性能。
在这一点上,分区和分表的测重点不同,分表重点是存取数据时,如何提高mysql并发能力上;而分区呢,如何突破磁盘的读写能力,从而达到提高mysql性能的目的。
4),实现的难易度上
a),分表的方法有很多,用merge来分表,是最简单的一种方式。这种方式根分区难易度差不多,并且对程序代码来说可以做到透明的。如果是用其他分表方式就比分区麻烦了。
b),分区实现是比较简单的,建立分区表,根建平常的表没什么区别,并且对开代码端来说是透明的。
三,mysql分表和分区有什么联系呢
1,都能提高mysql的性高,在高并发状态下都有一个良好的表面
[l5]存储过程和函数:类似于java中的方法