MySQL笔记(第一天)
数据库是用来存放数据的仓库
关系模型:记录和记录之间通过属性之间的关系来进行连接,保证数据独立性,并形成数据集之间的关系。
关系模型的特点:
每个表都是独立的;通过关系字段将两个表连接起来;关系:两个表的公共字段。关系型数据库中多个表联合查询效率低下。
为了解决关系型数据库多表查询效率的问题,项目中使用了NoSQL(非关系型数据库,Redis、mongodb等等),在数据库中按照键值对来存储,它是关系型数据库的补充。
非关系型数据库主要就是为了查询用的。存储还是要用关系型数据库。也就是一个项目中要用到两个数据库。
数据库中存放的是表,表中存放的是数据。
Structured Query Language(结构化查询语言),是用来操作关系型数据库的一门语言。这是一个关系型数据库的通用操作语言,也称为标准SQL,也叫SQL-92。
常用的关系型数据库
关系型数据库 开发公司 使用语言
access 微软 SQL 办公室使用的一种小型数据库
SQL Server 微软 T-SQL
Oracle 甲骨文 PL/SQL
MySQL 被甲骨文收购 MySQL
思考:已知标准SQL可以在所有的关系型数据库上运行,在Oracle上编写的PL/SQL能否在MySQL上运行?
答:不一定,只能运行标准SQL。扩展的东西不能运行。
安装PHPStudy,数据库就自动安装好了,就可以使用了。
第一步:连接服务器。
数据库是CS模式的软件,所以要连接数据库必须要有客户端软件。
MySQL数据库默认端口号是3306。localhost=127.0.0.1 本地
第一类:通过windows界面连接服务器
Navicat_for_MySQl MySQL-Front
第二类:通过web窗体连接服务器
phpMyAdmin(只要有浏览器就可以访问数据库)
第三类:通过命令行连接服务器
host -h 主机
port -P 端口号
user -u 用户名
password -p 密码
连接数据库
mysql -h127.0.0.1(/localhost) -P3306 -uroot -proot (明文)
如果连接本地数据库,-h可以省略,如果服务器端口号是3306,-P也可以省略。
mysql -uroot -proot (明文)
密文:
mysql -uroot -p => Enter => 输入密码即为密文
退出:exit/quit/\q
数据库、表相关
数据库:数据库中存放的是表,一个数据库中可以存放多个表
表:表示用来存放数据的
关系:两个表的公共字段
行:也称记录,也称实体
列:也称字段,也称属性
就表结构而言,表分为行和列;就表数据而言,表分为记录和字段;就面向对象而言,一个记录就是一个实体,一个字段就是一个属性。
数据相关
数据冗余:相同的数据存储在不同的地方(冗余只能减少,不能杜绝)
数据完整性:正确性+准确性=数据完整性
正确性:数据类型正确
准确性:数据范围要准确
解决数据冗余问题:分表(用关系转化成多个表) => 冗余越少,表越多,查询速度越慢
数据库的操作
连接数据库:mysql -uroot -proot
显示所有数据库:show databases;
创建数据库:create database [if not exists] 数据库名 [选项];
如果是特殊字符或关键字做数据库名怎么办?使用反引号将数据库名引起来。
由此引申出:不管你起的数据库名是不是关键字或特殊字符,统统加上反引号,绝对出不了错。
创建数据库时指定存储的字符编码:create database student charset=gbk;
如果不指定,安装数据库的时候使用的是什么编码,就是什么编码。
查看安装数据库时使用的是什么编码的指令:show variables like 'character_set_%';
数据库保存的路径在安装MySQL的时候就配置好。
也可以在my.ini配置文件中更改数据库的保存地址。(datadir="")
一个数据库就对应一个文件夹,在文件夹中有一个db.opt文件,在此文件中设置数据库的字符集和校对集。
如果要创建的数据库已存在,就会报错。
解决方法:创建数据库的时候判断一下数据库是否存在,如果不存在再创建。
如果数据库名是关键字和特殊字符要报错。
解决方法:在特殊字符、关键字上加上反引号。
创建数据库的时候可以指定字符编码。
创建数据库如果不指定字符编码,默认和MySQL服务器的字符编码是一致的。
数据库创建后,只默认带有information_schema、mysql、performance_schema、test/sys四个数据库。
删除数据库:drop databaase [if exists] 数据库名;
显示创建数据库的语句:show create database 数据库名;
修改数据库:alter database 数据库名 charset=字符编码;
只能修改数据库的字符编码。(注意:数据库里的utf字符编码没有“-”)
选择数据库:use 数据库名;
表的操作
显示所有表:show tables;
创建表:create table [if not exists] 表名
(
字段名
数据类型 [null|not null] [default] [auto_increment] [primary key] [comment],
字段名
数据类型 ...
)[engine=存储引擎] [charset=字符集];
null|not null 是否为空
default 默认值(此处如果要输入中文字符,要在创建表之前先执行mysql>set names gbk;)
auto_increment 自动增长,默认从1开始,每次递增1
primary key 主键,主键的值不能重复,不能为空,每个表必须只能有一个主键
comment 备注
engine 引擎 myisam,innodb(引擎决定了数据的存储方式和查询方式)
若不指定引擎,默认是innodb。
若不指定字符集,就默认跟所在数据库保持一致。
表名和字段名如果用了关键字,要用反引号引起来。
数据表的文件
一个数据库对应一个文件夹
一个表对应一个或多个文件
引擎是myisam,一个表对应三个文件
.frm 存储的是表结构
.myd 存储的是表数据
.myi 存储的是表索引
引擎是innodb,一个表对应一个表结构文件(.frm->framework架构:存储的是表结构)
innodb的所有表的数据都保存在ibdata1文件中,如果数据量很大,会自动的创建ibdata2,ibdata3...
推荐使用innodb。
myisam:查询速度快,容易产生碎片,不能约束数据。
innodb:以前没有myisam查询速度快,现在已经提速了(虽然还是没有myisam快,但已经很可以了),不产生碎片,可以约束数据。
显示创建表的语句:show create table 表名;
show create table 表名 \G;(竖着排)
查看表结构:describe 表名;/desc 表名;
删除表:drop table [if exists] 表1,表2,...;(注意:没有drop *;的写法)
复制表:语法一:create table 新表名 select 字段,字段,字段,... from 旧表名;
create table 新表名 select * from 旧表名;(复制所有的数据)
特点:不能复制父表的键,能够复制父表的数据
语法二:create table 新表名 like 旧表名;
特点:只能复制表结构,不能复制表数据
所有字段可以用*表示。
修改表:
语法:alter table 表名;
添加字段:alter table 表名 add [column] 字段名 数据类型 [位置]
alter table stu add add
varchar(20); 默认放到最后的位置
alter table stu add gender
char(1) after name; 放到name字段的后面(注意,没有before)
alter table stu add score
int first; (也没有last,second之类的),只有两个关键字after和first,足够了。
删除字段:alter table 表名 drop [column] 字段名
alter table stu drop gender
;
修改字段(改名):alter table 表名 change [column] 原字段名 新字段名 数据类型...
alter table stu change name stu_name varchar(20);
修改字段(不改名):alter table 表名 modify 字段名 字段属性...
alter table stu modify sex char(1);(主键被视为约束,不能用modify来修改)
alter table stu modify add
varchar(20) default '地址不详';
修改引擎:alter table 表名 engine=引擎名
alter table stu engine=innodb;
修改表名:alter table 表名 rename to 新表名
alter table student rename to stu;
将表移动到其他数据库(这种情况很少实用)
alter table student rename to 另一个存在的数据库名.新表名(表名可相同也可不同)
数据的操作(增删改查)
插入数据
语法:insert into 表名 (字段名,字段名,...) values (值1,值2,...);
insert into student values (值1,值2,...);(插入所有字段,前面的字段名可以省略。若是省略前面的字段名,则必须插入所有字段并且要跟表的字段顺序保持一致)
insert into student (id,name) values (1,'tom');
(插入的字段和表的字段可以顺序不一致,但是插入字段名和插入的值一定要一一对应。)
insert into student values (1,'tom',12,'男');
注意:如果主键位数据已存在,则不允许重复插入。比如id为主键,id=1的位置上已经有了数据,则不可再往id=1的位置插入数据。
插入字段名的顺序和数据表中字段名的顺序可以不一致;
插入值的个数、顺序必须和插入字段名的个数、顺序要一致;
插入值的个数、顺序和表中的字段个数、顺序一致,这时候插入字段可以省略;
自动增长列,可以直接插入null。
插入空值和默认值
insert into stu values (5,'jack',null,default);
default关键字用来插入默认值,null用来插入空值。
插入多条数据
insert into stu values (6,'李白','男','唐朝'),(7,'杜甫','男','宋朝'),...;
更新数据
语法:update 表名 set 字段=值 [where 条件]
update student set sex='女' where id=4;
update student set score=90 where name='李白';
update student set sex='女',age=24,score=100 where id=1;
update student set sex='女';(这样将影响到表中所有数据,意为将表中所有人的性别都改成女)
删除数据
语法:delete from 表名 [where 条件] [order by 排序] [limit 限制]
delete from student where id=1;
delete from student where name='berry';
delete from student;(删除表中所有数据=truncate table student)
只能逐条删除,不能加逗号同时删除多条。
delete from 表名和truncate table 表名的区别?
delete from 表名:遍历表记录,一条一条的删除;
truncate table 表名:将原表销毁,再创建一个同结构的新表,就清空表而言,这种方法效率高。
查询数据
语法:select 列名,列名,列名,... from 表名;(select * from 表名;)
select id from student;
select id,name from student;
select * from student;
数据传输时使用字符集
发现:在插入数据的时候,如果有中文就会报错(或者无法插入)
show variables like 'character_set_%';
Variable_name Value
character_set_client utf8 表示用utf8编码接收客户端的指令
character_set_database utf8 表示数据库用utf8编码存储数据
character_set_results utf8 表示用utf8编码返回结果
更改接收客户端指令的编码:set character_set_client=gbk;
原因:返回编码是utf8,客户端是gbk。
解决:set character_set_results=gbk;更改接收返回结果的编码。
也可直接使用一行代码解决:set names gbk;/set names utf8;
设置什么编码取决于客户端的编码,通过set names 编码值;设置编码。
环境变量配置
我的电脑->右键->属性->高级->环境变量->path下加上;D:\phpstudy_pro\Extensions\MySQL8.0.12\bin 设置完成之后,先关闭cmd客户端,再重新打开,就可以了。
校对集(实际工作中对于排序的处理一般不会用这个,会有专门的处理方法)
概念:在某种字符集下,字符之间的比较关系,比如a和B的大小关系,如果区分大小写a>B,如果不区分大小写则a 校对集依赖于字符集,不同的字符集的比较规则不一样,如果字符集更改,校对集也要重新定义。
不同校对集对同一字符序列比较的结果是不一致的。
可以在定义字符集的同时定义校对集
语法:collate=校对集;
校对集规则:
_bin: 按二进制编码比较,区分大小写
_ci: 不区分大小写
mysql> create table stu1(
-> name char(1)
-> )charset=utf8 collate=utf8_general_ci;
mysql> create table stu2(
-> name char(1)
-> )charset=utf8 collate=utf8_bin;
mysql> insert into stu1 values ('a'),('B');
mysql> insert into stu2 values ('a'),('B');
mysql> select * from stu1 order by name; => a B
mysql> select * from stu2 order by name; => B a