MySQL笔记[1]:基本操作
MySQL基础
一、MySQL简介
1.1 概念及发展
数据库:按照数据结构来组织、存储并管理数据的仓库。
MySQL发展
1985年,几个瑞典人位大型零售商的项目设计了一种利用索引顺序存取数据的软件,这就是MyISAM的前身。1996年,MySQL1.0发布,随后发布了3.11.1版本,并开始往其他平台移植。2000年MySQL采用GPL协议开源。MySQL 4.0开始支持MyIsam、InnoDB。
2005年10月,MySQL 5.0成为里程碑版本。
2008年1月被Sun公司收购。
2009年1月,在Oracle收购MySQL之前,Monty Widenius担心被收购,就从MySQL 5.5开始一条新的GPL分支,起名MariaDB。
MySQL的引擎是插件化的,可以支持很多引擎。
MyISAM, 不支持事物和外键,插入、查询速度快。
InnoDB, 支持事物和外键,行级锁,MySQL5.5起的默认引擎。
(对于两种引擎各自的优劣下文会有详细介绍)
1.2 分类
按照数据模型分类:网状数据库、层次数据库、关系型数据库。前两者应用很少,我们重点关心关系型数据库。
关系型数据库
使用行、列组成的二维表来组织数据和关系,表中行既可以描述数据实体,也可以描述实体间关系。
关系模型比网状模型、层次模型更简单,不需要关心数据存储的物理细节,而专注于数据的逻辑构建,而且关系模型有严谨的数学理论作为基础支撑。
RDBMS:包括IBM 的DB2,Oracle,MySQL,以及此前的infomix、Sybase等。
NoSQL
NoSQL是对非SQL,即非传统关系型数据库的统称。
NoSQL一词诞生于1998年,2009年这个词汇被再次提出,指非关系型、分布式、不提供ACID的数据库设计模式。
MySQL
是一种关系型数据库管理软件,支持网络访问,用mysql协议通信,默认使用tcp 3306端口。
1.3 SQL标准
SQL:Structured Query Language是结构化查询语言,1987年由ISO标准化,是对DBMS的统一操作方式进行标准化。
所有主流的关系型数据库都支持SQL,NoSQL也有很大一部分支持SQL。
例如SQL99,即1999年制定的标准,第四代结构化查询语言。
注意,每个DBMS都不只支持SQL标准,而会有一些自己独有的语法,比如limit语句只在MySQL中可以使用
1.4 SQL的语法
SQL语句可以在单行或多行书写,以分号结尾
有些时候可以不以分号结尾,比如代码中
可以使用空格和缩进来增强语句的可读性
MySQL不区分大小写,建议使用大写
可以使用空格和缩进来增强语句的可读性
MySQL不区分大小写,建议使用大写
1.5 SQL99标准的四大分类
DDL数据定义语言(data definition language)
create table,alter table,drop table,truncate table 。。
DML数据操作语言(Data Manipulation Language)
insert,update,delete
DQL数据查询语言(data query language),很多文档也将此归类为DML。
select
就是常说的CRUD增删改查,但因为对于程序员来说查询较重要,所以单独分离出来。
DCL数据控制语言(Data Control Language)
grant 授权,revoke 撤销
TCL(事务控制语言):commit,rollback,负责处理ACID事务。
二、 数据库基本操作与用户管理
2.1 mysql
终端管理命令入门
1. 连接
1 | mysql -u root -p |
回车后输入密码.
2. 查看数据库版本
1 | select version(); |
3. 查看当前时间
1 | select now(); |
4. 退出
exit
或quit
注意命令结束的时候一定要带分号.
5. 显示所有的数据库
1 | show databases; |
6. 创建数据库
1 | create database [if not exists]数据库名 [default charset utf8 collate utf8_general_ci]; |
说明:
- 数据库名不要使用中文
- 由于数据库中将来会存储一些
非ascii
字符, 所以务必指定字符编码, 一般都是指定utf-8
编码 - CHARSET 选择 utf8
COLLATION 选择 utf8_general_ci mysql
中字符集是utf8,不是utf-8。
7. 切换到要操作的数据库
若要操作数据库中的内容, 需要先切换到要操作的数据库
1 | use 数据库名; |
8. 查看当前选择的数据库
1 | select database(); |
9. 删除数据库
1 | drop database [if exists]数据库名; |
2.2 DCL(用户管理)
DCL数据控制语言(Data Control Language),用户创建、删除、授权、修改密码。一般在企业中由DBA负责。
通常一个项目创建一个或多个用户。一个项目对应的数据库只有一个,这个用户只能对这个数据库有权限,无法对其他数据库进行操作。
MySql中添加用户,新建数据库,用户授权,删除用户,修改密码:
1.创建用户
A:先使用root账户进行登录
B:创建用户:
1 | CREATE USER 'username'@'IP地址' [IDENTIFIED BY 'PASSWORD'] 其中密码是可选项; |
例如:
create user “test”@”localhost” identified by “1234”;
CREATE USER ‘bolen‘@’192.168.189.71’ IDENTIFIED BY “123”;
也可以空密码,由用户登录后自行创建密码
2.为用户授权
1 | 授权格式:grant 权限 on 数据库.* to 用户名@登录主机 identified by "密码"; |
A: 首先为用户创建一个数据库(testDB
):
1 | mysql>CREATE DATABASE testDB DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; |
B: 授权test用户拥有testDB
数据库的所有权限(某个数据库的所有权限):
1 | 格式:grant 权限 on 数据库.* to 用户名@登录主机 identified by "密码"; |
1 | mysql>grant all privileges on testDB .* to test@localhost identified by '1234'; |
C: 如果想指定部分权限给一用户,可以这样来写:
1 | mysql>grant select,update on testDB.* to test@localhost identified by '1234'; |
3.撤销权限
1 | revoke 权限1,权限2 on 数据库.* from 用户名@IP地址; |
撤销指定用户在指定数据库上的执行权限。
4. 查看权限
1 | show grants for 用户名@IP地址; |
5. 删除用户
删除账户及权限:
1 | drop user 用户名@'%'; |
三、DDL(表的基本操作)
数据库中存储的是表(table), 表中存储的是一行行的数据。
本章介绍数据表本身的创建和处理。
3.1 查看当前数据库中的所有表
1 | show tables; |
注意: tables
后面有个s
3.2 创建表
创建表示例
通用语法:CREATE TABLE table_***name (column_name column_type);***
1 | CREATE TABLE [IF NOT EXISTS] 表名( |
注释:
primary-key //创建主键,为了加速查找。主键在表中唯一且不可重复、不能为null。
NOT NULL //非空值,如果这项为空mysql会报错
auto-increment //设为自增列,一个表中只能有一个自增列
default //是设置默认值 update userinfo set part_nid=2;
engine=innodb //设置存储引擎
存储引擎的选择[扩展]
MyISAM
和InnoDB
是最常用的两个mysql
数据库引擎,主要区别援引如下:
- InnoDB支持事务,MyISAM不支持,对于InnoDB每一条SQL语言都默认封装成事务,自动提交,这样会影响速度,所以最好把多条SQL语言放在begin和commit之间,组成一个事务;
InnoDB支持外键,而MyISAM不支持。对一个包含外键的InnoDB表转为MYISAM会失败;
InnoDB是聚集索引,数据文件是和索引绑在一起的,必须要有主键,通过主键索引效率很高。但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据。因此,主键不应该过大,因为主键太大,其他索引也都会很大。而MyISAM是非聚集索引,数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的。
InnoDB不保存表的具体行数,执行select count(*) from table时需要全表扫描。而MyISAM用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快;
Innodb不支持全文索引,而MyISAM支持全文索引,查询效率上MyISAM要高;
如何选择:
- 是否要支持事务,如果要请选择innodb,如果不需要可以考虑MyISAM;
- 如果表中绝大多数都只是读查询,可以考虑MyISAM,如果既有读写也挺频繁,请使用InnoDB。
- 系统奔溃后,MyISAM恢复起来更困难,能否接受;
- MySQL5.5版本开始Innodb已经成为Mysql的默认引擎(之前是MyISAM),说明其优势是有目共睹的,如果你不知道用什么,那就用InnoDB,至少不会差。
简单总结:
1、myisam查询效率更高,支持全文索引。innodb不支持全文索引,查询效率差myisam6-7倍。
2、innodb支持事务,行锁,外键。myisam不支持。
如果数据表涉及的存储数据多、查询多,用myisam,如文章表。如果数据表涉及业务逻辑多,增删改操作多,就用innodb,如订单表。
自增简介[扩展]
如果为某列设置自增列,插入数据时无需设置此列的值,默认将自增(表中只能有一个自增列)
1 | create table tb1( |
注意:
1、对于自增列,必须是索引(含主键)。
2、对于自增可以设置步长和起始值。
1 | show session variables like 'auto_inc%'; |
主键简介[扩展]
主键是一种特殊的唯一索引,具有非空唯一性。
如果主键使用单个列,则它的值必须唯一,如果是多列,则其组合必须唯一。
1 | create table tb1( |
外键简介[扩展]
外键,一个特殊的索引。
作用:
- 软件工程的模块化思想,一张表不宜过大;
- 可以用主表(这里也叫外表,主键表)来约束从表(外键表);比如主表设置一个学号,子表的外键的学号字段就只能在这个范围内输入;
创建方法一:建表时就指定
1 | creat table color( |
创建方法二: 后加
1 | alter table user_info add constraint fk_u_p foreign key user_info(part_nid) references part(nid); |
注意
对于从表来说,外键不一定需要作为从表的主键,外键也不一定是外表的主键,外表的唯一键就可以作为从表的外键。
3.3 查看表结构
通用语法:desc 表名;
describe tableName
3.4 查看表的创建语句
1 | show create table 表名; |
3.5 修改表
通用语法:ALTER TALBE 表名….
1.添加字段 :add
1 | alter table 表名 add( |
2.修改列类型:modify
1 | alter table 表名 modify |
注意:如果被修改的列已经存在数据,那么新的类型可能会影响到已存在的数据
3.修改列名:change
1 | alter table 表名 change(原列名 新列名 列类型); |
4.删除列:drop
1 | alter table 表名 drop |
5.更改表的名称:rename to
1 | rename table 原表名 to 新表名; |
6. 主键、外键相关操作
1 | 添加主键: |
7.修改表中default值
1 | 改默认值: |
3.6 删除表
1 | drop table [if exists] 表名; |
3.7 [扩展]复制表中的数据
1 | create table 表名2 as select * from 表名1; |
(仅复制数据不复制表的结构)
四、DML(增改删)
广义的DML包括增删改查(CRUD),此处特指针对表中的数据进行的操作,而不是表本身。
由于查询在工作中常用,所以又把查询单拎出来叫做DQL。
DML语言:增删改
DQL语言:查
crud是指在做计算处理时的增加(Create)、读取查询(Retrieve)、更新(Update)和删除(Delete)简写。crud主要被用在描述软件系统中数据库或者持久层的基本操作功能。
4.1 增
增加数据的方式有多种:
注意:在数据库中所有的字符串类型,必须使用单引,不能使用双引。日期类型也要使用单引。
1. 全列插入
1 | insert into 表名 values(值1, 值2,...); |
说明:
- 全列插入的时候需要每一列的数据都要添加上去.
- 对自动增长的数据, 在全列插入的时候需要占位处理, 一般使用0来占位.但是最终的值以实际为准.
2. 缺省插入
1 | insert into 表名(列1, 列2, ...) values(值1, 值2, ...); |
说明:
插入的时候,not null
和primary key
的列必须赋值, 其他的列根据情况来赋值.如果没有赋值则会使用默认值.
3. 同时插入多条数据
1 | insert into 表名 values(值1, 值2,...), (值1, 值2,...),...; |
或者
1 | insert into 表名(列1, 列2, ...) values(值1, 值2, ...), (值1, 值2, ...), ...; |
1 | insert into 表 (列名,列名...) select (列名,列名...) from 表 //从其他表获取值 |
4.2 改
1 | update 表名 set 列1=值1,列2=值2,... where [修改条件] |
栗子:
1 | 1. 修改年龄不等于22岁的学生的生日为2016-5-5 |
条件(条件是可选的)
- 条件必须是
boolean
类型的值或者表达式- 运算符:=,!=,<>,>,<,>=,<=,between..and, in(…),or ,and ,not, is null,is not null
- is null 不是 = null(永远是false)
4.3 删
1 | delete from 表名 [where 条件] |
五、DQL(简介)
数据表的查询最为常用,而且较复杂,此处为了内容的完整性只列出简单的查询语句,下一篇博文会单拎这部分介绍。
(其实日常%99的查询看此部分就足够了,如果想深入了解查询语句就看下一篇)
5.1 条件查询
####1. 简单条件查询:
1 |
|
2. 通配符查询:
1 | select * from 表 where name like 'ale%' - ale开头的所有(多个字符串) |
5.2 限制查询(方言)
1 | select * from 表 limit 5; - 前5行 |
5.3 排序查询
1 | select * from 表 order by 列 asc // 根据 “列” 从小到大排列 |
5.4 分组查询
1 | select num from 表 group by num |
注意:group by 必须在where之后,order by之前
5.5 连表查询
1 | 无对应关系则不显示 |
注意:
内连接所检索出来的结果,都是满足连接条件的。外链接是扩展内连接检索出来的结果集。外链接返回的结果,除了包含满足链接条件的记录,还包括不满足连接条件。
5.6 组合查询
1 | 组合,自动处理重合 |
六、MySQL 数据类型
MySQL中定义数据字段的类型对数据库的优化是非常重要的。 MySQL支持多种类型,大致可以分为三类:数值、日期/时间和字符串(字符)类型。
6.1 数值类型
MySQL支持所有标准SQL数值数据类型。 这些类型包括严格数值数据类型(INTEGER、SMALLINT、DECIMAL和NUMERIC),以及近似数值数据类型(FLOAT、REAL和DOUBLE PRECISION)。 关键字INT是INTEGER的同义词,关键字DEC是DECIMAL的同义词。 BIT数据类型保存位字段值,并且支持MyISAM、MEMORY、InnoDB和BDB表。 作为SQL标准的扩展,MySQL也支持整数类型TINYINT、MEDIUMINT和BIGINT。下面的表显示了需要的每个整数类型的存储和范围。
在上面表中的类型中, 最常用的是2中类型: int(整数)和decimal(浮点数).
6.2 日期和时间类型
表示时间值的日期和时间类型为DATETIME、DATE、TIMESTAMP、TIME和YEAR。 每个时间类型有一个有效值范围和一个”零”值,当指定不合法的MySQL不能表示的值时使用”零”值。 TIMESTAMP类型有专有的自动更新特性,将在后面描述。
最常用: datatime类型.
6.3 字符串类型
字符串类型指CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET。该节描述了这些类型如何工作以及如何在查询中使用这些类型。 CHAR和VARCHAR类型类似,但它们保存和检索的方式不同。它们的最大长度和是否尾部空格被保留等方面也不同。在存储或检索过程中不进行大小写转换。 BINARY和VARBINARY类类似于CHAR和VARCHAR,不同的是它们包含二进制字符串而不要非二进制字符串。也就是说,它们包含字节字符串而不是字符字符串。这说明它们没有字符集,并且排序和比较基于列值字节的数值值。 BLOB是一个二进制大对象,可以容纳可变数量的数据。有4种BLOB类型:TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB。它们只是可容纳值的最大长度不同。 有4种TEXT类型:TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT。这些对应4种BLOB类型,有相同的最大长度和存储需求。
最常用的: char, varchar和text类型.
常用的类型总结:
int:整型
double:浮点型,例如double(5,2)表示最多5位,其中必须有2位小数,即最大值:999.99
decimal:浮点型,不会出现精度缺失问题,比如金钱。
char:固定长度字符串类型:最大长度:char(255)
varchar:可变长度字符串类型:最大长度:varchar(65535)
text(clob):字符串类型,存储超大文本。
blob:字节类型,最大4G
date:日期类型,格式为:yyyy-MM-dd
time:时间类型:格式为:hh:mm:ss
timestamp:时间戳
datatime
七、约束(constraint)
当创建数据表的时候,为某一个字段设置约束,表示限定该列的数值内容。也可以通过修改表结构添加约束
7.1 默认值:default
改默认值:
ALTER TABLE testalter_tbl ALTER i SET DEFAULT 1000;删默认值:
ALTER TABLE testalter_tbl ALTER i DROP DEFAULT;
7.2 非空约束:not null
如果某个字段添加了非空约束,那么该字段的数值不能为0,也不是空””,更不是”NULL”。
1 | create table stu ( |
删除非空约束:
1 | alter table stu modify sname varchar(20); |
添加非空约束:
1 | alter table stu modify sname varchar(20) not null; |
该列已有的数据不能有null数值。
7.3 唯一性约束:unique
唯一性约束强调所在的字段所有的数值都是唯一的。不允许重复。允许空值(多个)。
1 | create table stu ( |
删除唯一约束:
1 | alter table stu modify sname varchar(20); |
添加唯一约束:
1 | alter table stu modify sname varchar(20) not null unique; |
该列已有的数据不能有null数值。
为已有的字段设置约束
alter table 表名 modify 字段 约束
添加新的字段,带约束
1 | alter table 表名 add 字段 数据类型 约束 |
先将已有的字段删除,重新添加带约束的。
alter table 表名 drop column 列名
alter table 表名 add 列名 数据类型 约束
7.4 主键约束:primary key。
主键约束:要求该字段数值不允许空,而且数值唯一。(not null+unique)
主键约束用于唯一的标识表中的每一个行记录的。一个表中最多只能有一个主键约束。
1 | create table stu ( |
删除主键:
1 | alter table stu drop primary key; |
添加主键:
1 | alter table teachers add primary key(id); |
主键自增: auto_increment
要求该字段数值不允许空,而且数值唯一。所以我们通常会指定主键类型为整型,然后设置其自动增长,这样可以保证在插入数据时主键列的唯一和非空特性。
修改表时设置主键自动增长:
1 | alter table stu modify sid int auto_increment; |
修改表时删除主键自动增长:
1 | alter table stu modify sid int; |
7.5 外键约束:foreign key,
7.5.1外键
- 思考:怎么保证关系列数据的有效性呢?任何整数都可以吗?比如一个班级表中有班级编号,班级名称,班级位置。还有一个学生表,有学生编号,学生姓名,学生 性别,以及班级编号等。
- 答:必须是学生表中班级编号列存在的数据,可以通过外键约束进行数据的有效性验证
外键作用数据完整性。
班级表可以叫做父表(主表):class,字段classno,该表的主键
学生表可以叫做子表(从表):student,字段sid是该表的主键,classno是该表的外键
父表:department,字段deptno,该表的主键
子表:employee,字段empno,该表的主键,deptno,该表的外键
子表的外键是父表的主键。
- 当对于子表插入数据,外键字段的数值不能随便插入,而取决于父表的主键数值。
- 对于父表的删除操作,要看子表中是否有记录引用该数值。
7.5.2 外键的设置
方法一:在创建子表的时候,直接标明外键。
1 | 设置外键语法: |
方法二:使用alter语句添加外键
1 | alter table student add constraint stu_classno foreign key(classno) references class(classno); |
1 | alter table student add constraint stu_classno foreign key(classno) references class(classno) on delete cascade; |
- 此时插入或者修改数据时,如果classno的值在student表中不存在则会报错
删除外键:
1 | alter table student drop foreign key stu_classno; |
7.5.3外键的级联操作
- 在删除class表的数据时,如果这个classno值在student中已经存在,则会抛异常
- 推荐使用逻辑删除,就可以解决这个问题
- 可以创建表时指定级联操作,也可以在创建表后再修改外键的级联操作
1 | 语法: |
- 级联操作的类型包括:
- restrict(限制):默认值,抛异常
- cascade(级联):如果主表的记录删掉,则从表中相关联的记录都将被删除
- set null:将外键设置为空
- no action:什么都不做