mysql的进阶
老师的博客:http://www.cnblogs.com/wupeiqi/articles/5713323.html
总结
导出与导入
导出:mysqldump -u root -p 数据库 > 新建名称.sql
导入:一般先创建数据库 create database 数据库:
myslq -u root -p 数据库 < 被导入的文件.sql
注意,此时是在命令窗口执行的 不用加; 视图review
创建:create view 名 as sql语句;
此时只是一个虚拟的表,只是一段语句,如果里面的表变化的,查询出来的值也会改变的
修改:alter view 名 as sql语句;
删除:drop view 名;
对于视图的操作只能是查看作用:select * from 名;
触发器trigger:
创建:
delimiter \\
CREATE TRIGGER 触发器名 BEFORE INSERT ON 表名1 FOR EACH ROW
BEGIN
INSERT INTO 操作的表2 ( 列名,列名 )
VALUES
( NEW.名,'值'); END \\
delimiter;
#delimiter 是修改终止符
#NES.名 表示你对表1输入某个信息。与before相对是after
#new相对的是old,表示被删除的值
#两个insert可以根据具体的操作变为delect ,update
#详细代码见http://www.cnblogs.com/wupeiqi/articles/5713323.html
函数function:
函数有自定和内置的,官方的网址:https://dev.mysql.com/doc/refman/5.7/en/functions.html
中文网址:http://doc.mysql.cn/mysql5/refman-5.1-zh.html-chapter/functions.html#encryption-functions
创建函数:
delimiter \\
CREATE FUNCTION f2 ( num2 INT, num1 INT ) RETURNS INT BEGIN
DECLARE
a DEFAULT INT 1; SET a = num1 * num2;
RETURN ( a ) ;
END \\
delimiter;
里面的分隔符使用; 开始是returns 后面是return
调用函数:
select f2(9,5); #45
这个创建时因为mysql的master和slave的关系,被视为不安全的函数,因此需要修改配置文件。
最后我执行完函数又改了回来。
函数是不能写select * from 这样的语句的,储存过称可以
储存过程proceduce
创建:
简单:
delimiter //
CREATE PROCEDURE p1 ( )
BEGIN
SELECT * FROM class;
INSERT INTO class ( caption ) VALUES ( '高三五班' );
END //
调用,在mysql中 call p1();
在pymysql中 cursor.callproc('p1')
传参:in out inout
in:
delimiter //
CREATE PROCEDURE p2 (in cha char(10) )
BEGIN
SELECT * FROM class;
INSERT INTO class ( caption )VALUES( cha );
END //
delimiter;
inout:
delimiter //
CREATE PROCEDURE p3
(in cha char(10),
inout num int )
BEGIN
set num=233;
SELECT * FROM class;
INSERT INTO class ( caption )VALUES( cha );
END //
delimiter;
调用函数:
set @b=1;
call p3('牛头',@b);
select @b;
#@b表示一个全局变量,在哪都可用,没有return,但是inout的值可以拿到,你可发现@b的值已经变了。 删除:drop procedure 名;
事物(proceduce)
处理失败与成功处理
下面是小写,方便看。
delimiter //
create procedure p5 (inout check_num tinyint)
begin
declare exit handler for SQLEXCEPTION
begin
-- deal with error
set check_num=1;
rollback;
end; start transaction ;
select * from class;
insert into class(caption)values('高三十九班'),('拒水小学一年级九班');
commit;
select * from class;
set check_num=2;
-- success deal with process
end
//
delimiter ;
正确的格式:
delimiter //
CREATE PROCEDURE p5 ( INOUT check_num TINYINT ) -- 只有一个参数不写;多个写
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
-- deal with error
SET check_num = 1;
ROLLBACK;
END;
START TRANSACTION;
SELECT * FROM class;
INSERT INTO class ( caption ) VALUES ( '高三十九班'), ('拒水小学一年级九班' );
COMMIT;
SELECT * FROM class;
SET check_num = 2;
-- success deal with process END //
delimiter;
游标
里面可以写类似于for循环,请看代码;
delimiter //
create procedure p9()
begin -- 声明变量 不写;
declare a_id int;
declare a_value int ;
declare num int ;
declare done int default false;
declare my_cursor cursor for select id,value1 from a;-- 建立游标
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
-- 开始循环
open my_cursor;
lhy:loop
fetch my_cursor into a_id,a_value;
if done=True then
leave lhy;-- 离开循环
end if ;
set num = a_id + a_value;
insert into B(num) values(num);
end loop lhy; -- 结束循环
close my_cursor;
commit;
end //
delimiter;
call p9();
这是美化之后的:
delimiter //
CREATE PROCEDURE p9 ( ) BEGIN-- 声明变量
DECLARE a_id INT;
DECLARE a_value INT;
DECLARE num INT;
DECLARE done INT DEFAULT FALSE;
DECLARE my_cursor CURSOR FOR SELECT id,value1 FROMa;-- 建立游标
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
-- 开始循环
OPEN my_cursor;
lhy:LOOP
FETCH my_cursor INTO a_id,a_value;
IF done = TRUE THEN -- 这里没有;否者会报错
LEAVE lhy;-- 离开循环
END IF;
SET num = a_id + a_value;
INSERT INTO B ( num )VALUES( num );
END LOOP lhy;-- 结束循环
CLOSE my_cursor;
COMMIT; -- 记得提交不然就回滚了,没有输入值
END //
delimiter;
动态执行sql(防止sql注入):
先定义一个:
delimiter \\
create procedure p4 (
in nid int -- 声明变量
)
begin
set @nid=nid; -- 设置 @赋值
prepare prod from 'select * from student where sid > ?'; -- 预编译?是站位符
execute prod using @nid; -- 将?赋值,将prof 变为正常语言
deallocate prepare prod; -- 执行Prof
end\\
delimiter ;
call p4(0); -- 调用
然后我发现还是能注入,只是取不到第一个值
例如 call p4(100 or 1=1)取到除了第一个,其余取去到了
美化的代码:
delimiter \\
CREATE PROCEDURE p4 ( IN nid INT)
BEGIN
SET @nid = nid;
PREPARE prod FROM 'select * from student where sid > ?';
EXECUTE prod USING @nid;
DEALLOCATE PREPARE prod;
END \\
delimiter;
索引
对性能要求不高的用函数之类的,因为如果用了函数就不会走索引了。
普通索引:加速查找
创建列表时:index ix_name (name)
index 名(列名,列名)
创建:create index index_name on table_name(column_name)
create index 名 on 表名(列名,列名)
删除:drop index_name on table_name;
drop 索引名 on 表名
查看:show index from table_name
注意:对于创建索引时如果是BLOB 和 TEXT 类型,必须指定length。
create index ix_extra on in1(extra(32));
唯一索引:加速查询 和 唯一约束(可含null)
创建:1.create table in1(
nid int not null auto_increment primary key,
name varchar(32) not null,
email varchar(64) not null,
extra text,
unique ix_name (name)
)
2.create unique index 索引名 on 表名(列名,列名)
一队表示这一对的组合不能组合
删除:drop unique index 索引名 on 表名
主键索引:加速查询 和 唯一约束(不可含null)
创建:create table table_name(
nid int not null auto_increment primary key,
name varchar(32) not null,
email varchar(64) not null,
extra text,
index ix_name (name)
)
OR
create table table_name(
nid int not null auto_increment,
name varchar(32) not null,
email varchar(64) not null,
extra text,
primary key(ni1),
index ix_name (name)
)
另外一种:alter table 表名 add primary key(列名);
删除:alter table 表名 drop primary key;
alter table 表名 modify 列名 int, drop primary key;
组合索引:将n个列组合成一个索引
创建:create table in3(
nid int not null auto_increment primary key,
name varchar(32) not null,
email varchar(64) not null,
extra text
) create index ix_name_email on in3(name,email);
当然也可以在创建表示直接创建组合索引,上面三种都可以;
最左前缀匹配:name and email -- 使用索引
name -- 使用索引
email -- 不使用索引
注意:对于同时搜索n个条件时,组合索引的性能好于多个单一索引合并。
应该避免:- like '%xx'
select * from tb1 where name like '%cn';
- 使用函数
select * from tb1 where reverse(name) = 'wupeiqi';
- or
select * from tb1 where nid = 1 or email = 'seven@live.com';
特别的:当or条件中有未建立索引的列才失效,以下会走索引
select * from tb1 where nid = 1 or name = 'seven';
select * from tb1 where nid = 1 or email = 'seven@live.com' and name = 'alex'
- 类型不一致
如果列是字符串类型,传入条件是必须用引号引起来,不然...
select * from tb1 where name = 999;
- !=
select * from tb1 where name != 'alex'
特别的:如果是主键,则还是会走索引
select * from tb1 where nid != 123
- >
select * from tb1 where name > 'alex'
特别的:如果是主键或索引是整数类型,则还是会走索引
select * from tb1 where nid > 123
select * from tb1 where num > 123
- order by
select email from tb1 order by name desc;
当根据索引排序时候,选择的映射如果不是索引,则不走索引
特别的:如果对主键排序,则还是走索引:
select * from tb1 order by nid desc; - 组合索引最左前缀
如果组合索引为:(name,email)
name and email -- 使用索引
name -- 使用索引
email -- 不使用索引
同时注意:
- 避免使用select *
- count(1)或count(列) 代替 count(*)
- 创建表时尽量时 char 代替 varchar
- 表的字段顺序固定长度的字段优先
- 组合索引代替多个单列索引(经常使用多个条件查询时)
- 尽量使用短索引
- 使用连接(JOIN)来代替子查询(Sub-Queries)
- 连表时注意条件类型需一致
- 索引散列值(重复少)不适合建索引,例:性别不适合
其他的语句:
if条件语句:delimiter \\
create procedure proc_if ()
begin declare i int default 0;
if i = 1 then
select 1;
elseif i = 2 then
select 2;
else
select 7;
end if; end\\
delimiter ;
循环语句:while循环:
delimiter \\
create procedure proc_while ()
begin
declare num int ;
set num = 0 ;
while num < 10 do;
select num ;
set num = num + 1 ;
end while
end\\
delimiter ;
repeat循环:delimiter \\
create procedure proc_repeat ()
begin
declare i int ;
set i = 0 ;
repeat
select i;
set i = i + 1;
until i >= 5
end repeat;
end\\
delimiter ;
loop循环:begin
declare i int default 0;
loop_label: loop
set i=i+1;
if i<8 then;
iterate loop_label;
end if;
if i>=10 then
leave loop_label;
end if;
select i;
end loop loop_label;
end
常见的内置函数:
HAR_LENGTH(str)
返回值为字符串str 的长度,长度的单位为字符。一个多字节字符算作一个单字符。
对于一个包含五个二字节字符集, LENGTH()返回值为 10, 而CHAR_LENGTH()的返回值为5。 CONCAT(str1,str2,...)
字符串拼接
如有任何一个参数为NULL ,则返回值为 NULL。
CONCAT_WS(separator,str1,str2,...)
字符串拼接(自定义连接符)
CONCAT_WS()不会忽略任何空字符串。 (然而会忽略所有的 NULL)。 CONV(N,from_base,to_base)
进制转换
例如:
SELECT CONV('a',16,2); 表示将 a 由16进制转换为2进制字符串表示 FORMAT(X,D)
将数字X 的格式写为'#,###,###.##',以四舍五入的方式保留小数点后 D 位, 并将结果以字符串的形式返回。若 D 为 0, 则返回结果不带有小数点,或不含小数部分。
例如:
SELECT FORMAT(12332.1,4); 结果为: '12,332.1000'
INSERT(str,pos,len,newstr)
在str的指定位置插入字符串
pos:要替换位置其实位置
len:替换的长度
newstr:新字符串
特别的:
如果pos超过原字符串长度,则返回原字符串
如果len超过原字符串长度,则由新字符串完全替换
INSTR(str,substr)
返回字符串 str 中子字符串的第一个出现位置。 LEFT(str,len)
返回字符串str 从开始的len位置的子序列字符。 LOWER(str)
变小写 UPPER(str)
变大写 LTRIM(str)
返回字符串 str ,其引导空格字符被删除。
RTRIM(str)
返回字符串 str ,结尾空格字符被删去。
SUBSTRING(str,pos,len)
获取字符串子序列 LOCATE(substr,str,pos)
获取子序列索引位置 REPEAT(str,count)
返回一个由重复的字符串str 组成的字符串,字符串str的数目等于count 。
若 count <= 0,则返回一个空字符串。
若str 或 count 为 NULL,则返回 NULL 。
REPLACE(str,from_str,to_str)
返回字符串str 以及所有被字符串to_str替代的字符串from_str 。
REVERSE(str)
返回字符串 str ,顺序和字符顺序相反。
RIGHT(str,len)
从字符串str 开始,返回从后边开始len个字符组成的子序列 SPACE(N)
返回一个由N空格组成的字符串。 SUBSTRING(str,pos) , SUBSTRING(str FROM pos) SUBSTRING(str,pos,len) , SUBSTRING(str FROM pos FOR len)
不带有len 参数的格式从字符串str返回一个子字符串,起始于位置 pos。带有len参数的格式从字符串str返回一个长度同len字符相同的子字符串,起始于位置 pos。 使用 FROM的格式为标准 SQL 语法。也可能对pos使用一个负值。假若这样,则子字符串的位置起始于字符串结尾的pos 字符,而不是字符串的开头位置。在以下格式的函数中可以对pos 使用一个负值。 mysql> SELECT SUBSTRING('Quadratically',5);
-> 'ratically' mysql> SELECT SUBSTRING('foobarbar' FROM 4);
-> 'barbar' mysql> SELECT SUBSTRING('Quadratically',5,6);
-> 'ratica' mysql> SELECT SUBSTRING('Sakila', -3);
-> 'ila' mysql> SELECT SUBSTRING('Sakila', -5, 3);
-> 'aki' mysql> SELECT SUBSTRING('Sakila' FROM -4 FOR 2);
-> 'ki' TRIM([{BOTH | LEADING | TRAILING} [remstr] FROM] str) TRIM(remstr FROM] str)
返回字符串 str , 其中所有remstr 前缀和/或后缀都已被删除。若分类符BOTH、LEADIN或TRAILING中没有一个是给定的,则假设为BOTH 。 remstr 为可选项,在未指定情况下,可删除空格。 mysql> SELECT TRIM(' bar ');
-> 'bar' mysql> SELECT TRIM(LEADING 'x' FROM 'xxxbarxxx');
-> 'barxxx' mysql> SELECT TRIM(BOTH 'x' FROM 'xxxbarxxx');
-> 'bar' mysql> SELECT TRIM(TRAILING 'xyz' FROM 'barxxyz');
-> 'barx'
摘自老师的博客
。
mysql的进阶的更多相关文章
- mysql 开发进阶篇系列 55 权限与安全(安全事项 )
一. 操作系统层面安全 对于数据库来说,安全很重要,本章将从操作系统和数据库两个层面对mysql的安全问题进行了解. 1. 严格控制操作系统账号和权限 在数据库服务器上要严格控制操作系统的账号和权限, ...
- mysql 开发进阶篇系列 47 物理备份与恢复(xtrabackup 的完全备份恢复,恢复后重启失败总结)
一. 完全备份恢复说明 xtrabackup二进制文件有一个xtrabackup --copy-back选项,它将备份复制到服务器的datadir目录下.下面是通过 --target-dir 指定完全 ...
- mysql 开发进阶篇系列 46 物理备份与恢复( xtrabackup的 选项说明,增加备份用户,完全备份案例)
一. xtrabackup 选项说明 在操作xtrabackup备份与恢复之前,先看下该工具的选项,下面记录了xtrabackup二进制文件的部分命令行选项,后期把常用的选项在补上.点击查看xtrab ...
- mysql 开发进阶篇系列 42 逻辑备份与恢复(mysqldump 的完全恢复)
一.概述 在作何数据库里,备份与恢复都是非常重要的.好的备份方法和备份策略将会使得数据库中的数据更加高效和安全.对于DBA来说,进行备份或恢复操作时要考虑的因素大概有如下: (1) 确定要备份的表的存 ...
- mysql 开发进阶篇系列 20 MySQL Server(innodb_lock_wait_timeout,innodb_support_xa,innodb _log_*)
1. innodb_lock_wait_timeout mysql 可以自动监测行锁导致的死锁并进行相应的处理,但是对于表锁导致的死锁不能自动监测,所以该参数主要用于,出现类似情况的时候等待指定的时间 ...
- MySQL第二讲 一一一一 MySQL语句进阶
通过命令来备份数据库: 通过数据库软件里面的,mysqldump模块来操作,如下: mysqldump -u root db1 > db1.sql -p; //没有-d就是备份的时候:数据表结构 ...
- MYSQL(进阶篇)——一篇文章带你深入掌握MYSQL
MYSQL(进阶篇)--一篇文章带你深入掌握MYSQL 我们在上篇文章中已经学习了MYSQL的基本语法和概念 在这篇文章中我们将讲解底层结构和一些新的语法帮助你更好的运用MYSQL 温馨提醒:该文章大 ...
- mysql 开发进阶篇系列 10 锁问题 (相同索引键值或同一行或间隙锁的冲突)
1.使用相同索引键值的冲突 由于mysql 的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但如果是使用相同的索引键,是会出现锁冲突的.设计时要注意 例如:city表city_ ...
- 数据库学习笔记(二)MySQL数据库进阶
MySQL 进阶 关于连表 左右连表: join 上下连表: union #自动去重 (当两张表里的数据,有重复的才会自动去重) union all #不去重 #上下连表示例: select sid, ...
- MySQL 【进阶查询】
数据类型介绍 整型 tinyint, # 占1字节,有符号:-128~127,无符号位:0~255 smallint, # 占2字节,有符号:-32768~32767,无符号位:0~65535 med ...
随机推荐
- MsSql去掉重复记录
假如有这样一张表news:字段:id,title,time,image,author,现在表中有1万多条记录,其中title重复的有上千条.如何才能一次性将title重复记录删除呢? ID Title ...
- 云时代的.NET
编程语言从最初的0101机器码到汇编语言再到面向对象的编程,不断的发展,整个发展趋势呈现高内聚.低耦合.可重用.可理解的特点.最早编程是用机器码,人的大脑不像电脑,无法处理0101:后来汇编语言还是太 ...
- ReactiveSwift源码解析(四) Signal中的静态属性静态方法以及面向协议扩展
上篇博客我们聊了Signal的几种状态.Signal与Observer的关联方式以及Signal是如何向关联的Observer发送事件的.本篇博客继续上篇博客的内容,来聊一下Signal类中静态的ne ...
- 爬虫框架之Scrapy(三 CrawlSpider)
如何爬取一个网站的全站数据? 可以使用Scrapy中基于Spider的递归方式进行爬取(Request模块回调parse方法) 还有一种更高效的方法,就是基于CrawlSpider的自动爬取实现 简介 ...
- Ansible自动化运维工具安装与使用实例
1.准备两台服务器,要确定网络是通的.服务器当然越多越好啦....Ansible的简介和好处我就不多说了,自己看百科去(*╹▽╹*) IP:192.168.139.100 IP:192.168.139 ...
- Litepal【开源数据库ORM框架】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 好用的数据库框架. 效果图 代码分析 本篇主要是整理Litepal的引入和增删改查的简单操作,具体使用请阅读参考资料. 使用步骤 一 ...
- python基础2--数据结构(列表List、元组Tuple、字典Dict)
1.Print函数中文编码问题 print中的编码:# -*- coding: utf-8 -*- 注:此处的#代表的是配置信息 print中的换行符,与C语言相同,为"\n" 2 ...
- Springboot 系列(四)Spring Boot 日志框架
注意:本 Spring Boot 系列文章基于 Spring Boot 版本 v2.1.1.RELEASE 进行学习分析,版本不同可能会有细微差别. 前言 Spring 框架选择使用了 JCL 作为默 ...
- Keras入门(四)之利用CNN模型轻松破解网站验证码
项目简介 在之前的文章keras入门(三)搭建CNN模型破解网站验证码中,笔者介绍介绍了如何用Keras来搭建CNN模型来破解网站的验证码,其中验证码含有字母和数字. 让我们一起回顾一下那篇文 ...
- vue.js之组件篇
Vue.js 组件 模块化:是从代码逻辑的角度进行划分的: 组件化:是从UI界面的角度进行划分的. 组件(Component)是 Vue.js 最强大的功能之一,组件可以扩展 HTML 元素,封装可重 ...