mysql
优化数据库设计
第一范式(1st NF)
-
第一范式的目标是确保每列的原子性
定义:数据库表中的所有字段都是单一属性,不可再分的。这个单一属性是由基本的数据类型所构成的,如整数,浮点数,字符串,等;
换句话说 第一范式要求数据库中的表都是二维表。
如果每列都是不可再分的最小数据单元(也称为最小的原子单元),则满足第一范式(1 NF);
第二范式(2nd NF)
- 第二范式要求每个表只描述一件事情;
- 定义:数据库的表中不存在非关键字段对任一候选关键字段的部分函数依赖。
- 部分函数依赖是指存在着组合关键字中的某一关键字决定非关键字的情况。
- 换句话说:所有单关键字段的表都符合第二范式。
第三范式(3nd NF)
- 如果一个关系满足2NF,并且除了主键以外的其他列都不传递依赖于主键列,则满足第三范式(3 NF);
- 定义:第三范式是在第二范式的基础之上定义的,如果数据表中不存在非关键字段对任意候选关键字段的传递函数则符合第三范式。
1.什么是数据库?
- 数据库(database,简称DB):是按照数据结构来组织,存储和管理数据的仓库。
- 数据库管理系统(Databse Management System,DBMS):是指数据库系统中对数据进行管理的软件系统。
2.什么是MySQL?
MySQL一个开源的关系型数据库管理系统
-
MySQL由瑞典MySQL AB公司开发
目前属于Oracle旗下产品
SQL语言是用于访问数据库的最常用的标准化语言
3.MySQL常用命令
-
mysqladmin命令用于修改用户密码
命令格式:
mysqladmin命令格式:
mysqladmin -u用户名 -p旧密码 password
输入新密码:
确认新密码:
show databases; 命令用于显示所有数据库
use 数据库名;使用某个数据库(或切换到某个数据库)
-
select命令:
此命令用于显示当前连接(选择)的信息
select database(); 显示当前连接的数据库
select version(); 显示当前服务器版本
select now(); 显示当前日期时间
select user(); 显示当前用户
4.操作数据库
-
创建数据库是在系统磁盘上划分一块区域用于数据的存储和管理
创建数据库的语法格式:
create database 数据库名
create database if not exists test02 character set utf8; 判断数据库是否存在并创建默认编码字符
create datebase dbname charset=utf8; 创建数据库并创建默认编码字符
-
修改数据库
修改数据库的编码格式:
alter database test02 character set gb2312;
显示数据库的编码格式:
show variables like 'character%';
删除数据库:
drop database test02;
5.mysql的数据类型
- 数据类型是指数据列,存储过程参数,表达式和局部变量的数据特征,他决定了数据的存储格式,代表了不同的信息类型。
-
整型
数据类型 存储范围 字节 tinyint 有符号值:-128到127(-27到27-1) 无符号值:0到255(0到2^8-1) 1 smallint 有符号值:-32768到32767(-215到215-1) 无符号值:0到65535(0到2^16-1) 2 mediumint 有符号值:-8388608到8388607(-223到223-1) 无符号值:0到16777215(0到2^24-1) 3 int 有符号值:-2147483648到2147483647(-231到231-1) 无符号值:0到4294967295(0到2^32-1) 4 bigint 有符号值:-9223372036854775808到9223372036854775807(-263到263-1) 无符号值:0到18446744073709551615(0到2^64-1) 8 -
浮点数类型和定点数类型(表示小数)
数据类型 存储范围 浮点数类型 float[(m,d)] double[(m,d)] 4个字节存储 范围:-3.402823466E+38到3.402823466E+38 8个字节存储 范围:-1.797931348623157E+308 到 1.797931348623157E+308 定点数类型 decimal[(m,d)] m是精度 (=整数位数+小数位数),是标度(小数点后的位数) -
日期时间型
列类型 字节数 取值范围 表示形式 year 1 1901~2155 YYYY time 3 -838:59:59~838:59:59 HH:MM:SS date 4 1000-01-01~9999-12-31 YYYY-MM-DD datetime 8 1000-01-01 00:00:00~9999-12-3123:59:59 YYYY-MM-DD HH:MM:SS timestamp 4 1970010108001~20380119111407 YYYY-MM-DD HH:MM:SS -
字符型(字符串类型用来存储字符串数据,除了可以存储字符串数据之外,还可以存储其它数据,比如图片和声音的二进制数据)
列类型 存储需求 char(m) m个字节,0<=m<=255 varchar(m) l+1个字节,其中l<=m且0<=m<=65535 tinytext 0~255 (2^8-1) text 0~65535(2^16-1) mediumtext 0~2^24-1 longtext 0~2^32-1 enum('value1','value2',……) 取决于枚举的个数(最多65535个值) set('value1','value2',……) 取决于set成员的数目(最多64个成员)
数据库表
-
数据库最重要的组成部分之一,是其它对象的基础。
行(记录) 列(字段)
创建数据库表
-
create table<表名>
(
列名1 数据类型【列级别约束条件】【默认值】
列名2 数据类型【列级别约束条件】【默认值】
……
【表级别约束条件】
);
-
查看数据库表
- 查看数据表列表
- show tables [from 数据库名];查看当前库下的表时[ ]这部分可以省略
-
查看数据表基本结构
- show columns from 表名;
- describe 表名/desc 表名;
-
查看表详细结构语句
- show create table 表名;
修改数据库表
-
在已经存在的表添加新的列
alter table 表名 add 新列名 数据类型 [约束条件] 【first | after 已存在列名】;// [ ]为可选项
-
修改表列名的命令
alter table表名 change 旧列名 新列名 新数据类型
-
修改列的数据类型
alter table 表名 modify 列名 数据类型 //modify修改的意思
-
修改列的排列位置
alter table 表名 modify 列 1 数据类型 first | after 列2;
-
删除列
alter table 表名 drop 列名;
-
修改表名
alter table 旧表名 rename 【to】新表名
删除数据库表
- drop table [if exists] 表1,表2,表3,……表n; //添加括号内容不会报错(将错误信息隐藏)
表分区
当我们创建的表,需要承载的数据量很大的时候,就要注意他的性能问题,比如图书信息表,有1000万个图书信息,那么我们就得考虑如何优化他,其中一种方式就是表分区。
表分区就是把一张表的数据分成多个区块,这些区块可以在同一个磁盘上,也可以在不同的磁盘上,但所有的数据还在一个表中。
-
不过使用表分区有个前提就是你的数据库必须支持。执行下面命令查看是否支持
show plugins;
显示 partition |active|storage engine | null |gpl | //为支持
-
表分区方式
-
水平分区
将表的数据按行分割成不同的数据文件
-
垂直分区
将表的数据按列分割成不同的数据文件
-
MySQL约束
约束是一种限制,它通过对表的行或列的数据做出限制,来确保表的数据的完整性,唯一性。
-
常用的几种约束类型
约束类型 非空约束 主键约束 唯一约束 默认约束 外键约束 关键字 not null primary key unique default foreign key not null:这一列不能为空;
值 说明 null 字段值可以为空 not null 字段值禁止为空 - 非空约束(not null constraint)指字段的值不能为空。对于使用了非空约束的字段如果用户在添加数据时,没有指定值,数据库系统会报错。
- 语法:列名 数据类型 not null
- 添加非空约束:alter table 表名 modify 字段名 数据类型 not null;
- 删除非空约束:alter table 表名 modify 字段名 数据类型;
primary key:用于约束表当中的一行,通过主键约束定位到表中的一行;
- 要求主键列的数据唯一,并且不允许为空,主键能够唯一地标识表中的一条记录。
- 一张表中最多只能拥有一个主键列
类型 说明 单字段主键 由一个字段列组成 1.在定义列的同时指定主键(列名 数据类型 primary key); 2.在列定义的后边指定主键([constrant <约束名>])primary key(列名); 多字段联合主键 主键由多个字段(列)联合组成 primary key(字段1,字段2,……字段n) create table borrowinfo( book_id int,card_id char(18),primary key(book_id,card_id)); - 通过修改表为列添加主键
- alter table bookinfo modfiy book_id int primary key;
- alter table bookinfo add primary key(book_id);
- alter table bookinfo add constarint pk_id primary key(book_id);
- 删除主键
- alter table bookinfo drop primary key;
unique:一张表中指定一列的值不能有重复且唯一;
- 要求该列唯一,允许为空,可以确保一列或者几列不出现重复值
- 语法规则:
- 列名 数据类型 unique;
- 定义完所有列后
- 【constraint <约束名>】unique(列名);
- 修改表时添加唯一约束
- 与主键类似
- 删除表的唯一约束
- alter table bookinfo drop index book_name;
- alter table bookinfo drop key book_name;
default:插入数据时如果没有明确为字段赋值,就会自动赋予默认值;
- 指定某列的默认值
- 语法规则:
- 列名 数据类型 default 默认值
- 修改表时添加默认约束
- alter table bookinfo modify book_name varchar(20) default '机械工业出版社';
- alter table bookinfo alter column book_name set default '机械工业出版社';
- 删除默认约束
- altre table bookinfo modify book_name varchar(20);
- alter table bookinfo alter column book_name drop default;
foreign key:两个表的数据之间建立连接,通过外键约束可以保证数据的完整性和一致性;
- 用来在两个表的数据之间建立连接,它可以是一列或者多列。一个表可以有一个多个外键;
- 外键对应的是参照完整性,一个表的外键可以为空值,若不为空值,则每一外键必须等于另一个表中主键的某个值。
- 外键的作用是保持数据的一致性,完整性;
- 语法格式:
- [constraint<外键约束名>] foreign key(列名) references<主表名>(主键)
约束区别
- 唯一约束与主键约束的区别
- 一个表中可以有多个unique声明,但只能有一个primary key声明;
- 声明primary key的列不允许有空值;
- unique的列允许空值
插入数据
- 在使用数据库之前,数据库表中必须有数据,我们需要使用insert语句向数据库表中插入数据。
-
为表的所有列插入数据:
- 语法格式:
- insert into table_name(column_list) values(value_list);
- insert into table_name values(value_list); //插入顺序需要跟字段顺序对应
-
为表的指定列插入数据:
- 为表的指定列插入数据,就是在insert语句中只向部分列中插入值,而其他没有指定值的列所插入的数据为表定义时的默认值。
- 语法格式:
- insert into table_name(column_list//部分字段) values(value_list);
-
同时插入多条记录:
- 语法格式:
- nsert into table_name(column_list) values (value_list1), (value_list2), (value_list3)…… (value_listn);
-
将查询结果插入到表中
- insert可以将select语句查询的结果插入到表中。
- 语法格式:
- insert into table_name1(column_list1) select(column_list2) from table_name2 where (condition);
设置自动编号
-
设置表的属性值自动增加
语法格式:
列名 数据类型 auto_increment;
注意:auto_increment约束的字段可以是任何整数类型(tinyint,smallint,int等)
自增列的初始值默认是1,每添加一条记录,自动增长1。在建表时可用‘auto_increment=n’选项来指定一个自增的初始值。(默认为1)
-
create table table_name(
id int primary key auto_increment,
name varchar(10) not nul,
) auto_increment=5;
-
为已有的表添加自增列
- 修改表的方式
- alter table table_name modfiy 字段名 数据类型 auto_increment;
-
修改自增列的起始值
- alter table table_name auto_increment=x;
- 修改后auto_increment列起始值从x开始;
-
去掉字增列
- alter table table_name modfiy 字段名 数据类型 ;
单表数据记录的更新
mysql中使用update语句更新表中的记录
更新特定的行
-
更新所有的行
-
语法格式
update table_name set column_name1=value1,column_name2=value2,column_name3=value3,column_namen=valuen where (condition);
//不加where条件会更新所有的行
-
单表记录的删除
- 使用delete语句删除满足条件的记录,语法格式如下:
- delete from table_name [where <condition>];
- 如果想删除表中的所有记录,还可以使用truncate table语句,truncate将直接删除原来的表,并重新创建一个表,其语法结构为:
- TRUNCATE TABLE_NAME table_name;
单表记录的查询
mysql从数据表中查询数据的基本语句为select语句。
-
语法结构:
SELECT select_expr【,select_expr……】
【
FROM table_references
【WHERE where_condition】
【GROUP BY {col_name|position} 【ASC|DESC】,……】
【HAVING where_condition】
【ORDER BY {col_name|expr|position} 【ASC|DESC】,……】
【LIMIT {【offset,】row_count|row_count OFFSET offset}】
】
在select语句中使用星号‘*’通配符查询所有列
如:select * from bookcategory;
指定所有列
如:select category_id, category, parent_id from bookcategory;
查询单个列
如:select category from bookcategory;
查询多个列
如:select category_id, category from bookcategory;
-
通过where子句,对数据进行过滤,语法格式为:
select 列名1,列名2,……列名n
from 表名
where 查询条件
select book_id,book_name,price from bookinfo where press ='机械工业出版社';
-
使用distinct关键字指示mysql消除重复的记录值
select distinct 列名 from 表名;
如:select disyinct press from bookinfo;
使用is null子句,可以查询某列内容为空记录。
如:select * from readerinfo where age is null;
分组查询
- 分组查询是对数据按照某个或多个列进行分组
- 【group by 列名】【having<条件表达式>】
创建分组
查询结果分组
group by 列名
group 不要通常和聚合函数一起使用,例如:max(), min(), sum(), avg(), count()
-
例:
select count(*) from readerinfo where sex='男';
select sex ,count(*) from readerinfo group by sex;
[having <条件表达式>]
having限定显示记录所需满足的条件,只有满足条件的分组才会被显示。
-
例:
select sex from readerinfo group by sex having count(sex)>2;
排序
- 对查询结果进行排序
- mysql中可以通过order by子句对查询的结果进行排序
- order by 列名 [ASC|DESC]
- 单列排序
- 按照指定的某个列进行排序,默认升序。
- select * from bookinfo order by price;
- 多列排序
- 按照多个列进行排序,默认升序
- select * from bookinfo order by price,store;
- 指定排序方向
- 排序分为升序和降序,默认升序。
- 升序ASC
- 降序DESC
- select * from bookinfo order by price ASC,store DESC;
- 单列排序
限制查询
-
通过limit语句限制查询记录的数量
limit关键字可以返回指定位置的记录
limit [位置偏移量,] 行数
说明:第一条记录的位置偏移量为0,第二条为1,……以此类推。
-
显示图书信息表的前3行记录
select * from bookinfo limit 3;
-
显示从第3条记录开始后的2条图书信息记录
select * from bookinfo limit 2,2;
说明:mysql5.7中也可以使用limit 2 offset 2,实现例2相同的效果。
Mysql中的额运算符
-
熟悉mysql中常用运算符的使用
运算符是告诉mysql执行特定算术或逻辑操作的符号,运算符连接表达式中各个操作数,其作用是用来指明对操作数所进行的运算。
-
常用的运算符
算术运算符
-
用于各类数值运算
运算符 作用 + 加法 - 减法 * 乘法 / 除法 % 求余(取模)
比较运算符
运算符 作用 >,< 大于,小于 >=,<= 大于等于,小于等于 = 等于 <>(!=) 不等于 is(not) null 判断一个值是否为空(或不为空) between……and 判断一个值是否在两个值之间 (not)in 判断一个值是(或不是)in列表中的值 like 通配符匹配 逻辑运算符
-
运算符 | 作用 |
---|---|
AND | 逻辑与 |
OR | 逻辑或 |
NOT | 逻辑非 |
mysql数值函数
函数
- 函数表示对输入参数值返回一个具有特定关系的值,mysql提供了大量丰富的函数,在进行数据库管理以及数据的查询和操作时会经常用到各种函数。通过对数据的处理,数据库功能可以变得更加强大,更加灵活的满足不同用户的需求。
- 常用函数
-
数值函数(数学函数)
-
主要是用来处理数值数据的。
获取整数的函数
-
CEIL(x):向上取整
select ceil(28.55) 结果:29
-
floor(x):向下取整
select floor(28.55) 结果:28
-
round(x) :返回最接近于参数x的整数,对参数x进行四舍五入
select round(28.55) 结果:29
-
round(x,y):返回最接近于参数x的数,其值保留到小数点后面的y位,若y为负值,则将保留x值到小数点左边y位
select round(28.55,1), round(28.55,0), round(28.55,-1);
结果:28.6 29 30
-
截断函数 truncate(x,y)返回被舍去至小数点后y位的数字x.若y的值为0,则结果为整数,若y的值为负数,则截去x小数点左起第y位开始后面所有低位的值
select truncate(28.55,1), truncate(28.55,0), truncate(28.55,-1);
结果: 28.5 28 20
-
取模(求余)
-
mod(x,y)返回x被y除后的余数
select mod(11,2); 结果:1
-
-
-
字符函数
-
用来处理数据库中字符串数据
-
字符串连接函数
concat(s1,s2,...)返回结果为连接参数产生的字符串,如果任何一个参数为null,则返回值为null
select concat('hello','world'); 结果:helloworld
-
concat_ws(x,s1,s2,...),第一个参数x是其它参数的分隔符,分隔符的位置放在要连接的两个字符串之间,分隔符可以是一个字符串,也可以是其它参数,如果分隔符为null,则结果为null。
select concat_ws('-','hello','word'); 结果为:hello-word
-
字母转换大小写函数
-
lower(str)可以将字符串str中的字母字符全部转换成小写字母
select lower('Hello Word'); 结果:hello word
-
upper(str)可以将字符串str中的字母字符串全部换成大写字母。
select upper('Hello Word'); 结果:HELLO WORLD
-
-
求字符长度的函数
-
length(str)返回值为字符串的字节长度
select length(' hello '); 结果:7
-
-
删除空格的函数
- ltrim(s)返回字符串s,字符左侧空格字符被删除
- rtrim(s)返回字符串s,字符右侧空格字符被删除
- trim(s):删除字符串两侧的空格
-
截取字符串
substring(s,n,len)带有len参数的格式,从字符串s返回一个长度同len字符相同的子字符串,起始于位置n。n如果是负数,则子字符串的位置起始于字符串结尾的n个字符。
select substring('hello,world',1,5); 结果:hello
select substring('hello world',-3,2); 结果:rl
-
获取指定长度的字符串函数
-
left(s,n)返回字符串s开始的最左边n个字符
select left('hello world',5); 结果:hello
-
right(s,n)返回字符串中最右边n个字符
select right('hello world',5); 结果:world
-
-
替换函数
-
replace(str,from_str,to_str)在字符串str中所有出现的字符串from_str均被yo_str替换,然后返回这个字符串。
select replace('hello world','world','mysql'); 结果:hello mysql
-
-
格式化函数
-
format(x,n)将数字x格式化,并以四舍五入的方式保留小数点后n为,结果以字符串的形式返回。若n为0,则返回结果不含小数部分。
select format(1234.5678,2), format(1234.5,2),format(1234.5678,0);
结果:1234.57 1234.50 1235
-
-
-
-
日期时间函数
- 日期和时间函数主要是用来处理日期和时间值
- 获取当前日期的函数
- curdate()和current_date()函数作用相同,将当前日期按照‘YYY-MM-DD’或‘YYYMMDD’格式的值返回,具体格式根据函数在字符串或是数字语境中而定。
- select curdate(); 结果为:2018-05-16
- select curdate()+0; 结果为:20180516
- 获取当前时间的函数
- curtime()和current_time()函数作用相同,将当前时间按照‘HH:MM:SS’或‘HHMMSS’格式的值返回,具体格式根据函数在字符串或是数字语境中而定。
- select curdate(); 结果为:15:03:28
- select curdate()+0; 结果为:150328
- 获取当前的日期和时间
- now()和sysdate()函数作用相同,均返回当前的日期时间值。格式为‘YYY-MM-DD HH:MM:SS’或‘YYYMMDDHHMMSS’格式的值返回,具体格式根据函数在字符串或是数字语境中而定。
- select now(); 结果为:2018-05-16 15:12:57
- select now()+0; 结果为:20180516151257
- 执行日期的加运算
- date_add(date,interval expr type)其中,date是一个DATETIME或DATE值,用来指定起始时间。expr是一个表达式,用来指定从起始时间添加或减去的时间间隔值。type为关键词,它指示了表达式被解释的方式,如:YEAR,MONTH,DAY,WEEK,HOUR等。
- select date_add('2018-05-19',interval 3 month); 结果为:2018-08-19
- 计算两个日期之间的间隔天数
- datediff(date1,date2)返回起始时间date1和结束时间date2之间的天数。
- select datediff('2018-06-1','2018-05-1'); 结果为:31
- 日期的格式化
- date_format(date,format)根据format指定的格式显示date值。
- date_format时间日期格式:
- %b:月份的缩写名称(Jan...Dec)
- %c:月份,数字形式(0...12)
- %m:月份,数字形式(00...12)
- %M:月份名称(January..December)
- %d:该月日期,数字形式(00...31)
- %e:该月日期,数字形式(0...31)
- %Y:4位数形式表示年份
- %y:2位数形式表示年份
-
聚合函数(分组函数)
- 有时候并不需要返回实际表中的数据,而只是对获取的数据进行分析和总结。这时候就需要使用聚合函数。
名称 描述 AVG() 返回某列的平均值 COUNT() 返回某列的行数 MAX() 返回某列的最大值 MIN() 返回某列的最小值 SUM() 返回某列值的和 -
信息函数
- VERSION():返回当前MySQL服务器版本的版本号。
- CONNECTION_ID():返回MySQL服务器当前连接的次数,每个连接都有各自唯一的ID。
- DATABASE()和SCHEMA():返回当前的数据库名
- USER():获取用户名的函数,返回当前登录 的用户名称
-
加密函数
- 加密函数主要用来对数据进行加密和界面处理,以保证某些重要数据不被别人获取
- MD5():信息摘要算法(不可逆)
- MD5(str)函数可以加密字符串,加密后的值以32位十六进制数字的二进制字符串形式返回,若参数为NULL,则返回NULL。
- PASSWORD():密码算法
- PASSWORD(str)从原明文密码str计算并返回加密后的密码字符串,当参数为NULL时,返回NULL。
-