目录python
用户认证mysql
只是经过文件操做,改变数据是很是繁琐的linux
解决对于多台机器或多个进程操做同一份数据咱们须要本身解决并发和安全问题比较麻烦ios
本身处理数据备份,容错措施正则表达式
c/s架构的操做数据文件的一个管理软件redis
数据操做算法
专有名词sql
常见的数据库mongodb
关系型数据库数据库
非关系型数据库(key:value结构)eg:快递单号(redis、mongodb、memcache)
在 WEB 应用方面,MySQL是最好的 RDBMS(关系数据库管理系统) 应用软件。
# 客户端 [mysql] # 设置mysql客户端默认字符集 default-character-set=utf8 # server端 [mysqld] #设置3306端口 port = 3306 # 设置mysql的安装目录 basedir=C:\Program Files\mysql-5.6.39-winx64 # 设置mysql数据库的数据的存放目录 datadir=C:\Program Files\mysql-5.6.39-winx64\data # 容许最大链接数 max_connections=200 # 服务端使用的字符集默认为8比特编码的latin1字符集 character-set-server=utf8mb4 # 建立新表时将使用的默认存储引擎 default-storage-engine=INNODB
# windows mysqld install net start mysql # server net stop mysql mysql -u'用户名' -p'密码' # 客户端,能够是python代码也能够是一个程序 # mysql.exe是一个客户端
# mac sudo mysql.server status sudo mysql.server start/stop/restart
sql语句(structure query language)
# 查看当前用户 select user(); # 设置密码,password 表示密文存储 set password for root@localhost = password('123'); # 建立用户 create user '用户名'@'网段.%' identified by '密码'; # 查看用户状态,用户信息都存储在mysql中的user表中 select host,user from mysql.user; # 查看当前库 show databases; # 建立文件夹henry create database henry; # 查看指定用户权限 show grants for '用户名'(@'网段.%'); # 受权 * 表示全部 grant all(select/insert) on henry.* to '用户名'@'ip网段.%'; # 设置当即生效 flush privileges # 建立帐号并受权,必须有密码 grant all on herny.* to 'henry'@'%' identified by '123'; #select, insert, update, delete, create, drop, index, alter, grant, references, reload, shutdown, process, file等14个权限 # 取消用户权限 revoke all on test.* from 'henry'@'%'; # 删除用户 delete from mysql.user where host='192.168.12.%' and user='test'; drop user 'test'@'192.168.12 # 修改指定用户密码 update mysql.user set password=password('新密码') where User='test' and Host='%';
# 建立库 create database demo; # 查看库 show databases; # 删除库,demo drop database demo # 查看当前使用的库 select database(); # 切换库,到demo库下 use demo;
# 建立表,char()默认一个字符 create table student(id int, name char(10)); # 查看当前文件夹中的表 show tables; # 删除表 drop table student; # 查看表结构 desc student; # 删除多个表 drop tables s2,s3,s4;
# 数据插入 insert into student values(1, 'henry'); # 数据查看 select * from student; # 修改数据,必须设置条件,肯定为一条数据data update 表 set 字段名=值 where id=2; # 删除数据 delete from 表 where id=1;
其余存储引擎
# 查看与存储引擎相关配置 show variables like '%engine%'; show variables like "default_storage_engine"; # 查看当前数据库支持的存储引擎 show engines \g show engines; # 修改已经存在表的存储引擎 alter table 表名 engine = innodb; # 查看与编码相关的配置 show variables like '%chara%'; # 查看 show variables like '%关键字%';
# 建立表 create table t1(id int, name char(10)) engine=innodb; # 查看表的结构,包括存储引擎和编码 \G 格式化输出,带 \G 不能使用分号 show create table t1 \G # 只查看表字段基础信息 describle t1; t1.frm frame 表结构 t1.ibd innoDB 存储引擎
# 指定engine为myisam create table t2(id int, name char(10)) engine=MyISAM; t2.frm 表结构 t2.MYD 数据 t2.MYI 索引
# 指定engine为memory create table t2(id int, name char(10)) engine=memory; t2. 数据
# 语法: create table 表名( 字段名1 类型[(宽度) 约束条件], 字段名2 类型[(宽度) 约束条件], 字段名3 类型[(宽度) 约束条件]); # 注意: 1. 在同一张表中,字段名是不能相同 2. 宽度和约束条件可选 3. 字段名和类型是必须的
# 建立无符号int型表 create table t3(id1 int, id2 int unsigned);
# 一共有5位,小数2位 float(5, 2)/ double(5, 2) # 建立表 create tables t4(f1 float(5,2), double(5,2)); # 不指定长度,单精度和双精度 create tables t4(f1 float, double); # decimal精度,默认存储(10,0)整数 create table t5(d1 decimal, d2 decimal(25, 20)); # decimal内部存储是按照字符串存的
# 建立表 create table t6(d1 date, y year, ts timestamp); insert into t6(now(), now(), now()); # 指定传y,datetime默认为更新时间 insert into t6(y) values(2019); # 指定datetime更新方式 create table t6(d1 date, y year, dt datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP); # 可使用字符串,纯数字 # 5.7版本,插入参数不全,会报错,5.6版不会
create table t7(name1 char(5), name2 varchar(5)); # 分别存储 'echo ' 和 'echo4' insert into t7 values('echo', 'echo') select concat(name1, '---') from t7; select concat(name2, '---') from t7;
create table t8(name char(12), gender ENUM('male', 'female'), hobby set('play', 'drink', 'eat'));
create table t1(id int not null, name char(12) not null, age int); insert into t1(id, name) values(1, 'henry');
create table t2(id int not null, name char(12) not null, gender enum('male', 'female') not null default 'male' ); insert into t2(id, name) values(1, 'henry');
create table t3(id int unique, username char(12) not null unique, pwd char(18) );
create table t4(id int not null unique, ip char(15), server char(10), port int, unique(ip, port)) # 联合惟一,不能同时重复
create table t5(id int unique auto_increment, username char(10), pwd char(18)); insert into t5(username, pwd) values('henry', '123'); # 自增大小只增不减 # 对于自增的字段,在用delete删除后,再插入值,该字段仍按照删除前的位置继续增加
# 也能够建立表时指定auto_increment的初始值,注意初始值的设置为表选项,应该放到括号外 create table student(id int primary key auto_increment, name varchar(20), gender enum('male','female') default 'male' )auto_increment=3;
#设置步长 # sqlserver:自增步长 # 基于表级别,指定步为2,从0开始计数 create table t1(id int unique auto_increment, age int )engine=innodb,auto_increment=2 default charset=utf8; # mysql自增的步长: show session variables like 'auto_inc%'; # 基于会话级别 set session auto_increment_increment=2;# 修改会话级别的步长 # 基于全局级别的 set global auto_increment_increment=2; # 修改全局级别的步长(全部会话都生效) # 查看设置,从新登录5.7版本直接失效 show variables like 'auto_incre%';
create table t6(id int not null unique, name char(10) not null unique); # 第一个指定为not null nuique 字段被定义为主键
create table t7(id int primary key, name char(10) not null unique);
create table t8(id int, ip char(15), server char(10), port int, primary(ip, port)) # 联合主键
create table staff(id int primary key auto_increment, age int, gender enum('male', 'female'), salary float(10,2), hire_date date, post_id int, foreign key(post_id) references dept(pid); create table dept(pid int primary key, name char(10) not null nuique);
create table staff(id int primary key auto_increment, age int, gender enum('male', 'female'), salary float(10,2), hire_date date, post_id int, foreign key(post_id) references dept(pid) on update cascade on delete set null); create table dept(pid int primary key, name char(10) not null nuique);
# 修改表名 alter table 表名 rename 新表名;
# 添加字段 alter table 表名 add 添加字段名 数据类型(宽度) 约束 # 删除字段 alter table 表名 drop 删除字段名;
# 修改已经存在字段的类型、宽度 约束,不能修改字段名字 alter table 表名 modify 字段名 类型() 约束 # 修改已经存在字段的类型、宽度 约束、字段名字 alter table 表名 change 字段名 新字段名 类型() 约束
# 把字段放在第一列 alter table 表名 modify age 类型+约束 first; # 把字段放在id以后 alter table 表名 modify age int not null after id; # 也能够与 add、change 连用
#去掉null约束 alter table t modify name char(10) null; # 添加null约束 alter table t modify name char(10) not null;
# 去掉unique约束,特殊 alter table 表名 drop index 字段名; # 添加unique约束 alter table 表名 modify 字段名 int unique;
alter database 库名 CHARACTER SET utf8;
# 先删除主键,删除一个自增主键会报错 # 须要先去掉主键的自增约束,而后再删除主键约束 alter table 表名 drop primary key; # 增长主键 alter table 表名 add primary key(id);
# 添加外键 alter table 表名 add constraint 外键名 foreign key(字段) references press(字段); # 删除外键 alter table 表名 drop foreign key 外键名;
drop table 表名;
两张表的数据关系:多对一、一对一、多对多(书、做者)
create table press(id int primary key auto_increment, name varchar(20)); create table book(id int primary key auto_increment, name varchar(20), press_id int not null, foreign key(press_id) references press(id) on delete cascade on update cascade); insert into press(name) values('henry publisher'), ('echo publisher'),('dean publisher'); insert into book(name,press_id) values('henry',1),('echo',2), ('dean',2),('brad',3),('dianel',2),('oleg',3);
# 两张表:学生表和客户表 create table customer(id int primary key auto_increment, name varchar(20) not null, qq varchar(10) not null, phone char(16) not null); create table student(id int primary key auto_increment, class_name varchar(20) not null, customer_id int unique, #该字段必定要是惟一的 foreign key(customer_id) references customer(id) on delete cascade on update cascade); # 增长客户 insert into customer(name,qq,phone) values('henry', '12345', 12312312311), ('echo','123123123',12312312311),('dean', '283818181', 12312312311), ('brad','283818181',12312312311), ('oleg', '888818181', 12312312311), ('dianel','112312312',12312312311); # 增长学生 insert into student(class_name,customer_id) values('1班',3),('2班',4),('3班',5);
create table author(id int primary key auto_increment, name varchar(20)); create table book(id int primary key auto_increment, name varchar(20)); # 这张表就存放做者表与书表的关系,即查询两者的关系查这表就能够了 create table author_book(id int not null unique auto_increment, author_id int not null, book_id int not null, constraint fk_author foreign key(author_id) references author(id) on delete cascade on update cascade, constraint fk_book foreign key(book_id) references book(id) on delete cascade on update cascade, primary key(author_id,book_id)); # 插入做者和书籍信息 insert into author(name) values('henry'),('echo'),('dean'),('diane'); insert into book(name) values('1'),('2'),('3'),('4'),('5'),('6') insert into author_book(author_id,book_id) values(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(2,1),(2,6),(3,4),(3,5),(3,6),(4,1);
# 在父表上update/delete记录时,同步update/delete掉子表的匹配记录 cascade方式 # 在父表上update/delete记录时,将子表上匹配记录的列设为null要注意子表的外键列不能为not null set null方式 # 若是子表中有匹配的记录,则不容许对父表对应候选键进行update/delete操做 No action方式 # 同no action, 都是当即检查外键约束 Restrict方式 # 父表有变动时,子表将外键列设置成一个默认的值 但Innodb不能识别 Set default方式
# 写入一行数据 insert into t1 values(1, 'henry', 19); insert into t1 value(1, 'henry', 19); # 写入多行数据 insert into t1 values(1, 'henry', 19), (2, 'echo', 18); # 指定字段写入 insert into t1(name, age) value('henry', 19);
# 删除条件匹配到的数据 delete form 表 where 条件;
# 修改表中数据, set 后的字段能够为一个或多个 update 表 set 字段=值 where 条件; # 注意null只能使用 is 匹配 where name is null;
SELECT DISTINCT 字段1,字段2... FROM 表名 WHERE 条件 GROUP BY field HAVING 筛选 ORDER BY field LIMIT 限制条数
# 查看表中全部数据 select * from 表 # 查看指定字段 select 字段1,字段2... from 表 # 查看指定字段,自动去重 select distinct 字段1,字段2... from 表 # 数值型四则运算,并名别名显示 select name,salary*12 (as) annual_salary form 表 # 数值型四则运算,并名别名, 拼接显示 select concat ('姓名:',name,'薪资:',salary*12) (as) annual_salary form 表 # 使用':'进行拼接 select concat_ws (':', name,salary*12 (as) annual_salary) form 表
# 结合CASE语句: SELECT(CASE WHEN emp_name = 'henry' THEN emp_name WHEN emp_name = 'echo' THEN CONCAT(emp_name,'_prefect') ELSE concat(emp_name, '_nice') END ) as new_name FROM employee;
select * from t1 where salary>1000; # 和数值类型无关 select * from t1 where salary=20000 or slary=30000; # 逻辑运算 select * from t1 where gender='male' and age=18; # 多选一,可使用 in select 字段名,... from t1 where salary in (20000, 30000, 19000); # not in select 字段名,... from t1 where salary not in (20000, 30000, 19000); # is /is not select 字段名 from t1 where 字段 is null;
# between ... and ... select name,salary from t1 where salary between 10000 and 20000
# like , % 通配符,匹配任意长度,任意内容 select * from t1 where name like '程%'; # like , _ 通配符,匹配一个任意字符 select * from t1 where name like '程_'; # like , 以 n 结尾 select * from t1 where name like '%n';
select * from t1 where name regexp 正则表达式; SELECT * FROM employee WHERE emp_name REGEXP 'on$';
# 显示一个组的第一个,必须有group的字段 select post from employee group by post; # distinct 基于group by完成
select count(*/ 主键) from employee; # 只算id不为空的字段个数 select count(id) from employee;
select avg(salary) from employee; select sum(salary) from employee;
# 分别对各个组,统计人数 select post,count(*) from employee group by post; # 对某一组进行统计人数 select post,count(*) from employee where post='teacher'; # 各部门的平均薪资 select post,avg(salary) from employee group by post;
# 最晚入职 select max(hire_date) from employee group by post; # 最先入职 select min(hire_date) from employee group by post;
# 查询岗位名以及岗位包含的全部员工名字 select post, group_concat(emp_name) from employee group by post; # 查询岗位名以及各岗位内包含的员工个数 select post, count(id) from employee group by post; # 查询公司内男员工和女员工的个数 select gender, count(id) from employee group by gender;
# 部门人数大于3 select post from employee group by post having count(*) > 3; # 平均薪资大于10000 select post from employee group by post having avg(salary) > 10000; # 过滤整张表,必须有 age 字段,不然报错 select emp_name, age from employee having avg(age)>18;
# 查询各岗位内包含的员工个数小于2的岗位名、岗位内包含员工名字、个数 select post, group_concat(emp_name), count(*) from employee group by post having count(id) < 2; # 查询各岗位平均薪资大于10000的岗位名、平均工资 select post,avg(salary) from employee group by post having avg(salary) > 10000; # 查询各岗位平均薪资大于10000且小于20000的岗位名、平均工资 select post,avg(salary) from employee group by post having avg(salary) > 10000 and avg(salary) < 20000; # 使用 between ... and... select post,avg(salary) from employee group by post having avg(salary) between 10000 and 20000;
# desc 表示降序排 # asc 表示生序排列,默认值 select * from employee order by salary desc; # 多个个字段排序,先根据第一个字段排列后,再根据第二个字段排列 select * from employee order by age asc, salary desc;
# 查询各岗位平均薪资大于10000的岗位名、平均工资,结果按平均薪资升序排列 select post, avg(salary) from employee group by post having avg(salary) > 10000 order by avg(salary) asc; # 查询各岗位平均薪资大于10000的岗位名、平均工资,结果按平均薪资降序排列 select post, avg(salary) from employee group by post having avg(salary) > 10000 order by avg(salary) desc;
# 分页显示 # 默认从0开始,显示前5个 select * from employee limit 5; # 显示下5个, 5+1 位置开始取 # limit m,n 表示从m+1开始取到5个 limit n offset m等价于limit m,n select * from employee limit 5,5; # 显示下5个 select * from employee limit 10,5;
#建表 create table department(id int, name varchar(20) ); create table staff(id int primary key auto_increment, name varchar(20), gender enum('male','female') not null default 'male', age int, dep_id int); #插入数据 insert into department values(200,'技术'),(201,'人力资源'),(202,'销售'),(203,'运营'); insert into staff(name,gender,age,dep_id) values ('henry','male',18,200), ('echo','female',48,201), ('dean','male',38,201), ('diane','female',28,202), ('oleg','male',18,200), ('iris','female',18,204); #查看表结构和数据 mysql> desc department; mysql> desc employee; mysql> select * from department; mysql> select * from employee;
select 字段列表 FROM 表1 INNER|LEFT|RIGHT JOIN 表2 ON 表1.字段 = 表2.字段;
# 笛卡尔积 select 字段 from t1,t2 where 字段1=字段2; # 连表查询,staff,department 两个表,和 inner join 效果一致 select * from staff, department as dept where dep_id=dept.id;
select 字段 from t1 inner join t2 on t1(字段1) = t2(字段2);
# t1链接t2,显示全量的左表,只显示匹配到的t2 select 字段 from t1 left join t2 on t1(字段1) = t2(字段2); select 字段 from t1 right join t2 on t1(字段1) = t2(字段2); # 全链接 select 字段 from t1 left join t2 on t1(字段1) = t2(字段2) union select 字段 from t1 right join t2 on t1(字段1) = t2(字段2);
# 经过左外、和右外链接实现全外链接示例 select * from staff left join department as dept on dep_id = dept.id union select * from staff right join department as dept on dep_id = dept.id;
# 之内链接的方式查询staff和department表,而且staff表中的age字段值必须大于25,即找出年龄大于25岁的员工以及员工所在的部门 # 此时括号能够省略 select staff.name, dept.name from staff left join department as dept on dep_id = dept.id where age > 25; # 之内链接的方式查询staff和department表,而且以age字段的升序方式显示 select * from staff inner join department as dept on dep_id = dept.id order by age;
1:子查询是将一个查询语句嵌套在另外一个查询语句中。 2:内层查询语句的查询结果,能够为外层查询语句提供查询条件。 3:子查询中能够包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等关键字 4:还能够包含比较运算符:= 、 !=、> 、<等
# 子表中匹配到惟一值 select name from emp where dep_id = (select id from department where name='技术'); # 子表中匹配到多个值 select name from emp where dep_id in (select id from department where name in ('技术', '销售'));
# 查询平均年龄在25岁以上的部门名 select name from department where id in (select dep_id from staff group by dep_id having avg(age) > 25); # 查看技术部员工姓名 select name from staff where dep_id in (select id from department where name = '技术' ) # 查看不足1人的部门名(子查询获得的是有人的部门id) select name from department where id not in (select dep_id from staff group by dep_id);
# 查询大于全部人平均年龄的员工名、年龄 select name, age from staff where age > (select avg(age) from staff); # 查询大于部门内平均年龄的员工名、年龄 select name, age from staff t1 inner join (select dep_id, avg(age) avg_age from staff group by dep_id) t2 on t1.dep_id = t2.dep_id where t1.age > t2.avg_age;
# exists后为真 select * from staff where exists (select id from department where id=200); # 输出staff中全部数据 # exists后为假 select * from staff where exists (select id from department where id=200); # 输出为空
# 连表查询 select t1.emp_name, t1.hire_date, t1.post from employee as t1 inner join (select depart_id, max(hire_date) as max_date from employee group by depart_id) as t2 on t1.depart_id = t2.depart_id where t1.hire_date = t2.max_date;
# 子查询 select t3.emp_name,t3.post,t3.hire_date from employee as t3 where id in (select (select id from employee as t2 where t2.depart_id=t1.depart_id order by hire_date desc limit 1) from employee as t1 group by depart_id);
# 1.准备表 create table s_test(id int, name varchar(20), gender char(6), email varchar(50)); # 2.建立存储过程,实现批量插入记录 delimiter $$ #声明存储过程的结束符号为$$ create procedure auto_insert() BEGIN declare i int default 1; while(i<3000000)do insert into s_test values(i,'henry','male',concat('henry',i,'@qq.com')); set i=i+1; end while; END$$ #$$结束 delimiter ; #从新声明分号为结束符号 # 3.查看存储过程 show create procedure auto_insert\G # 4.调用存储过程 call auto_insert(); # 在写入的时候不更新索引表,只针对myisam生效 ALTER TABLE table_name DELAY_KEY_WRITE= 1;
平衡树 balance tree b树
写入数据:速度较慢,须要整理数据
b树在范围查询b树不占优点(root、leaf、branch)演变成双向链式结构
在b树基础上的改良:b+树(innodb 默认结构)(2)
索引字段要尽可能的小:经过上面的分析,咱们知道IO次数取决于b+数的高度h,假设当前数据表的数据为N,每一个磁盘块的数据项的数量是m,则有h=㏒(m+1)N,当数据量N必定的状况下,m越大,h越小;而m = 磁盘块的大小 / 数据项的大小,磁盘块的大小也就是一个数据页的大小,是固定的,若是数据项占的空间越小,数据项的数量越多,树的高度越低。这就是为何每一个数据项,即索引字段要尽可能的小,好比int占4字节,要比bigint8字节少一半。这也是为何b+树要求把真实的数据放到叶子节点而不是内层节点,一旦放到内层节点,磁盘块的数据项会大幅度降低,致使树增高。当数据项等于1时将会退化成线性表。
树的高度会影响索引的效率
索引特色(2)
mysql中全部的b+树索引的高度都基本上控制在3层
数据库中的B+树索引能够分为汇集索引(clustered index)和辅助索引(secondary index)
汇集索引:数据直接存储在树结构的叶子节点
# InnoDB存储引擎表是索引组织表,即表中数据按照主键顺序存放。 1. 而汇集索引(clustered index)就是按照每张表的主键构造一棵B+树,同时叶子结点存放的即为整张表的行记录数据,也将汇集索引的叶子结点称为数据页。 2. 汇集索引的这个特性决定了索引组织表中数据也是索引的一部分。同B+树数据结构同样,每一个数据页都经过一个双向链表来进行连接。 # 若是未定义主键,MySQL取第一个惟一索引(unique)并且只含非空列(NOT NULL)做为主键,InnoDB使用它做为聚簇索引。 1. 若是没有这样的列,InnoDB就本身产生一个这样的ID值,它有六个字节,并且是隐藏的,使其做为汇集索引。 # 因为实际的数据页只能按照一棵B+树进行排序,所以每张表只能拥有一个汇集索引。 1. 在多数状况下,查询优化器倾向于采用汇集索引。由于汇集索引可以在B+树索引的叶子节点上直接找到数据。 2. 此外因为定义了数据的逻辑顺序,汇集索引可以特别快地访问针对范围值得查询。
alter table t1 add primary key(id); alter table t1 modify id not null unique;
辅助索引:数据不直接存储在树中
汇集和辅助索引对比
innodb中汇集索引和辅助索引并存(都是b+树)
myisam中只有辅助索引
须要注意的是:innodb表的索引会存放于s1.ibd文件中,而myisam表的索引则会有单独的索引文件table1.MYI
MySAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。而在innodb中,表数据文件自己就是按照B+Tree(BTree即Balance Tree)组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,所以innodb表数据文件自己就是主索引。由于inndob的数据文件要按照主键汇集,因此innodb要求表必需要有主键(Myisam能够没有),若是没有显式定义,则mysql系统会自动选择一个能够惟一标识数据记录的列做为主键,若是不存在这种列,则mysql会自动为innodb表生成一个隐含字段做为主键,这字段的长度为6个字节,类型为长整型.
# 方法一:建立表时 create table 表(字段..., index|unique|fulltext|spatial|key 索引名称 on 表(字段1,字段2...)); # 方法二:CREATE在已存在的表上建立索引,经常使用方法 create index(索引类型,一般使用index) 索引名称 on 表(字段1,字段2...); # 方法三:ALTER TABLE在已存在的表上建立索引 alter table 表名 add index 索引名称 on 表(字段1,字段2...); # 删除索引 drop index 索引名 on 表名字; # 查看表s1的索引 show index from s1;
select * from 表 where id between 1000000 and 1000005; # 使用like select * from 表 where emial like '%abc';
# 而对于区分度低的字段,没法找到大小关系,由于值都是相等的,毫无疑问,还想要用b+树存放这些等值的数据,只能增长树的高度,字段的区分度越低,则树的高度越高。
select * from s1 where id*10 = 1000000;
小结:索引不生效状况
create index ind_mix on s1(id, email); # 对于联合索引(a,b),下述语句能够直接使用该索引,无需二次排序 select ... from table where a=xxx order by b; # 而后对于联合索引(a,b,c)来首,下列语句一样能够直接经过索引获得结果 select ... from table where a=xxx order by b; select ... from table where a=xxx and b=xxx order by c; # 可是对于联合索引(a,b,c),下列语句不能经过索引直接获得结果,还须要本身执行一次filesort操做,由于索引(a,c)并未排序 select ... from table where a=xxx order by c;
# 执行计划,并不会真正执行sql语句,给出一个执行计划 explain select id from s1 where id = 1000000;
# 语法: mysqldump -h服务器 -u用户名 -p密码 数据库名 > 备份文件.sql # 示例: # 单库备份 mysqldump -uroot -p123 库名 > 备份文件名(路径) mysqldump -uroot -p123 db1 table1 table2 > db1-table1-table2.sql # 多库备份,导入时不须要指定库名,会覆盖库名相同的库 mysqldump -uroot -p123 --databases db1 db2 mysql db3 > db1_db2_mysql_db3.sql # 备份全部库 mysqldump -uroot -p123 --all-databases > all.sql
# 方法一:不使用 --databases 参数 mysql -u用户名 -p密码 库名 < 备份文件名 # 方法二: mysql> use db1; # 关闭二进制日志,只对当前session生效 mysql> SET SQL_LOG_BIN=0; mysql> source /root/db1.sql
mysql -uroot -p mysql.exe # mysql的一个客户端
import pymysql con = pymysql.connect(host='127.0.0.1', user='root', password='123', database='test') # 数据库操做符,游标,dict取值,默认元组 cur = con.cursor(pymysql.cursors.DictCursor) # 操做 cur.execute('sql语句') # 获取返回值,cur相似操做文件的游标指针 ret = cur.fetchone()/ fetchmany(n)/ fetchall() con.commit() con.close()
# 开启事务 begin; 或者 start transction; # 查询id值,for update添加行锁; select * from emp where id = 1 for update; # 完成更新 update emp set salary=10000 where id = 1; # 提交事务 commit;
-- 表示注释掉以后的sql语句 select * from userinfo where name = 'alex' ;-- and password = '792164987034'; select * from userinfo where name = 219879 or 1=1 ;-- and password = 792164987034; select * from userinfo where name = '219879' or 1=1 ;-- and password = '792164987034';
sql = 'select * from 表' # 参数为可迭代对象,使用execut拼接 cur.execute(sql, (username, password)) cur.close() con.close()
import pymysql # 打开数据库链接 db = pymysql.connect("localhost","testuser","test123","TESTDB" ) # 使用cursor()方法获取操做游标 cursor = db.cursor() # SQL 插入语句 sql = """INSERT INTO EMPLOYEE(FIRST_NAME, LAST_NAME, AGE, SEX, INCOME) VALUES ('Mac', 'Mohan', 20, 'M', 2000)""" try: cursor.execute(sql) # 执行sql语句 db.commit() # 提交到数据库执行 except: db.rollback() # 若是发生错误则回滚 # 关闭数据库链接 db.close()
import pymysql # 打开数据库链接 db = pymysql.connect("localhost", "root", "root", "day40") # 使用cursor()方法获取操做游标 cur = db.cursor() # SQL 查询语句 sql = "SELECT * FROM employee \ WHERE salary > %s" % (1000) try: ret = cur.execute(sql) # 执行SQL语句 print(ret) # ret为数据行数 results = cur.fetchall() # 获取全部记录列表 for row in results: id = row[0] name = row[1] gender = row[2] age = row[3] hire_date = row[4] print("id=%s,name=%s,gender=%s,age=%s,hire_date=%s"%(id, name, gender, age, hire_date)) except: print("Error: unable to fetch data") # 关闭数据库链接 db.close()