MySQL知识点总结
文章目录
-
下载和安装
https://downloads.mysql.com/archives/community/
C:\Program Files\mysql-5.7.31-winx64
mysqld]
port=3306
basedir=C:\\Program Files\\mysql-5.7.31-winx64
datadir=C:\\Program Files\\mysql-5.7.31-winx64\\
data
character-set-server=utf8
collation-server=utf8_general_ci
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
user="root"
password="root123"
"C:\Program Files\mysql-5.7.31-winx64\bin\mysqld.exe"
win下初始化可能会出错,需安装两个补丁文件dxwebsetup.exe,vcredist_x64.exe
"C:\Program Files\mysql-5.7.31-winx64\bin\mysqld.exe"
"C:\Program Files\mysql-5.7.31-winx64\bin\mysqld.exe"
net start mysql57
net stop mysql57
"C:\Program Files\mysql-5.7.31-winx64\bin\mysqld.exe"
set password = password('pwd123');
mysql -u root -p;
-
数据库管理
show databases;
create database 数据库名 default charset 编码 collate 排序规则;
create database day25db default charset utf8 collate utf8_general_ci;
drop database 数据库名
drop database day25db;
use 数据库名
use day25db;
use day25db;
show tables;
create table 表名(
列名 数据类型,
列名 数据类型,
列名 数据类型
)default charset=utf8;
create table info(
id not null auto_increment primary key,
name varchar(16) not null,
email varchar(32) not null,
connent text not null,
password varchar(64) not null,
age int not null
)default charset=utf8;
drop table 表名;
drop table info;
delete from 表名;
delete from info;
truncate table 表名;(是的快,无法回滚)
truncate table info;
alter table 表名 add 列名 类型;
alter table 表名 add 列名 类型 default 默认值;
alter table 表名 add 列名 类型 not null default 默认值;
alter table 表名 add 列名 类型 not null auto_increment primary key;
alter table 表名 drop column 列名;
alter table info drop column email;
alter table 表名 modify column 列名 类型;
alter table info modify column email varchar(32) default None;
alter table 表名 change 原列名 新列名 新类型;
alter table info change password pwd varchar(64) not null;
alter table 表名 alter 列名 set default 默认值;
alter table info alter age set default 99;
alter table 表名 alter 列名 drop default;
alter table info alter email drop default;
alter table 表名 add primary key(列名);
alter table info add primary key(id);
alter table 表名 drop primary key;
alter table info drop primary key;
-
数据行管理
insert into 表名(列名,列名,列名) values(对应列的值,对应列的值,对应列的值);
insert into info(name,email,connent,password,age) vaules(
'jack','jk258@qq.com','python全栈','jk258369',38);
delete from 表名;
delete from 表名 where 条件;
elete from tb1;
delete from tb1 where name="wupeiqi";
delete from tb1 where name="wupeiqi"
and password="123";
delete from tb1 where id>9;
update 表名 set 列名=值;
update 表名 set 列名=值 where 条件;
update tb1 set name="wupeiqi";
update tb1 set name="wupeiqi" where id=1;
update tb1 set age=age+1;
update tb1 set age=age+1 where id=2;
update L3 set name=concat(name,"db");
update L3 set name=concat(name,"123") where id=2;
select * from 表名;
select 列名,列名,列名 from 表名;
select 列名,列名 as 别名,别名 from 别名;
select * from 别名 where 条件;
select * from tb1;
select id,name,age from tb1;
select id,name as N,age, from tb1;
select id,name as N,age, 111 from tb1;
select * from tb1 where id = 1;
select * from tb1 where id > 1;
select * from tb1 where id != 1;
select * from tb1 where name="wupeiqi"
and password="123";
-
数据类型
int[(m)][unsigned][zerofill]
int 表示有符号,取值范围:-
2147483648 ~ 2147483647
int unsigned 表示无符号,取值范围:0 ~4294967295
int(5)zerofill
tinyint[(m)][unsigned][zerofill]
igint[(m)][unsigned][zerofill]
decimal[(m[,d])][unsigned][zerofill]
FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]
OUBLE[(M,D)] [UNSIGNED] [ZEROFILL]
char(m)
text
mediumtext
A TEXT column with a maximum length of 16,777,215 (2**24 − 1) characters.
longtext
A TEXT column with a maximum length of 4,294,967,295 or 4GB (2**32 − 1)
datetime
YYYY-MM-DD HH:MM:SS(1000-01-01 00:00:00/9999-12-31 23:59:59)
timestamp
YYYY-MM-DD HH:MM:SS(1970-01-01 00:00:00/2037年)
date
time
HH:MM:SS('-838:59:59'/'838:59:59')
-
如何来避免SQL注入
select * from users where name='' or 1=1
cursor.execute("select * from users where name=%s and password=%s", [user, pwd])
-
必备SQL和表关系
select * from info where age > 30;
select * from info where id > 1;
select * from info where id = 1;
select * from info where id >= 1;
select * from info where id != 1;
select * from info where id between 2 and 4;
select * from info where exists (select * from depart where id=5);
select * from info where not exists (select * from depart where id=5);
select * from info where name like "%沛%";
select * from info where email like "_@live.com";
select
id,
name,
(select title from depart where depart.id=info.depart_id) as x1
from info;
select
id,
name,
case depart_id when 1 then "第1部门" end v1,
case depart_id when 1 then "第1部门" else "其他" end v2,
case depart_id when 1 then "第1部门" when 2 then "第2部门" else "其他" end v3,
case when age<18 then "少年" end v4,
case when age<18 then "少年" else "油腻男" end v5,
case when age<18 then "少年" when age<30 then "青年" else "油腻男" end v6
from info;
select * from info order by age desc;
select * from info order by age asc;
select * from info limit 5;
select * from info order by id desc limit 3;
select * from info where id > 4 order by id desc limit 3;
数据库表中:1000条数据
第一页:select * from info limit 10 offset 0;
第二页:select * from info limit 10 offset 10;
第三页:select * from info limit 10 offset 20;
第四页:select * from info limit 10 offset 30;
...
select age,max(id),min(id),count(id),sum(id),avg(id) from info group by age;
select age,count(1) from info group by age;
select depart_id,count(id) from info group by depart_id;
select depart_id,count(id) from info group by depart_id having count(id) > 2;
select count(id) from info;
select max(id) from info;
select age,name from info group by age;
select * from info where id in (select max(id) from info group by age);
select age,count(id) from info group by age having count(id) > 2;
select age,count(id) from info where id > 4 group by age having count(id) > 2;
主表 left outer join 从表 on 主表.x = 从表.id
select
*
from
info
left outer join depart on info.depart_id = depart.id;
select
info.id,info.name,info.email,depart.title
from
info
left outer join depart on info.depart_id = depart.id;
select * from info inner join depart on info.depart_id=depart.id;
select id,title from depart
union
select id,name from info;
select id,title from depart
union
select email,name from info;
select id from depart
union
select id from info;
select id from depart
union all
select id from info
-
外键约束
create table depart(
id int not null auto_increment primary key,
title varchar(16) not null
)default charset=utf8;
create table info(
id int not null auto_increment primary key,
name varchar(16) not null,
email varchar(32) not null,
age int,
depart_id int not null,
constraint fk_info_depart foreign key (depart_id) references depart(id)
)default charset=utf8;
alter table info add constraint fk_info_depart foreign key info(depart_id) references depart(id);
alter table info drop foreign key fk_info_depart;
-
常见索引
create table 表名(
id int not null auto_increment primary key,
name varchar(32) not null
);
create table 表名(
id int not null auto_increment,
name varchar(32) not null,
primary key(id)
);
create table 表名(
id int not null auto_increment,
name varchar(32) not null,
primary key(列1,列2)
);
alter table 表名 add primary key(列名);
alter table 表名 drop primary key;
create table 表名(
id int not null auto_increment primary key,
name varchar(32) not null,
email varchar(64) not null,
unique ix_name (name),
unique ix_email (email)
);
create table 表名(
id int not null auto_increment,
name varchar(32) not null,
unique (列1,列2)
);
create unique index 索引名 on 表名(列名);
drop unique index 索引名 on 表名;
create table 表名(
id int not null auto_increment primary key,
name varchar(32) not null,
email varchar(64) not null,
index ix_email (email),
index ix_name (name)
);
create table 表名(
id int not null auto_increment primary key,
name varchar(32) not null,
email varchar(64) not null,
index ix_email (name,email)
);
create index 索引名 on 表名(列名);
drop index 索引名 on 表名;
- innodb和myisam引擎的区别
myisam引擎,非聚簇索引(数据 和 索引结构 分开存储)
innodb引擎,聚簇索引(数据 和 主键索引结构存储在一起)
-
命中索引
select * from big where name = 123;
select * from big where email = 123;
select * from big where id = "123";
select * from big where name != "武沛齐";
select * from big where email != "wupeiqi@live.com";
特殊的主键:
select * from big where id != 123;
select * from big where id = 123 or password="xx";
select * from big where name = "wupeiqi" or password="xx";
select * from big where id = 10 or password="xx" and name="xx";
select * from big order by name asc;
select * from big order by name desc;
select * from big order by id desc;
select * from big where name like "%u-12-19999";
select * from big where name like "_u-12-19999";
select * from big where name like "wu-%-10";
select * from big where name like "wu-1111-%";
select * from big where name like "wuw-%";
select * from big where reverse(name) = "wupeiqi";
select * from big where name = reverse("wupeiqi");
name and password
name
password
name or password
-
执行计划和事务四大特性
explain + SQL语句;
-
基于Python代码操作事务的示例:
import pymysql
import threading
def task():
conn = pymysql.connect(host='127.0.0.1', port=3306,
user='root', passwd='root123', charset="utf8", db='userdb')
cursor = conn.cursor(pymysql.cursors.DictCursor)
conn.begin()
cursor.execute("select id,age from tran where id=2 for update")
result = cursor.fetchone()
current_age = result['age']
if current_age > 0:
cursor.execute("update tran set age=age-1 where id=2")
else:
print("已售罄")
conn.commit()
cursor.close()
conn.close()
def run():
for i in range(5):
t = threading.Thread(target=task)
t.start()
if __name__ == '__main__':
run()
-
锁
begin;
select * from L1 where name="武沛齐" for update;
commit;
begin;
select * from L1 where id=1 for update;
commit;
begin;
select * from L1 where name="武沛齐" lock in share mode;
commit;
begin;
select * from L1 where id=1 lock in share mode;
commit;
-
数据库连接池
import threading
import pymysql
from dbutils.pooled_db import PooledDB
MYSQL_DB_POOL = PooledDB(
creator=pymysql, # 使用链接数据库的模块
maxconnections=5, # 连接池允许的最大连接数,0和None表示不限制连接数
mincached=2, # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
maxcached=3, # 链接池中最多闲置的链接,0和None不限制
blocking=True, # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
setsession=[], # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
ping=0,
# ping MySQL服务端,检查是否服务可用。
# 如:0 = None = never, 1 = default = whenever it is requested,
# 2 = when a cursor is created, 4 = when a query is executed, 7 = always
host='127.0.0.1',
port=3306,
user='root',
password='root123',
database='userdb',
charset='utf8'
)
def task():
# 去连接池获取一个连接
conn = MYSQL_DB_POOL.connection()
cursor = conn.cursor(pymysql.cursors.DictCursor)
cursor.execute('select sleep(2)')
result = cursor.fetchall()
print(result)
cursor.close()
# 将连接交换给连接池
conn.close()
def run():
for i in range(10):
t = threading.Thread(target=task)
t.start()
if __name__ == '__main__':
run()
-
单例和方法
import pymysql
from dbutils.pooled_db import PooledDB
class DBHelper(object):
def __init__(self):
# TODO 此处配置,可以去配置文件中读取。
self.pool = PooledDB(
creator=pymysql, # 使用链接数据库的模块
maxconnections=5, # 连接池允许的最大连接数,0和None表示不限制连接数
mincached=2, # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
maxcached=3, # 链接池中最多闲置的链接,0和None不限制
blocking=True, # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
setsession=[], # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
ping=0,
# ping MySQL服务端,检查是否服务可用。# 如:0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always
host='127.0.0.1',
port=3306,
user='root',
password='root123',
database='userdb',
charset='utf8'
)
def get_conn_cursor(self):
conn = self.pool.connection()
cursor = conn.cursor(pymysql.cursors.DictCursor)
return conn, cursor
def close_conn_cursor(self, *args):
for item in args:
item.close()
def exec(self, sql, **kwargs):
conn, cursor = self.get_conn_cursor()
cursor.execute(sql, kwargs)
conn.commit()
self.close_conn_cursor(conn, cursor)
def fetch_one(self, sql, **kwargs):
conn, cursor = self.get_conn_cursor()
cursor.execute(sql, kwargs)
result = cursor.fetchone()
self.close_conn_cursor(conn, cursor)
return result
def fetch_all(self, sql, **kwargs):
conn, cursor = self.get_conn_cursor()
cursor.execute(sql, kwargs)
result = cursor.fetchall()
self.close_conn_cursor(conn, cursor)
return result
db = DBHelper()
from db import db
db.exec("insert into d1(name) values(%(name)s)", name="武沛齐666")
ret = db.fetch_one("select * from d1")
print(ret)
ret = db.fetch_one("select * from d1 where id=%(nid)s", nid=3)
print(ret)
ret = db.fetch_all("select * from d1")
print(ret)
ret = db.fetch_all("select * from d1 where id>%(nid)s", nid=2)
print(ret)
-
上下文管理
import threading
import pymysql
from dbutils.pooled_db import PooledDB
POOL = PooledDB(
creator=pymysql, # 使用链接数据库的模块
maxconnections=5, # 连接池允许的最大连接数,0和None表示不限制连接数
mincached=2, # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
maxcached=3, # 链接池中最多闲置的链接,0和None不限制
blocking=True, # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
setsession=[], # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
ping=0,
host='127.0.0.1',
port=3306,
user='root',
password='root123',
database='userdb',
charset='utf8'
)
class Connect(object):
def __init__(self):
self.conn = conn = POOL.connection()
self.cursor = conn.cursor(pymysql.cursors.DictCursor)
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.cursor.close()
self.conn.close()
def exec(self, sql, **kwargs):
self.cursor.execute(sql, kwargs)
self.conn.commit()
def fetch_one(self, sql, **kwargs):
self.cursor.execute(sql, kwargs)
result = self.cursor.fetchone()
return result
def fetch_all(self, sql, **kwargs):
self.cursor.execute(sql, kwargs)
result = self.cursor.fetchall()
return result
from db_context import Connect
with Connect() as obj:
# print(obj.conn)
# print(obj.cursor)
ret = obj.fetch_one("select * from d1")
print(ret)
ret = obj.fetch_one("select * from d1 where id=%(id)s", id=3)
print(ret)
-
python代码操作MySQL示例1
import pymysql
# 连接MySQL,自动执行 use userdb;
conn = pymysql.connect(host='127.0.0.1', port=3306, user='
root', passwd='root123', charset="utf8", db='userdb')
cursor = conn.cursor()
# 1.新增(需commit)
""""
cursor.execute("insert into tb1(name,password) values('武沛
齐','123123')")
conn.commit()
""""
# 2.删除(需commit)
""""
cursor.execute("delete from tb1 where id=1")
conn.commit()
""""
# 3.修改(需commit)
""""
cursor.execute("update tb1 set name='xx' where id=1")
conn.commit()
""""
# 4.查询
"""‘
cursor.execute("select * from tb where id>10")
data = cursor.fetchone() # cursor.fetchall()
print(data)
"""”
# 关闭连接
cursor.close()
conn.close()
-
python代码操作数据库示例2
import pymysql
# 连接MySQL
conn = pymysql.connect(host='127.0.0.1', port=3306, user='
root', passwd='root123', charset="utf8")
cursor = conn.cursor()
# 1. 创建数据库
""""
cursor.execute("create database db4 default charset utf8
collate utf8_general_ci")
conn.commit()
""""
# 2. 进入数据库、查看数据表
""""
cursor.execute("use db4")
cursor.execute("show tables")
result = cursor.fetchall()
print(result)
""""
# 3. 进入数据库创建表
cursor.execute("use db4")
sql = """
create table L4(
id int not null primary key auto_increment,
title varchar(128),
content text,
ctime datetime
)default charset=utf8;
"""
cursor.execute(sql)
conn.commit()
# 4. 查看数据库中的表
""""
cursor.execute("show tables")
result = cursor.fetchall()
print(result)
""""
# 5. 其他 drop table... 略过
# 关闭连接
cursor.close()
conn.close()
-
python代码操作数据库示例3
import pymysql
# 连接MySQL(socket)
conn = pymysql.connect(host='127.0.0.1', port=3306,
user='root', passwd='root123', charset="utf8")
cursor = conn.cursor()
# 1. 查看数据库
# 发送指令
cursor.execute("show databases")
# 获取指令的结果
result = cursor.fetchall()
print(result) # (('information_schema',), ('mysql',), ('
performance_schema',), ('sys',))
# 2. 创建数据库(新增、删除、修改)
# 发送指令
cursor.execute("create database db3 default charset
utf8 collate utf8_general_ci")
conn.commit()
# 3. 查看数据库
# 发送指令
cursor.execute("show databases")
# 获取指令的结果
result = cursor.fetchall()
print(result) # (('information_schema',), ('db3',), ('
mysql',), ('performance_schema',), ('sys',))
# 4. 删除数据库
# 发送指令
cursor.execute("drop database db3")
conn.commit()
# 5. 查看数据库
# 发送指令
cursor.execute("show databases")
# 获取指令的结果
result = cursor.fetchall()
print(result) # (('information_schema',), ('mysql',), ('
performance_schema',), ('sys',))
# 6. 进入数据库,查看表
# 发送指令
cursor.execute("use mysql")
cursor.execute("show tables")
result = cursor.fetchall()
print(result) # (('columns_priv',), ('db',), ('engine_
cost',), ('event',), ('func',), ('general_log',),....
# 关闭连接
cursor.close()
onn.close()
-
python代码操作事务
import pymysql
conn = pymysql.connect(host='127.0.0.1',
port=3306, user='root', passwd='root123',
charset="utf8", db='userdb')
cursor = conn.cursor()
# 开启事务
conn.begin()
try:
cursor.execute("update users set
amount=1 where id=1")
int('asdf')
cursor.execute("update tran set
amount=2 where id=2")
except Exception as e:
# 回滚
print("回滚")
conn.rollback()
else:
# 提交
print("提交")
conn.commit()
cursor.close()
conn.close()
-
创建用户并授权
create user '用户名'@'链接地址' identified by '密码';
create user 'jack'@'&' identified by 'root123';
drop user '用户名'@'链接地址';
drop user 'jack'@'%';
rename user '用户名'@'IP地址' to '新用户名'@'IP地址';
rename user 'jack'@'127.0.0.1' to 'JackQi'@'localhost';
set password for '用户名'@'IP地址' = password('新密码');
set password for 'JackQi'@'localhost' = password('pwd123');
grant 授权 on 数据库.表 to '用户名'@'IP地址';
grant all privileges on *.* to 'JackQi'@'localhost';
grant all privileges on day26db.* to 'JackQi'@'127.0.0.1';
grant all privileges on day26db.info to 'JackQi'@'localhost';
grant select on day26db.info to 'JackQi'@'localhost';
grant select,insert on day26db.* to 'JackQi'@'loxalhost';
show grant for '用户名'@'IP地址';
show grant for 'JackQi'@'%';
show grant for 'JackQi'@'localhost';
show grant for 'JackQi'@'127.0.0.1';
revoke 权限 on 数据库.表 from '用户名'@'IP地址';
revoke all privileges day26db.* 'JackQi'@'%';