mysql初期使用全本

mysql
mysql前戏
数据库服务器-:运行数据库管理软件 =>pc

数据库管理软件:管理-数据库 => mysql

数据库:用来组织文件/表 => 文件夹

表:用来存放多行内容/多条记录 =>文件


mysql安装
1,安装包安装
数据库服务器 (一台电脑)
数据库管理系统 (Mysql 软件)
数据库 (data/db 一个文件夹)
表: (一个文件)
记录:(多个字段的信息组成一条记录,即文件中的一行内容)

1.解压mysql的压缩包 到 E:
2.E:\mysql-5.7.21-winx64\bin 添加系统的环境变量
3.初始化软件data目录
生成data目录
mysqld --initialize-insecure
存放数据库 => 文件=> 记录

*** 初始化的时候 一定等着 自己退出 ******
mysqld --initialize-insecure



二、开启mysql服务端
cmd
管理员身份运行
mysqld
4.mysqld(必须授权)

三、开启客户端、连接服务端
5.mysql -uroot -p

四、安装window服务

mysqld --install 安装window服务(直接安装就可以)
mysqld --remove 移除window服务


net start mysql : 开启服务端
net stop mysql :关闭服务端


五、忘记密码怎么办?
(1) 先关闭掉之前的mysql服务器的进程
(2) 跳过授权表开启mysql的服务端 mysqld --skip-grant-tables (开启服务端的 约束条件跳过授权)
(3) 客户端连接 mysql -uroot -p
(4) 更改密码:update mysql.user set authentication_string =password('') where User='root';
(5) 刷新权限 flush privileges;

查看进程号:tasklist |findstr mysql
杀死进程:taskkill /F /PID 进程号

六、统一字符编码
在Mysql软件的目录下新创建一个my.text,找到属性改后缀名为 ini
[mysqld]
# 设置mysql的安装目录 **后面的路径一定是安装sql的目录(自己电脑的)**
basedir=C:\mysql-5.7.22-winx64\mysql-5.7.22-winx64
# 设置mysql数据库的数据的存放目录,必须是data
datadir=C:\mysql-5.7.22-winx64\mysql-5.7.22-winx64\data
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
# mysql端口
port=3306
# 字符集
[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8

再次重启mysql 服务端(net stop mysqld(先关闭) net start mysqld(再次启动))


七、cmd运行之后 输入 mysql -uroot -p 进入mysql
\s 查看配置文件



mysql初始化
查看当前登陆的账号
select user();
修改密码
mysqladmin -uroot -p"123" password"456";
停止mysql服务
net stop mysql
重新启动服务
net stop mysql
刷新权限
flush privileges;
查看当前进程
tasklist |findstr mysql
杀死当前进程
taskkill /F /PID 6052 #6052进城号



mysql 库的操作
show databases; 查看所有的库
create database lzq; 创建lzq库
show create database lzq; 查看当前的库
select database(); 查看所在的库
use lzq; 用这个库
drop database lzq; 删除lzq库



mysql 表的操作

默认引擎
InnoDB 存储引擎 (默认)
create table t1(id int)engine=innodb;
MyISAM 存储引擎
create table t2(id int)engine=myisam;
Memory 存储引擎 (缓存)
create table t3(id int)engine=memory;
BLACKHOLE 存储引擎(黑洞,丢进去就没了)
create tables t4(id int)engine=blackhole;


相当于文件,表中的一条记录就相当于文件的一行内容,不同的是,表中的一行记录有对应的标题,称为表的字段

例子
show databases; 查看数据库
create database lzq; 新建lzq数据库
use lzq; 选择操作的数据库
create table study(
id int,
name varchar(20),
age int
); 建表
insert into study values(
1,'李志强',22,
2,'李二短',23
); 插入数据
desc study; 查看表的结构
select * from study; 查看表的数据
show create table study\G; 查看表的详细结构
拷贝表
create databases rkn; 新建数据库
create table studyinfo select * from lzq.study; 在lzq数据库中拷贝study表中的所有结构和数据
create table studyinfo select * from lzq.study where 1>2; 在lzq库+ where 1> 2 不成立,只拷贝结构
create table studyinfo like lzq.study; 拷贝表的结构
drop table study 删除study表



数据类型
整型 默认显示的宽度在最大宽度+1
作用:存储年龄,等级,id,各种号码等
tinyint 小整数
有符号 tinyint (-128~127)
create table t7(x tingint); 创建表格
insert into t7 values(-1); 默认有符号,范围(-128~127)可以插入
insert into t7 values(-130); 报错,超出范围

无符号 unsigned(0~255)
create table t8(x tingint unsigned); 创建表格
insert into t8 values(-130); 报错,超出范围
insert into t8 values(255); 成功 在0~255范围内

int 整数(0~4294967295)
int类型后存储的是显示的宽度,而不是存储的宽度
create table t9(
id int(1) unsigned
);
insert into t9 values(25555555); 显示成功


浮点型
作用:存储薪资、身高、体重、体质参数等
float 随着小数的增多,精度变得不准确
create table t1(x float(255,30)); #范围255~30
insert into t1 values(1.1111111111111111111111)
select * from t1;

double 随着小数的增多,精度变得不准确,but比float精度强
create table t2(x double(255,30));
insert into t2 values(1.1111111111111111111111)
select * from t2;

decimal 随着小数的增多,精度最准确
create table t3(x decimal(65,30));
insert into t3 values(1.1111111111111111111111)
select * from t3;


日期类型
****year 年
YYYY(1901-2155)
****date 年-月-日
YYYY-MM-DD(1000-01-01~9999-12-31)
****time 时间
HH:MM:SS
*****datetime 年-月-日 时;分:秒
YYYY-MM-DD HH:MM:SS
**timestamp
YYYYMMDD HHMMSS()
new sql内置函数=>获取当前的时间
例子
create table t9(time timestamp);
insert into t9 values(now());
select * from t9;

datetime和timestamp的区别
1.datetime范围是1001~9999年,timestamp范围是1970~2038年
2.datetime存储的时间与时区无关,timestamp存储的时间和时区有关
3.datetime用8字节存储空间,timestamp存储空间是4个字节,后者比前者利用率更高
4.datetime默认值是null,timestamp默认值不为空,默认是当前时间


字符类型
char :定长,简单粗暴,浪费空间,存取速度快
字符长度(0~255)
指定长度10,<10剩下的用空格添到10个字符存储;>10则报错


varchar :变长,精准,节省空间,存取速度慢
字符长度(0-65535)
尾部有空格也会被保留下来

效率 char > varchar > text

例子:
create table t10(x char(5),y varchar(4));
select * from t10;
insert into t10 values('你是谁 ','你谁啊 '); 给x和y添加值
select x,char_length(x),y,char_length(y) from t10;
+-----------+----------------+------------+----------------+
| x | char_length(x) | y | char_length(y) |
+-----------+----------------+------------+----------------+
| 你瞅啥 | 3 | 你瞅啥 | 4 |
+-----------+----------------+------------+----------------+
#看上去x是占用3个字符,实则占用3个字符+1个空格+1个浪费掉=>占用5个字符
方法:
mysql> SET sql_mode = 'PAD_CHAR_TO_FULL_LENGTH'; #修改mode 只作用于这次会话
select x,char_length(x),y,char_length(y)from t10;
+-------------+------+----------------+
| x | y | char_length(y) |
+-------------+------+----------------+
| 你瞅啥 | 5 | 4 |
+-------------+------+----------------+



枚举类型和集合类型
enum 枚举,只能选一个
set 集合,多选
例子
create table t11(
id int,
name varchar(50),
sex enum('male','female','other'),
level enum('vip1','vip2','vip3'),
fav set('play','music','read','study')
);
insert into t11 values
(1,'赵云','male','vip2','play,music'),
(2,'赵四','other','vip3','play,music'),
select * from t11;
+------+---------+-------+-------+------------+
| id | name | sex | level | fav |
+------+---------+-------+-------+------------+
| 1 | 赵云 | male | vip2 | read,study |
| 2 | 赵云2 | other | vip4 | play |
+------+---------+-------+-------+------------+



完整性约束
作用:保证数据的完整性和一致性


not null和null和default
例子
create table t12(
id int not null,
name varchar(50) not null,
age int(3) not null,
sex enum('male','female') default'male', #默认性别
fav set('smoke','drink','tangtou') default'drink,tangtou' #默认爱好
);
insert into t12(id,name,age) values(1,'lzq',22);
insert into t12(id,name,age) values(2,'led',23);
select * from t12;
+----+------+-----+------+---------------+
| id | name | age | sex | fav |
+----+------+-----+------+---------------+
| 1 | lzq | 22 | male | drink,tangtou |
+----+------+-----+------+---------------+
| 2 | led | 23 | male | drink,tangtou |
+----+------+-----+------+---------------+


unique 在mysql中称单列唯一
例子1
create table t12(
id int,
name char(10)
);
insert into t12 values(
1,'IT',
2,'IT',
);
#没问题


例子2
create table t13(
id int,
name char(10) unique
);
insert into t12 values(
1,'IT',
2,'sale'
);
#如果 2,'IT';则报错!!!!



联合唯一 (只要有一列不一样就可以插入)
例子3
create table t14(
id int,
ip char(15),
port int,
unique(id),
unique(ip,port)
);
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int(11) | YES | UNI | NULL | |
| ip | char(15) | YES | MUL | NULL | |
| port | int(11) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
insert into t14 values
(1,'192.168.11.23','80'),
(2,'192.168.11.23','81'),
(3,'192.168.11.25','80');
总结:
只要有一列唯一,就可以插入
insert into t14 values
( 4,'192.168.11.25','82')



primary key(索引优化)
等价于 not null + unique,字段的值不为空且唯一
例子:
create table t15(
id int primary key auto_increment, #primary key 设置唯一主键,auto_increment自增长,以后插入数据可以不用id
name varchar(10) unique
);
insert into t15(name) values('lzq');
insert into t15(name) values('led');
insert into t15(name) values('李志强');
select * from t14;
+----+-----------+
| id | name |
+----+-----------+
| 2 | led |
| 1 | lzq |
| 3 | 李志强 |
+----+-----------+
#删除之后再添加id = 在删除的id + 1
delete from t15 where id = 3; #在t15表里删除 id=3的数据
insert into t15(name) values ('李志强'); #自添加的id 添加值
select * from t15;
+----+-----------+
| id | name |
+----+-----------+
| 2 | led |
| 1 | lzq |
| 4 | 李志强 |
+----+-----------+
扩展:mysql里只要看到带key的,都为了查询优化有关



foreign key 外键 (建立两张表之间的联系)
废话不多说,直接上例子
例子:
#主表(被关联的表),先建这个
create table dep(
id int primary key, #primary key 设置主键,唯一的值
name varchar(20) not null,
descripe varchar(20) not null);

#从表(关联的表),后建这个
create table emp(
id int primary key,
name varchar(20) not null,
age int not null,
dep_id int,
constraint fk_dep foreign key(dep_id) references dep(id) #不加 ,
on delete cascade #不加 , 同步删除
on update cascode #同步更新
);
#解释:constraint 约束 / fk_dep起的名字 /foregin key(dep_id) 给emp表dep_id设置外键/references 关联,
#给emp这个表的dep_id字段设置外键,让它关联主表dep表中的id

插入数据
insert into dep values
(1,'IT','IT技术有限部门'),
(2,'销售部','销售部门'),
(3,'财务部','花钱太多部门');

insert into emp values
(1,'zhangsan',18,1),
(2,'lisi',19,1),
(3,'egon',20,2),
(4,'yuanhao',40,3),
(5,'alex',18,2);

扫描二维码关注公众号,回复: 3615974 查看本文章

#ok 这样就可以同步删除同步更新了 ,符合我们现实生活中真实的情况
#切记:添加数据和删除数据的时候,都要在主表(被关联的表)添加或删除!!!

1==>2 1就是从表,2就是主表

#!!!如果建表的时候没有直接进行外键约束,那么就需要通过后期的设置表的结构进行添加,具体命令如下
#添加外键约束:alter table 从表 add constraint 外键(形如:FK_从表_主表) foreign key 从表(外键字段) references 主表(主键字段);
#删除外键约束:alter table 表名 drop foreign key 外键(区分大小写);
外键的变种:
分析步骤:
#1、先站在左表的角度去找
是否左表的多条记录可以对应右表的一条记录,如果是,则证明左表的一个字段foreign key 右表一个字段(通常是id)

#2、再站在右表的角度去找
是否右表的多条记录可以对应左表的一条记录,如果是,则证明右表的一个字段foreign key 左表一个字段(通常是id)

#3、总结:
#多对一:
如果只有步骤1成立,则是左表多对一右表
如果只有步骤2成立,则是右表多对一左表

#多对多
如果步骤1和2同时成立,则证明这两张表时一个双向的多对一,即多对多,需要定义一个这两张表的关系表来专门存放二者的关系

#一对一:
如果1和2都不成立,而是左表的一条记录唯一对应右表的一条记录,反之亦然。
这种情况很简单,就是在左表foreign key右表的基础上,将左表的外键字段设置成unique即可


关联
create table t20(
id int primary key auto_increment,
name varchar(20) not null,
);
create table t21(
id int primary key auto_increment,
name varchar(20) not null,
press_id int not null,
constraint fk_t20_t21 foreign key(press_id) references t20(id)
on delete cascade
on update cascade
);

insert into t20(name) values
('北京工业地雷出版社')
('人民音乐不好听出版社')
('知识产权没有用出版社');

insert into t21(name,press_id) values
('九阳神功',1),
('九阴真经',2),
('九阴白骨爪',2),
('独孤九剑',3),
('降龙十巴掌',2),
('葵花宝典',3);

select * from t21;
select * from t20;



单表查询
关键字执行的优先级
from :找到表
where :拿着指定的约束条件,去表中取出一条条记录
group by :取出的记录进行分组,如果没有group by,则整体是一体
having :将分组进行having过滤
select :执行 select
distinct :去重
order by :将结果进行排序
limit :限制显示的条数

例子
create table employee(
id int primary key auto_increment,
name varchar(20) not null,
sex enum('male','female') not null default 'male', #大部分是男的
age int(3) unsigned not null default 28,
hire_date date not null,
post varchar(50),
post_comment varchar(100),
salary double(15,2),
office int,#一个部门一个屋
depart_id int
);
#三个部门:教学,销售,运营
insert into employee(name ,sex,age,hire_date,post,salary,office,depart_id) values
('egon','male',18,'20170301','老男孩驻沙河办事处外交大使',7300.33,401,1), #以下是教学部
('alex','male',78,'20150302','teacher',1000000.31,401,1),
('wupeiqi','male',81,'20130305','teacher',8300,401,1),
('yuanhao','male',73,'20140701','teacher',3500,401,1),
('liwenzhou','male',28,'20121101','teacher',2100,401,1),
('jingliyang','female',18,'20110211','teacher',9000,401,1),
('jinxin','male',18,'19000301','teacher',30000,401,1),
('xiaomage','male',48,'20101111','teacher',10000,401,1),

('歪歪','female',48,'20150311','sale',3000.13,402,2),#以下是销售部门
('丫丫','female',38,'20101101','sale',2000.35,402,2),
('丁丁','female',18,'20110312','sale',1000.37,402,2),
('星星','female',18,'20160513','sale',3000.29,402,2),
('格格','female',28,'20170127','sale',4000.33,402,2),

('张野','male',28,'20160311','operation',10000.13,403,3), #以下是运营部门
('程咬金','male',18,'19970312','operation',20000,403,3),
('程咬银','female',18,'20130311','operation',19000,403,3),
('程咬铜','male',18,'20150411','operation',18000,403,3),
('程咬铁','female',18,'20140512','operation',17000,403,3);


where约束查询
select age,name from employee where age > 40;
select name,salary from employee where salary > 5000;
select name,salary from employee where salary between 5000 and 10000;
select name,age from employee where age in (18,28);
select * from employee where name like 'jin%' #查询以jin开头的名字
select age from employee where name like 'ale_'; #查询以ale开头的名字

group by分组查询
前提:可以按照任意字段分组,但是分组完毕后,
比如group by post,只能查看post字段,如果想查看组内信息,需要借助于聚合函数
为何要分组呢?
1.取每个部门的最高工资
2.取每个部门的员工数
3.取男人数和女人数
1.设置sql的模式:set global sql_mode='ONLY_FULL_GROUP_BY';设置后重启mysql
2.select post from employee group by post;
group by 分组之后只能查看当前字段,如查看组内信息需要借助聚合函数


聚合函数
max()求最大值
select post,max(salary) from employee group by post;
min()求最小值
select post,min(salary) from employee group by post;
avg()求平均值
select post,avg(salary) from employee group by post;
sum() 求和
select post,sum(salary) from employee group by post;
count() 求总个数
select post,count(id) from employee group by post;


having过滤
1.执行的优先级:where > group by > having
2.having发生在group by 之后,可以使用分组字段,想要获取其他字段,可以使用聚合函数

练习题
1. 查询各岗位内包含的员工个数小于2的岗位名、岗位内包含员工名字、个数
select post,group_concat(name),count(id) from employee group by post having count(id) < 2;
2. 查询各岗位平均薪资大于10000的岗位名、平均工资
select post,avg(salary) from employee group by post having avg(salary) > 10000;
3. 查询各岗位平均薪资大于10000且小于20000的岗位名、平均工资
select post,avg(salary) from employee group by post having avg(salary) between 10000 and 20000;


order by 查询排序
asc 升序
desc 降序
例子:
1. 查询所有员工信息,先按照age升序排序,如果age相同则按照hire_date降序排序
select * from employee order by age asc,hire_date desc;
2. 查询各岗位平均薪资大于10000的岗位名、平均工资,结果按平均薪资升序排列
select post,avg(salary) from employee group by post having avg(salary)>10000 order by avg(salary)asc;
3. 查询各岗位平均薪资大于10000的岗位名、平均工资,结果按平均薪资降序排列
select post,avg(salary) from employee group by post having avg(salary) > 10000 order by avg(salary) desc;

limit 限制查询的记录数
select * from employee order by salary desc limit 5,5 # 第一个5:起始位置 第二个表示:查询数
select * from employee order by salary desc limit 10,5 # 10:从第11个数据开始查询 第二个表示:查询数




多表查询
1.笛卡尔积,不适合任何查询
select * from employee,department; #直接把两个表生成一个虚拟的表
2.内连接:只连接匹配的行
select employee.id,employee.name,employee.age,employee.sex,department.name from employee,department where employee.dep_id=department.id;
# 查询employee,department中的 employee中的dep_id 等于 department.id
3.外链接之左连接:优先显示左表全部记录
4.外链接之右连接:优先显示右表全部记录


子查询
一句话:内层查询的结果当做外层查询的条件
子查询包含了 运算符等查询方法和not in and 等关键字
1、查询平均年龄在25岁以上的部门名
select name from department where id in (select dep_id from employee group by dep_id having avg(age) > 25);

2、查看不足1人的部门名
select name from department where id not in (select dep_id from employee group by dep_id);

3、查询大于所有人平均年龄的员工名与年龄
select name,age from employee where age > (select avg(age) from employee);

4、查询大于部门内平均年龄的员工名、年龄
思路:
(1)先对员工表(employee)中的人员分组(group by),查询出dep_id以及平均年龄。
(2)将查出的结果作为临时表,再对根据临时表的dep_id和employee的dep_id作为筛选条件将employee表和临时表进行内连接。
(3)最后再将employee员工的年龄是大于平均年龄的员工名字和年龄筛选。

select * from employee inner join (select dep_id,avg(age) as b from employee group by dep_id) as A on employee.dep_id = A.dep_id where employee.age > A.b;



创建用户
创建用户
1.use mysql
2.create user 'root'@'192.168.1.11' indentified by '123'; #指定ip是192.168.1.11的root用户
2.create user 'root'@'192.168.1.%' indentified by '123'; #指定ip是192.168.1.任何root用户
3.drop user 'root'@'192.168.1.11'; #删除用户
4.rename user '用户名'@'ip地址' to '新用户'@'ip地址' #修改用户
5.set password for '用户名'@'ip地址'=password('新密码') #修改密码

对用户进行授权
show grants for '用户'@'ip地址';
grant select,insert,update on db1.t1 to 'lzq'@'%';#授权 mjj用户仅对db1.t1文件有查询、插入和更新的操作
grant all privileges on db1.* to 'lzq'@'%'; #lzq用户对db1数据库有任何操作

取消权限
remove all on db1.t1 from 'lzq'@'%'; 取消lzq用户对db1数据库的操作



pymysql模块的使用
连接的操作
1.import pymysql
2.user = input('请输入用户名:')
3.pwd = input('请输入密码:')
4.conn = pymysql.connect(host='127.0.0.1', #需要连接的地址
port=3306, #端口号
user='root', #连接的用户名
password='', #密码,有就写
db='lzq', #连接的数据库
charset='utf8') #默认编码
5.cursor = conn.cousor() #创建游标
6.sql = 'select * from userinfo where username = $s and pwd = %s'
print(sql)
7.cursor.execute(sql) #执行sql语句
8.result=cursor.execute(sql,[user,pwd]) #执行sql语句,返回sql查询成功的记录数目
print(result)
9.cursor.close() # 关闭连接,游标和连接都要关闭
conn.close()

if result:
print('登陆成功')
else:
print('登录失败')

增删改 conn.commit()
在数据库进行增删改的时候必须用commit()方法,否则插入的数据不生效
1.conn = pymysql.connect(host='locahost',port=3306,user='root',password='',db='lzq',charset='utf8')
2.curor = conn.curor()
3.sql = 'insert into userinfo (usernam,pwd) values (%s,%s)' #插入一条数据


sql='update userinfo set username = %s where id = 2'
effect_row = cursor.execute(sql,username)
print(effect_row)
conn.commit()


sql = 'delete from userinfo where id = 2'
effect_row = cursor.execute(sql)
conn.commit()


fetchone() 获取下一行数据,默认是第一行
fetchall() 获取所有的数据
fetmany(4) 获取4行的数据

例子
import pymysql #引用模块
conn = pymsql.connect(host = 'localhost',
port=3306,
user='root',
pwd='',db'lzq',
charset='utf8')
cursor = conn.cursor() #创建游标
#cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
#在实例化的时候,将属性cursor设置为pymysql.cursors.DictCursor
sql = 'select * from userinfo' #在那个表查询
cursor.execute(sql) #执行sql语句
row = cursor.fetchone() #查询第一行
print(row)
row = cursor.fetchall()#查询所有数据
print(row)
row = cursor.fetmany(5)#查询5行数据
print(row)
cursor.close()
conn.close()



索引
作用:约束和快速查询
常见的索引的方式
普通索引
create index 索引的名字 on 表明(添加索引的字段)
唯一索引
create unique index 索引名 on 表名(列名)
主键索引
alter table 表名 add primary key(列名);
联合索引
create index 索引名 on 表名(列名1,列名2);

使用索引的三步走
创建索引
命中索引
正确的使用索引

索引的注意事项
(1)避免使用select *
(2)count(1)或count(列) 代替count(*)
(3)创建表时尽量使用char代替varchar
(4)表的字段顺序固定长度的字段优先
(5)组合索引代替多个单列索引(经常使用多个条件查询时)
(6)尽量使用短索引 (create index ix_title on tb(title(16));特殊的数据类型 text类型)
(7)使用连接(join)来代替子查询
(8)连表时注意条件类型需一致
(9)索引散列(重复少)不适用于建索引,例如:性别不合适

猜你喜欢

转载自www.cnblogs.com/lzqrkn/p/9812871.html