Hexo

  • Home

  • About

  • Tags

  • Categories

  • Archives

  • Schedule

PHP基础12-cookie与session

Posted on 2019-02-15 | In PHP基础
会话控制

cookie

介绍

Cookie是用来将网站的资料记录在客户端的技术,这种技术让Web服务器能将一些资料,存放于客户端(用户的电脑)之中。 比如:当通过验证,成功登录网站后,在”网页一“的PHP脚本中,会把这个用户有关的信息,设置到客户端电脑的Cookie中,当再次访问同一个网站中的其他脚本时,就会自动携带Cookie中的数据一起访问,在服务器中的每个脚本中都可以接受Cookie中的数据,不需要每访问一个页面就重新输入一次登录者的信息。
Cookies最典型的应用是判定注册用户是否已经登录网站,用户可能会得到提示,是否在下一次进入此网站时保留用户信息以便简化登录手续,这些都是Cookies的功用。另一个重要应用场合是“购物车”之类处理。用户可能会在一段时间内在同一家网站的不同页面中选择不同的商品,这些信息都会写入Cookies,以便在最后付款时提取信息。

使用和禁用Cookie

用户可以改变浏览器的设置,以使用或者禁用Cookies。
微软Internet Explorer
工具 > Internet选项 > 隐私页
调节滑块或者点击“高级”,进行设置.
Mozilla Firefox
工具>选项>隐私
(注: 在Linux版本中,是如下操作:编辑 > 首选项 > 隐私 , 而Mac则是:Firefox > 属性 > 隐私)
查看源网页
查看源网页 [5]
设置Cookies选项
设定阻止/允许的各个域内Cookie
查看Cookies管理窗口,检查现存Cookie信息,选择删除或者阻止它们

由于用户可能会禁用cookie那么使用替代方案:URL参数

Cookie操作:

1.向客户端电脑中设置Cookie
setcookie ();

1
2
3
<?php
var_dump(uniqid(rand(1000,9999)));//设置cookie产生的随机数
?>

2.在服务器端上读取Cookie的内容
$_COOKIE

1
2
3
4
<?php
header('Content-type:text/html;charset=utf-8');
var_dump($_COOKIE);
?>

3.将多维数组应用于Cookie中
setcookie(“member[name]”,’孙胜利’);
setcookie(“member[email]”,'1205429372@qq.com‘);
一维数组:将所以cookie都直接保存在cookie数组下
使用二维数组,这样就能使多个cookie保存在cookie数组里的一个数组元素中

之所以还有上面的两个cookie是因为有效期还没过,我们删除之前的记录后:

4.删除Cookie
setcookie(“member”,’’,time()-1);

1
2
3
4
5
 <?php 
foreach ($_COOKIE['member'] as $key=>$val){
var_dump(setcookie("member[{$key}]",'',time()-3600));
}
?>

注意点:使用setcookie删除cookie的时候,需要与当初设置cookie时的参数一致

session

Session技术与Cookie相似,都是用来存储使用者的相关资料,但是最大的不同之处在于Cookie是将资料存储在客户端电脑中,而Session则是将数据存放于服务器上。把保存的资料比喻成超市里面的会员卡,Cookie技术就相当于需要用户自己保存会员卡,每次去超市必须要持有会员卡才能代表自己的身份,那么Session技术就相当于会员卡由超市方保存,每次来超市的时候只需要报出会员卡的卡号(我们可以称为Session ID,客户端的cookie中只需要保存Session ID)即可!

session操作

1.开启session
session_start();//开启一个会话,或者返回已经存在的会话
2.使用session存储数据
session_start();
$_SESSION[‘username’]=’sunshengli’;
$_SESSION[‘email’]='1205429372@qq.com‘;
3.注销变量与销毁session

1
2
3
4
5
6
 <?php 
session_start();//打开要销毁的会话!
session_unset();//Free all session variables 释放所有的会话变量
session_destroy();//销毁一个会话中的全部数据
setcookie(session_name(),'',time()-3600,'/');//销毁保存在客户端的卡号(session id)
?>

注意:
如果此时我们不写第四个path参数即代码为:
setcookie(session_name(),’’,time()-3600)
此时我们查看session和cookie的销毁情况如下:

注意到cookie没有被删掉
原因:
PHP手册中setcookie里面的第四个参数:
path
Cookie 有效的服务器路径。 设置成 ‘/‘ 时,Cookie 对整个域名 domain 有效。 如果设置成 ‘/foo/‘, Cookie 仅仅对 domain 中 /foo/ 目录及其子目录有效(比如 /foo/bar/)。 默认值是设置 Cookie 时的当前目录。
而使用session时传的cookie位置是”/“

我们可以发现路径不一致,因此没有销毁对应的cookie
当我们设置好path参数后,成功删除客户端里的cookie

结论:
在销毁保存在客户端的时cookie时,要保证和当初设置的参数(path)一致。

在新的php中想获取session时,要先使用session_start();返回已经存在的会话。否则获取不到session

cookie与session

1>联系:Session在客户端也需要保存一个标识,所以就要借助Cookie,session是通过cookie来工作的session和cookie之间是通过$_COOKIE[‘PHPSESSID’]来联系的,通过$_COOKIE[‘PHPSESSID’]可以知道session的id,从而获取到其他的信息。
2>区别:Cookie机制采用的是在客户端(浏览器)保持状态的方案,而session机制采用的是在服务器端保持状态的方案

PHP正则表达式(续)

Posted on 2019-02-14 | In PHP正则表达式

正则表达式匹配网页

//正则匹配函数:preg_match preg_match_all

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
$str=<<<yfstr
<div id="mainNav" class="clearfix">
<a href="index.php">首页</a>
<a href="category.php?id=3">GSM手机</a>
<a href="category.php?id=4">双模手机</a>
<a href="category.php?id=6">手机配件</a>
<a href="group_buy.php">团购
商品</a>
<a href="activity.php">优惠活动</a>
<a href="snatch.php">夺宝奇兵</a>
<a href="auction.php">拍卖活动</a>
<a href="exchange.php">积分商城</a>
<a href="message.php">留言板</a>
<a href="http://bbs.ecshop.com/">EC论坛</a>
</div>
yfstr;

echo "<table width='900' border='1'>";
echo "<tr><th>名称</th><th>URL地址</th><th>链接</th></tr>";
//使用正则匹配
preg_match_all("/<a href=\"(.*?)\".*?>(.*?)<\/a>/s",$str,$a);
foreach($a[0] as $k=>$v){
echo "<tr>";
echo "<td>{$a[2][$k]}</td>";
echo "<td>{$a[1][$k]}</td>";
echo "<td>{$v}</td>";
echo "</tr>";
}
echo "</table>";

注:使用<<< 这个是php定界符
使用格式:
<<<EOF
…
EOF;
使用定界符无需给双引号增加转义字符,可以参考如下:

1
$str=”/<div id=\"mainNav\" class=\"clearfix\">/”;

正则的其他函数使用

//正则的其他函数使用:
//preg_quote – 转义正则表达式字符
//preg_split – 用正则表达式分割字符串
//preg_replace – 执行正则表达式的搜索和替换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

//1.preg_quote -- 转义正则表达式字符
echo preg_quote("(abc){10}","'");//在每个增则表达式语法的字符前增加一个反斜杠

$s = "a{4}";
preg_match("/".preg_quote($s)."/","werta{4}yu",$a);
var_dump($a);

echo "<br/>";


//2. preg_split -- 用正则表达式分割字符串
$s = "12,34:56;784;35,67:897:65";
$list = preg_split("/[,:;]/",$s);
var_dump($list);

echo "<hr/>";


//3. preg_replace执行正则表达式的搜索和替换

$s = "12,34:56;784;35,67:897:65";
//要求将上面的:,;都换成空格
echo preg_replace("/[,;:]/"," ",$s);

$str = "<ul style='color:red'>
<li>aaaaa</li>
<li>bbbbb</li>
<li>ddddd</li>
<li>eeeee</li>
</ul>";

//将上面字串中所有li标签中都添加一个b标签。
echo "<hr/>";
echo $str;

echo "<hr/>";
//echo preg_replace("/<li>(.*?)<\/li>/","<li><b>\\1</b></li>",$str);
//echo preg_replace("/<li>(.*?)<\/li>/","<li><b>\$1</b></li>",$str);
echo preg_replace("/<li>(.*?)<\/li>/",'<li><b>$1</b></li>',$str);

子存储(扩展)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//子存储使用
$date="[2012-08-09],[2012,09-19],[2011/08,09],[2012/10/09],[2013,08,01]";

//将上面字串中合法的日期匹配出来
preg_match_all("/\[[0-9]{4}([\-,\/])[0-9]{2}\\1[0-9]{2}\]/",$date,$a);
var_dump($a);

echo "<hr/>";

$str = "<ul
style='color:red'><br/>
<li>aaaaa</li>
<li>bbbbb</li>
<li>ddddd</li>
<li>eeeee</li>
</ul>";
//将上面字串中的html标记删除掉(替换空)
echo preg_replace("/<\/?.*?\/?>/s","",$str);

附录 常用正则表达式

^\d+$  \d 是代表0-9  $必须要以....结束  这是代表非负整数   正则表达式

平时做网站经常要用正则表达式,下面是一些讲解和例子,仅供大家参考和修改使用: 
"^\d+$"  //非负整数(正整数 + 0) 
"^[0-9]*[1-9][0-9]*$"  //正整数 
"^((-\d+)|(0+))$"  //非正整数(负整数 + 0) 
"^-[0-9]*[1-9][0-9]*$"  //负整数 
"^-?\d+$"    //整数 
"^\d+(\.\d+)?$"  //非负浮点数(正浮点数 + 0) 
"^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$"  //正浮点数 
"^((-\d+(\.\d+)?)|(0+(\.0+)?))$"  //非正浮点数(负浮点数 + 0) 
"^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$"  //负浮点数 
"^(-?\d+)(\.\d+)?$"  //浮点数 
"^[A-Za-z]+$"  //由26个英文字母组成的字符串 
"^[A-Z]+$"  //由26个英文字母的大写组成的字符串 
"^[a-z]+$"  //由26个英文字母的小写组成的字符串 
"^[A-Za-z0-9]+$"  //由数字和26个英文字母组成的字符串 
"^\w+$"  //由数字、26个英文字母或者下划线组成的字符串 
"^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$"    //email地址 
"^[a-zA-z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$"  //url 
/^(d{2}|d{4})-((0([1-9]{1}))|(1[1|2]))-(([0-2]([1-9]{1}))|(3[0|1]))$/ // 年-月-日 
/^((0([1-9]{1}))|(1[1|2]))/(([0-2]([1-9]{1}))|(3[0|1]))/(d{2}|d{4})$/ // 月/日/年 
"^([w-.]+)@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.)|(([w-]+.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(]?)$" //Emil 
/^((\+?[0-9]{2,4}\-[0-9]{3,4}\-)|([0-9]{3,4}\-))?([0-9]{7,8})(\-[0-9]+)?$/ //电话号码 
"^(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5])$" //IP地址 
匹配中文字符的正则表达式: [\u4e00-\u9fa5] 
匹配双字节字符(包括汉字在内):[^\x00-\xff] 
匹配空行的正则表达式:\n[\s| ]*\r 
匹配HTML标记的正则表达式:/<(.*)>.*<\/\1>|<(.*) \/>/ 
匹配首尾空格的正则表达式:(^\s*)|(\s*$) 
匹配Email地址的正则表达式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)* 
匹配网址URL的正则表达式:^[a-zA-z]+://([url=file://\\w+(-\\w+)*)(\\.(\\w+(-\\w+)*))*(\\?\\S*)?$]\\w+(-\\w+)*)(\\.(\\w+(-\\w+)*))*(\\?\\S*)?$[/url] 
匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$ 
匹配国内电话号码:(\d{3}-|\d{4}-)?(\d{8}|\d{7})? 
匹配腾讯QQ号:^[1-9]*[1-9][0-9]*$ 


元字符及其在正则表达式上下文中的行为: 
\ 将下一个字符标记为一个特殊字符、或一个原义字符、或一个后向引用、或一个八进制转义符。 
^ 匹配输入字符串的开始位置。如果设置了 RegExp 对象的Multiline 属性,^ 也匹配 ’\n’ 或 ’\r’ 之后的位置。 
$ 匹配输入字符串的结束位置。如果设置了 RegExp 对象的Multiline 属性,$ 也匹配 ’\n’ 或 ’\r’ 之前的位置。 
* 匹配前面的子表达式零次或多次。 
+ 匹配前面的子表达式一次或多次。+ 等价于 {1,}。 
? 匹配前面的子表达式零次或一次。? 等价于 {0,1}。 
{n} n 是一个非负整数,匹配确定的n 次。 
{n,} n 是一个非负整数,至少匹配n 次。 
{n,m} m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。在逗号和两个数之间不能有空格。 
? 当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认 
的贪婪模式则尽可能多的匹配所搜索的字符串。 
. 匹配除 "\n" 之外的任何单个字符。要匹配包括 ’\n’ 在内的任何字符,请使用象 ’[.\n]’ 的模式。 
(pattern) 匹配pattern 并获取这一匹配。 
(?:pattern) 匹配pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。 
(?=pattern) 正向预查,在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。 
(?!pattern) 负向预查,与(?=pattern)作用相反 
x|y 匹配 x 或 y。 
[xyz] 字符集合。 
[^xyz] 负值字符集合。 
[a-z] 字符范围,匹配指定范围内的任意字符。 
[^a-z] 负值字符范围,匹配任何不在指定范围内的任意字符。 
\b 匹配一个单词边界,也就是指单词和空格间的位置。 
\B 匹配非单词边界。 
\cx 匹配由x指明的控制字符。 
\d 匹配一个数字字符。等价于 [0-9]。 
\D 匹配一个非数字字符。等价于 [^0-9]。 
\f 匹配一个换页符。等价于 \x0c 和 \cL。 
\n 匹配一个换行符。等价于 \x0a 和 \cJ。 
\r 匹配一个回车符。等价于 \x0d 和 \cM。 
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。 
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。 
\t 匹配一个制表符。等价于 \x09 和 \cI。 
\v 匹配一个垂直制表符。等价于 \x0b 和 \cK。 
\w 匹配包括下划线的任何单词字符。等价于’[A-Za-z0-9_]’。 
\W 匹配任何非单词字符。等价于 ’[^A-Za-z0-9_]’。 
\xn 匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。 
\num 匹配 num,其中num是一个正整数。对所获取的匹配的引用。 
\n 标识一个八进制转义值或一个后向引用。如果 \n 之前至少 n 个获取的子表达式,则 n 为后向引用。否则,如果 n 为八进制数字 (0-7),则 n 为一个 
八进制转义值。 
\nm 标识一个八进制转义值或一个后向引用。如果 \nm 之前至少有is preceded by at least nm 个获取得子表达式,则 nm 为后向引用。如果 \nm 之前至 
少有 n 个获取,则 n 为一个后跟文字 m 的后向引用。如果前面的条件都不满足,若 n 和 m 均为八进制数字 (0-7),则 \nm 将匹配八进制转义值 nm。 
\nml 如果 n 为八进制数字 (0-3),且 m 和 l 均为八进制数字 (0-7),则匹配八进制转义值 nml。 
\un 匹配 n,其中 n 是一个用四个十六进制数字表示的Unicode字符。 

匹配中文字符的正则表达式: [\x{4e00}-\x{9fa5}] 
匹配双字节字符(包括汉字在内):[^x00-xff] 
匹配空行的正则表达式:n[s| ]*r 
匹配HTML标记的正则表达式:/<(.*)>.*|<(.*) />/ 
匹配首尾空格的正则表达式:(^s*)|(s*$) 
匹配Email地址的正则表达式:w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)* 
匹配网址URL的正则表达式:[url=http://([w-]+.)+[w-]+(/[w]http://([w-]+.)+[w-]+(/[w[/url]- ./?%&=]*)? 
利用正则表达式限制网页表单里的文本框输入内容: 
用正则表达式限制只能输入中文:onkeyup="value=value.replace(/[^u4E00-u9FA5]/g,'')" 
用正则表达式限制只能输入全角字符: 
用正则表达式限制只能输入数字:onkeyup="value=value.replace(/[^d]/g,'') "onbeforepaste="clipboardData.setData 
('text',clipboardData.getData('text').replace(/[^d]/g,''))" 
用正则表达式限制只能输入数字和英文:onkeyup="value=value.replace(/[W]/g,'') "onbeforepaste="clipboardData.setData 
('text',clipboardData.getData('text').replace(/[^d]/g,''))" 



=========常用正则式

匹配中文字符的正则表达式: [\x{4e00}-\x{9fa5}]
匹配双字节字符(包括汉字在内):[^\x00-\xff] 
匹配空行的正则表达式:\n[\s| ]*\r 
匹配HTML标记的正则表达式:/<(.*)>.*<\/\1>|<(.*) \/>/ 
匹配首尾空格的正则表达式:(^\s*)|(\s*$) 
匹配IP地址的正则表达式:/(\d+)\.(\d+)\.(\d+)\.(\d+)/g // 
匹配Email地址的正则表达式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)* 
匹配网址URL的正则表达式:[url=http://(/[\w-]+\.)+[\w-]+(/[\w]http://(/[\w-]+\.)+[\w-]+(/[\w[/url]- ./?%&=]*)? 
sql语句:^(select|drop|delete|create|update|insert).*$ 
1、非负整数:^\d+$ 
2、正整数:^[0-9]*[1-9][0-9]*$ 
3、非正整数:^((-\d+)|(0+))$ 
4、负整数:^-[0-9]*[1-9][0-9]*$ 
5、整数:^-?\d+$ 
6、非负浮点数:^\d+(\.\d+)?$ 
7、正浮点数:^((0-9)+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$ 
8、非正浮点数:^((-\d+\.\d+)?)|(0+(\.0+)?))$ 
9、负浮点数:^(-((正浮点数正则式)))$ 
10、英文字符串:^[A-Za-z]+$ 
11、英文大写串:^[A-Z]+$ 
12、英文小写串:^[a-z]+$ 
13、英文字符数字串:^[A-Za-z0-9]+$ 
14、英数字加下划线串:^\w+$ 
15、E-mail地址:^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$ 
16、URL:^[a-zA-Z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\s*)?$ 
或:^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\':+!]*([^<>\"\"])*$ 
17、邮政编码:^[1-9]\d{5}$ 
18、中文:^[\u0391-\uFFE5]+$ 
19、电话号码:^((\(\d{2,3}\))|(\d{3}\-))?(\(0\d{2,3}\)|0\d{2,3}-)?[1-9]\d{6,7}(\-\d{1,4})?$ 
20、手机号码:^((\(\d{2,3}\))|(\d{3}\-))?13\d{9}$ 
21、双字节字符(包括汉字在内):^\x00-\xff 
22、匹配首尾空格:(^\s*)|(\s*$)(像vbscript那样的trim函数) 
23、匹配HTML标记:<(.*)>.*<\/\1>|<(.*) \/> 
24、匹配空行:\n[\s| ]*\r 
25、提取信息中的网络链接:(h|H)(r|R)(e|E)(f|F) *= *('|")?(\w|\\|\/|\.)+('|"| *|>)? 
26、提取信息中的邮件地址:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)* 
27、提取信息中的图片链接:(s|S)(r|R)(c|C) *= *('|")?(\w|\\|\/|\.)+('|"| *|>)? 
28、提取信息中的IP地址:(\d+)\.(\d+)\.(\d+)\.(\d+) 
29、提取信息中的中国手机号码:(86)*0*13\d{9} 
30、提取信息中的中国固定电话号码:(\(\d{3,4}\)|\d{3,4}-|\s)?\d{8} 
31、提取信息中的中国电话号码(包括移动和固定电话):(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14} 
32、提取信息中的中国邮政编码:[1-9]{1}(\d+){5} 
33、提取信息中的浮点数(即小数):(-?\d*)\.?\d+ 
34、提取信息中的任何数字 :(-?\d*)(\.\d+)? 
35、IP:(\d+)\.(\d+)\.(\d+)\.(\d+) 
36、电话区号:/^0\d{2,3}$/ 
37、腾讯QQ号:^[1-9]*[1-9][0-9]*$ 
38、帐号(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$ 
39、中文、英文、数字及下划线:^[\u4e00-\u9fa5_a-zA-Z0-9]+$



资料摘自:http://www.cnblogs.com/yafei236/p/4168290.html

PHP正则表达式

Posted on 2019-02-14 | Edited on 2019-02-23 | In PHP正则表达式

一、 正则表达式介绍

描述了一类字符串的特征,然后通过这个特征可以配合一些特定的函数,来完成对字符串更加复杂的一系列操作!
普通字符和特殊字符组成的一个字符串

1. 用途:匹配、查找、替换、分割 
2. php提供了两套正则表达式函数库 
    (1). Perl 兼容正则表达式函数(推荐使用) 
    (2). POSIX 扩展正则表达式函数

二、语法规则

表达式的格式: "/表达式/[修正符]" 

其中修正符是可选的,表示对表达式做额外的修饰。
我们一般习惯使用正斜线”/“作为定界的字符,前后一致
注意:定界符不可以是字母、数字和斜线\。
像“#”、“|”、“!”等都可以的
如:/…/ #…# |….|

三、 正则表达式的组成部分:

1. 基本单位(原子)

原子是组成正则表达式的基本单位,在分析正则表达式时,应作为一个整体。
原子包括以下内容:

* 单个字符、数字,如a-z,A-Z,0-9。 
* 模式单元,如(ABC)可以理解为由多个原子组成的大的原子。 
* 原子表,如 [ABC]。 
* 重新使用的模式单元,如:\\1 
* 普通转义字符,如:\d, \D, \w 
* 转义元字符,如:\*,\. 
* 元字符

2. 元字符(具有特殊意义字符):

各个字符含义

[] 表示单个字符的原子表 
    例如:[aoeiu] 表示任意一个元音字母 
          [0-9] 表示任意一位数字 
          [a-z][0-9]表示小写字和一位数字构成的两位字符 
          [a-zA-Z0-9] 表示任意一位大小字母或数字 
[^] 表示除中括号内原子之外的任何字符 是[]的取反 
    例如:[^0-9] 表示任意一位非数字字符 
          [^a-z] 表示任意一位非小写字母 
{m}    表示对前面原子的数量控制,表示是m次 
    例如:[0-9]{4} 表示4为数字 
          [1][3-8][0-9]{9} 手机号码 
{m,} 表示对前面原子的数量控制,表示是至少m次          
    例如: [0-9]{2,} 表示两位及以上的数字 
{m,n}表示对前面原子的数量控制,表示是m到n次 
    例如: [a-z]{6,8} 表示6到8位的小写字母 
* 表示对前面原子的数量控制,表示是任意次,等价于{0,} 
+ 表示对前面原子的数量控制,表示至少1次,等价于{1,} 
? 表示对前面原子的数量控制,表示0次或1次(可有可无) 等价于{0,1} 
    例如:正整数:[1-9][0-9]* 
            整数:[\-]?[0-9]+ 
() 表示一个整体原子,还有一个子存储单元的作用【使用\\数字或$数字来代表圆括号部分所匹配到的内容】。 
        也可以使用?:来拒绝子存储。 (?:.*?) 
    例如:(red) 字串red 
           (rea|blue) 字串red或blue 
           (abc){2} 表示两个abc 
|  表示或的意思 
        (rea|blue) 字串red或blue 
^  用在正则单元块的开头处,表示必须以指定的开头 
$  用在正则单元块的结尾处,表示必须以指定的结尾 
.  表示任意一个除换行符之外的字符 

()的使用:

如果使用对应的\\数字或$数字来代表圆括号部分所匹配到的内容,那么要注意匹配完整

由于没用匹配到\\1对应的e,匹配失败

只有对应的内容都匹配到了才是匹配成功。array数组中分别保存了匹配的完整字符串,和()所匹配到的字符


常用组合(贪婪匹配问题)

.与{n}配合 中间有n个非空
.与*配合 默认是贪婪匹配(尽可能多的去匹配字符) 中间有任意个非空

.*? 可以解决贪婪匹配(表示最小匹配所有字符)

也可以使用模式修正符来解决: m

3. 普通转义字符:

\d 匹配一个数字;等价于[0-9]
\D 匹配除数字以外任何一个字符;等价于[^0-9]
\w 匹配一个英文字母、数字或下划线;等价于[0-9a-zA-Z_]
\W 匹配除英文字母、数字和下划线以外任何一个字符;等价于[^0-9a-zA-Z_]
\s 匹配一个空白字符;等价于[\f\n\r\t\v]
\S 匹配除空白字符以外任何一个字符;等价于[^\f\n\r\t\v]
\f 匹配一个换页符等价于 \x0c 或 \cL
\n 匹配一个换行符;等价于 \x0a 或 \cJ
\r 匹配一个回车符等价于\x0d 或 \cM
\t 匹配一个制表符;等价于 \x09\或\cl
\v 匹配一个垂直制表符;等价于\x0b或\ck
\oNN 匹配一个八进制数字
\xNN 匹配一个十六进制数字
\cC 匹配一个控制字符

4. 常见模式修正符

常见四种

i    在和模式进行匹配时不区分大小写"/[a-zA-Z]/" <==>"/[a-z]/i" 
m    多行匹配,如果目标字符串 中没有"\n"字符, 或者模式中没有出现^或$, 设置这个修饰符不产生任何影响
s    如果设定了此修正符,那么.将匹配所有的字符包括换行符(表示匹配视为单行:就是可以让点.支持换行) 
U    禁止贪婪匹配

U 禁止贪婪匹配

i 不区分大小写

如果设置了这个修饰符,模式中的字母会进行大小写不敏感匹配。

m 多行匹配

(如果目标字符串中没用“\n”字符,或者模式中没用出现^或$,设置这个修饰符不产生任何影响)
使用条件

  1. 目标字符串必须包含换行符“\n” 字符串中出现\n就表示新的一行开始
  2. 正则表达式中必须要出现^或者$
    未使用修正符时:


此时使用模式修正符,发现没用改动!

为什么?
因为在单引号里面不识别转义\n,它认为是普通的字符,而不是换行!!!

因此,我们将单引号换成双引号(我们可以发现\n有了高亮,实现了转义)

此时发现,m 模式修饰符起到了作用
换成以test结束试试(使用$)

依旧可以

\n代表着换行那么,我们手动换行试试?

只能匹配一个,此时匹配的是最后一个
为什么?
解释:
在windows操作系统中,我们所看到的换行(肉眼看到的换行现象),其实是通过两个字符来完成的(\r\n)
在linux操作系统中看,我们所看到的换行(肉眼看到的换行现象),是通过\n来完成的

如果是这样,我们修改匹配规则: $pattern=’/test\r$/m’;

发现匹配到了三个,此时应为前三个匹配到

那么我们如何在windows如何匹配到四个呢?我们可以使用*来使得\r出不出现都能匹配到

1
$pattern='/test\r*$/m';


此时成功匹配到四个

s 让点.支持换行

如果设置了这个修饰符,模式中的点号元字符匹配所有字符,包含换行符。如果没有这个 修饰符,点号不匹配换行符
不使用s 修正符时

使用s修正符:

使用手动回车代替\n时:

发现:同样我们在使用模式修正符s时,如果我们不是写\n而是手动回车也会发生同样的错误



补充:
\r 回车符
\n 换行符
两者区别
以下代码摘自网络:本帖最后由 rossini23 于 2011-05-26 23:48 编辑
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>

int main()
{
printf("this is\ra test\r\n"); //1
printf("this is\na test\r\n"); //2
printf("this is\r\na test\r\n"); //3
return 0;
}

a tests
this is
a test
this is
a test

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1.	#include <stdio.h>
2.
3. int main()
4. {
5. printf("this is\ra test\r\n"); //1
6. printf("this is\na test\r\n"); //2
7. printf("this is\r\na test\r\n"); //3
8. return 0;
9. }
上面这一小段代码在Linux、windows下的输出如下:
1. a tests
2. this is
3. a test
4. this is
5. a test
第一条打印语句,\r使光标移动到本行行首,然后打印a test覆盖this i,变成a tests
第二条打印语句,\n使光标移动到下一行行首,然后打印a test
第三条打印语句,\r\n使光标移动到本行行首,然后移动到下一行行首,然后打印a test

然后在linux下,用stty设置关闭ONLCR转换:
stty -onlcr
发现输出变为:
1.    a tests
2.    this is
3.             a test
4.    this is
5.    a test
看起来,第二条打印语句的\n行为是“将光标移动到下一行当前位置”
在linux系统下,onlcr是控制nl转换到cr nl。
也就是说正常情况下\n被转换成了\r\n,然后送到屏幕上显示,所以第二个输出语句看到的效果是回到下一行行首。

stty -onlcr也就是关闭nl转换到cr nl,这时候送到屏幕上的只有\n,看到结果是移动到下一行当前位置。


\r\n是一个让人郁闷的问题,windows和我们的嵌入式系统之间交互总是有问题,所以想搞明白这个问题。
网络上搜\r\n也可以看到很多OS之间、协议之间交互的问题。

四、 正则表达式的函数:

preg_grep --  返回与模式匹配的数组单元 
**preg_match_all** -- 进行全局正则表达式匹配 , 返回共计匹配的个数。 
    和下面的一样,不同的是匹配到最后(全局匹配) 
**preg_match** -- 进行正则表达式匹配,只匹配一次,返回1,否则0, 
    格式:preg_match("正则表达式","被匹配的字串",存放结果的变量名,PREG_OFFSET_CAPTURE,起始偏移量) 
    其中:PREG_OFFSET_CAPTURE表示获取匹配索引位置 
          起始偏移量:从指定位置开始匹配 
preg_quote -- 转义正则表达式字符 
preg_split -- 用正则表达式分割字符串 
**preg_replace** -- 执行正则表达式的搜索和替换

preg_match_all 执行多次

执行一个全局正则表达式匹配
搜索subject中所有匹配pattern给定正则表达式的匹配结果并且将它们以flag指定顺序输出到matches中
在第一个匹配找到后, 子序列继续从最后一次匹配位置搜索

int preg_match_all ( string $pattern , string $subject [, array &$matches [, int $flags = PREG_PATTERN_ORDER [, int $offset = 0 ]]] )
参数 说明:

1.pattern

要搜索的模式,字符串形式。

2.subject

输入字符串。

3.matches

多维数组,作为输出参数输出所有匹配结果, 数组排序通过flags指定。

4.flags

可以结合下面标记使用(注意不能同时使用PREG_PATTERN_ORDER和 PREG_SET_ORDER):

PREG_PATTERN_ORDER(默认)

结果排序为$matches[0]保存完整模式的所有匹配, $matches[1] 保存第一个子组的所有匹配,以此类推。

PREG_SET_ORDER

结果排序为$matches[0]包含第一次匹配得到的所有匹配(包含子组), $matches[1]是包含第二次匹配到的所有匹配(包含子组)的数组,以此类推。

PREG_OFFSET_CAPTURE

如果这个标记被传递,每个发现的匹配返回时会增加它相对目标字符串的偏移量。 注意这会改变matches中的每一个匹配结果字符串元素,使其 成为一个第0个元素为匹配结果字符串,第1个元素为 匹配结果字符串在subject中的偏移量

5.offset

通常, 查找时从目标字符串的开始位置开始。可选参数offset用于 从目标字符串中指定位置开始搜索(单位是字节)。

preg_match 执行一次

mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )

第一个参数:正则表达式:pattern
pattern:要搜索的模式。可以使一个字符串或字符串数组。
第二个参数:要替换的字符串:replacement

第三个参数:目标字符串:subject
要进行搜索和替换的字符串或字符串数组。
如果subject是一个数组,搜索和替换回在subject 的每一个元素上进行, 并且返回值也会是一个数组。

如何使中间部分不变,只将div标签替换成a标签?
联系正则表达式中的()和\\ 由于\\指的使()中的内容,所以我们可以使用\\保留原来的字符串

也可以同时替换多个

replacement中可以包含反向引用\\n 或$n,语法上首选后者。

我们还能在标签内部也使用()和对应的反斜杠或$ 来保留标签样式

第四个参数limit(可选)
每个模式在每个subject上进行替换的最大次数。默认是 -1(无限)。

第五个参数count(可选)
如果指定,将会被填充为完成的替换次数。

和str_replace一样,第一个参数和第二个参数都可以是数组
如果pattern(第一个参数)和replacement(第二个参数) 都是数组,每个pattern使用replacement中对应的 元素进行替换。如果replacement中的元素比pattern中的少, 多出来的pattern使用空字符串进行替换。

mysql22-整库数据备份与还原

Posted on 2019-02-12 | In mysql

整库数据备份与还原

整库数据备份也叫SQL数据备份:备份的结果都是SQL指令

在mysql中提供了一个专门用于备份sql的客户端:mysqldump.exe

应用场景

SQL备份是一种mysql非常常见的备份与还原方式,SQL备份不只是备份数据,还备份对应的SQL指令(包含数据与表结构):即便是数据库遭到毁灭性的破坏(数据库被删),那么利用sql备份依然可以实现数据还原

sql备份因为需要备份结构,因此产生的备份文件特别大,因此不适合特大型数据备份,也不适合数据变化频繁型数据库备份

应用方案

SQL备份

sql备份用到的是专门的备份客户端,因此还没与数据库服务器进行连接

基本语法

mysqldump/mysqldump.exe -hPup 数据库名字【表1 【表2。。。】】 >备份文件地址
注:

  • 此时在windowsCMD环境下,而不是在sql,所以不需要语法的分号。
  • -h,-P可省略

备份可以有三种方式

  1. 整库备份(只需要提供数据库名字)
  2. 单表备份:数据库后面跟一张表
  3. 多表备份:数据库后跟多张表

查看备份的成果

查看备份文件中的具体内容

数据还原

mysql提供了多种方式来实现:两种
mysqldump备份的数据中没有关于数据库本身的操作,都是针对表级别的擦欧总:当进行数据(sql还原),必须指定数据库

利用mysql.exe客户端

  1. 利用mysql.exe客户端:没有登录之前,可以直接用改客户端进行数据还原
    mysql.exe-hPup数据库 <文件位置

    导入SQL指令

  2. 在sql指令,提供了一种导入SQL指令的方式
    source SQL 文件位置; //必须先进入对应的数据库

  3. 人为操作:打开备份文件,复制所以SQL指令,然后到mysql.exe客户端中粘贴执行(不推荐)类似第二种

本机动手操作:

D:\php\PHPTutorial\MySQL\binmysqldump.exe -uroot -proot mydatabase >C:\Users\华\Desktop\my\mydatabase.sql//CMD命令备份



drop database mydatabase;//sql指令删除了数据库mydatabase



开始还原:

create database mydatabase; //sql指令先创建数据库


D:\php\PHPTutorial\MySQL\bin\mysql.exe -uroot -proot mydatabase < C:\Users\华\Desktop\my\mydatabase.sql //cmd命令行下还原

还原成功

mysql21-子查询

Posted on 2019-02-12 | In mysql

子查询

子查询与主查询

子查询概念

子查询:sub query
子查询是一种常用计算机语言SELECT—SQL语言中嵌套查询下层的程序模块。当一个查询是另一个查询的条件时,称之为子查询
子查询:指在一条select语句中,嵌入了另外一条select语句,那么被嵌入的select语句称之为子查询语句

主查询概念

主查询:主要的查询对象,第一条select语句,确定的用户所有获取的数据目标(数据源)已经要具体得到的字段信息。

子查询和主查询的关系

  1. 子查询是嵌入到主查询中的
  2. 子查询的辅助查询:要么作为条件,要么作为数据源
  3. 子查询其实可以独立存在:是一条完整的select语句

子查询分类

按功能分

标量子查询:子查询返回的结果是一个数据(一行一列)
列子查询:返回的结果是一列(一列多行)
行子查询:返回的结果是一行(一行多列)
表子查询:返回的结果是多行多列(多行多列)
exist子查询:返回的结果是1或者0(类似布尔操作)

按位置分

where子查询:子查询出现的位置在where条件中

from子查询:子查询出现的位置在from数据源中(作数据源)

标量子查询:

概念

子查询返回的结果是一个数据(一行一列)

语法:

基本语法:select * from 数据源 where 条件判断 =/< > (select 字段名 from 数据源 where条件判断) //子查询得到的结果只有一个值

列子查询

概念

子查询得到的结果是一列数据(一列多行)

语法

基本语法
主查询 where 条件 in(列子查询);

行子查询

概念

子查询返回的结果是一行多列

行元素

行元素:字段元素是指一个字段对应的值,行元素对应的就是多个字段:多个字段合起来作为一个元素参与运算,把这种情况称之为行元素。

语法

基本语法:
主查询 where 条件【(构造一个行元素)】=(行子查询)

该语句实现了返回身高和年龄最高的学生的信息

为什么不能用 having 语句:

select *from my_student having stu_age=max(stu_age) and stu_height=max(stu_height);
原因分析:

  1. having是在group by之后:使用having代表着前面的group by执行力一次(聚合函数使用)
  2. group by一旦执行:结果就是只返回一行记录:第一行

总结:已经学过三个子查询:常见的三个子查询

标量子查询、列子查询和行子查询:都属于where子查询

表子查询

概念

表子查询:返回的结果是多行多列,表子查询与行子查询非常相似,只是行子查询需要产生行元素,而表子查询没有。

行子查询是用于where条件判断:where子查询
表子查询是用于from数据源:from子查询

语法

基本语法
select 字段表 from (表子查询)as 表名【where】【group by】【limit】

为什么要有as 别名。因为from 后面必须跟着表名,不能没有名字。同时别名也方便后面语句的操作

exists子查询

概念

exists子查询:查询返回的结果只有0或者1,1戴白哦成立,0代表不成立

语法

基本语法:where exists(查询语句); //exists就是根据拆线呢得到的结果进行判断:如果结果存在那么返回1,否则返回0

where 1:永远为真

子查询中特定关键字的使用

in

主查询 where 条件 in (列子查询)

any

任意一个
=any(列子查询):条件在查询结果中有任意一个匹配即可,等价于in

<>any(列子查询):条件在查询结果中只要不等于其中一个即为true(即不全等)

例如:
1 =any(1,2,3)====true
1 <>any(1,2,3)====true

some

与any完全一样:在国外some与any的正面含义一致,但是否定就大不相同:not any与not some含义不同
开发者为了让对应的使用者不要在语法上纠结:重新设计了some

all

全部:等于里面的全部
=all(列子查询):表示等于里面的所有
<>all(列子查询):不等于其中所有

由于my_class中班级存在3与my_student的班级1和2都不相同,于是修改语句:

如果对应的匹配字段有NULL,那么不参与匹配

mysql20-连接查询

Posted on 2019-02-12 | In mysql

连接查询

连接查询:将多张表连到一起进行查询(会导致记录数行和字段数列发生改变)

连接查询的意义

在关系型数据库设计过程中,实体(表)与实体之间是存在很多联系的。在关系型数据库表的设计过程中,遵循着关系来设计:一对一,一对多和多对多,通常在实际操作的过程中,需要利用这层关系来保证数据的完整性

连接查询的分类

交叉连接

交叉连接:将两张表的数据与另外一张表批次交叉

原理

  1. 从第一张表一次取出一条记录
  2. 去除每一条记录只会,与另外一张表的全部记录挨个匹配
  3. 没有任何匹配条件,所有的结果都会进行保留
  4. 记录数=第一张表记录数*第二张表记录数;字段数=第一张表字段数+第二张表字段数

    语法

    基本语法:表1 cross join 表2;

应用

交叉连接产生的结果是笛卡尔集,没有实际应用。
保障连接查询的完整型
本质 from 表1,表2; 结果一样

内连接

内连接:inner join,从一张表中取出所有的记录去另外一张表中匹配:利用匹配条件进行匹配,成功了则保留,失败了放弃

原理

  1. 从第一张表中取出一条记录,然后去另外一张表中进行匹配
  2. 利用匹配条件进行匹配
    2.1匹配到:保留,继续向下匹配
    2.2匹配失败:向下继续,如果全表匹配失败,结束

语法

基本语法:表1【inner】join 表2 on 匹配条件

  1. 如果内连接没有条件,那么其实就是交叉连接(避免)
  2. 使用匹配条件进行匹配
  3. 因为表的设计通常容易产生同名字段,尤其是id,所以为了避免重名出现错误,通常使用表名.字段名,来确保唯一性

    4.通常,如果条件中使用到对应的表名,可以使用表别名进行简化

    5内连接匹配的时候必须保证匹配到才保存

    6.内连接因为不强制必须使用匹配条件(on)因此可以在数据匹配完成之后,使用where条件来限制,效果与on一样。(但建议使用on:where等于先全部匹配后再筛选)

    应用

    内连接通常是在对数据有精确要求的地方使用:必须保证两种表中都能进行数据匹配。

外连接

左外连接(左连接)和右外连接(右连接)
外连接:outer join,按照某一张表作为主表(表中所以记录在最后都会保留),根据条件去连接另外一张表,从而得到目标数据

外连接分为两种:左连接(left join),右外连接(right join)

左连接:左表是主表

右连接:右表是主表

原理

  1. 确定连接主表:左连接就是left join 左边的表为主表,right join就是右边为主表
  2. 拿主表的每一条记录去匹配另外一张表(从表)的每一条记录
  3. 如果满足匹配条件:保留;不满足则不保留
  4. 如果主表记录在从表中一条都没有匹配成功,那么也要保留该记录:从表对应的字段值都为NULL

    语法

    基本语法:
    左连接:主表 left join 从表 on 连接条件;
    右连接:从表 right join 主表 on 连接条件

左连接对应的主表数据在左边;右连接对应的主表数据在右边

特点:

  1. 外连接中主表数据记录一定会保存:连接之后不会出现记录数少于主表(内连接可能)
  2. 左连接和右连接可以互相转换(主表不变即可),但是数据对应的位置(表顺序)会改变

    应用

    非常常用的一种获取的数据方式:作为数据获取对应主表以及其他数据(关联)


自然连接


using关键字

是在连接查询中用来代替对应的on关键字,进行条件匹配

原理

  1. 在连接查询时,使用on的地方用using代替
  2. 使用using的前提是对应的两张表连接的字段是同名(类似自然连接自动匹配)
  3. 如果使用using关键字,那么对应的同名字段,最终在结果中只会保留一个

语法

基本语法:表1 【inner,left,right】join 表2 using(同名字段列表) //连接字段

mysql19-联合查询

Posted on 2019-02-07 | Edited on 2019-02-08 | In mysql

联合查询

基本概念:

联合查询时可合并多个相似的选择查询的结果集。等同于将一个表追加到另一个表,从而实现将两个表的查询组合到一起,使用谓词为UNION或UNION ALL

联合查询:将多个查询的结果合并到一起(纵向合并):字段数不变,多个查询的记录数合并。

应用场景

  1. 将同一张表中不同的结果(需要对应多条查询语句来实现),合并到一起展示数据
  2. 最常见:在数据量大的情况下,会对表进行分表操作,需要对每张表进行部分数据统计,使用联合查询来将数据存放到一起显示。

基本语法

基本语法:
select 语句
union 【union选项】
select 语句

union选项:与select选项基本一样
distinct:去重,去掉完全重复的数据(默认的)

all:保存所有的结果

注意细节:union理论上只要保证字段数一样,不需要每次拿到的数据对应的字段类型一致。永远只保留第一个select语句对应的字段名

order by的使用

1.
在联合查询中,如果要使用order by,那么对应的select语句必须使用括号括起来

正确的语法要加上括号

2.
order by在联合查询中若想要生效,必须配合使用limit:而limit 必须跟对应的限制数量(通常可以使用一个较大的值:大于对应表的记录数)

mysql18-高级操作之查询中的运算符

Posted on 2019-02-06 | Edited on 2019-02-07 | In mysql

高级操作–查询中的运算符

算术运算符

+ - * / %

基本算术预算:通常不再条件中使用,而是用于结果运算(select字段中)

比较运算符

, >=, <, <=, =, <>(不等于)
通常是用来在条件中进行限定结果
=:在mysql中,没有对应的==比较符号,就是用=进行相等判断
<=> :相等比较

特殊应用:就是在字段结果中进行比较运算
注:mysql中没有规定select必须有数据表

在条件判断的时候,还会有对应的比较运算符:计算区间
between 条件1 and 条件2

between中条件1必须小于条件2,反过来不可以

逻辑运算符

and、or、not
and:逻辑与

or:逻辑或


not:逻辑非

in预算符

in:在什么里面,是用来代替=,当结果不是一个值,而是一个结果集的时候
基本语法: in(结果1,结果2,。。。)只要当前条件在结果集中出现过 ,就成立

is运算符

is是专门用来判断字段是否为NULL的运算符
基本语法:is null/is not null

like运算符

like运算符:是用来进行模糊匹配的(匹配字符串)
基本语法:like‘匹配模式’

匹配模式中,有两种占位符
_:匹配对应的单个字符
%:匹配多个字符

mysql17-高级操作之查询

Posted on 2019-02-06 | In mysql

查询数据

完整查询指令
select select选项 字段列表 from 数据源 where 条件 group by 分组 having 条件俺 order by 排序 limit 限制

select选项:系统如何对待查询得到的结果
all:默认的,表示保存所有的记录

distinct:去重,去除重复的记录,只保留一条(所有字段都相同)

字段列表:有的时候需要从多张表获取数据,在获取数据的时候,可能存在不同表中有同名的字段,需要将同名的字段命名成不同名的: 别名 alias

基本语法 字段列表【as 】别名
一个字段可以取两个别名

如图,显示两个别名

from数据源

from是为前面的查询提供数据:数据源只要是一个复合二维表结构的数据即可。

单表数据

from 表名

多变数据

从多张表获取数据:基本语法:from 表1,表2,。。。

结果:两张表的记录数相乘,字段数拼接
本质:从第一张表去除一条记录,取拼凑第二张表的所有记录,保留所有结果
在数学上有一个专业的说法:笛卡儿积,这个结果除了给数据库造成压力,没有其他意义:应该尽量避免出现笛卡儿积

动态数据

from 后面跟的数据,不是一个实体表,而是一个从表中查询出来得到的二维结果表(子查询)
基本语法:from (select 字段列表 from 表名)as 别名;

where子句

where 字句:用来从数据表获取数据的时候,然后进行条件筛选

数据获取原理:针对表去对应的磁盘处获取所有的记录(一条条获取),where的作用就是在拿到一条结果就开始进行判断,判断是否符合条件,如果符合条件就保存下来,如果不符合直接舍弃(不放到内存中)

where是通过运算符进行结果比较来判断数据

group by 子句

group by 表示分组的含义:根据指定的字段s,将数据进行分组:分组的目标是为了分组统计

分组统计:

基本语法:group by 字段名

group by 是为了分组后进行数据统计的,如果只是想看数据显示,那么group by 没什么意义:group by 将数据按照指定的字段分组之后,只会保留每组的第一条记录

利用统计函数(聚合函数 ):

count():统计每组中的数量,如果统计的目标是字段,那么不统计为空NULL字段,如果为* 代表统计记录
avg():求平均值
sum():求和
max():求最大值
min():求最小值

如果不加group表示在全表范围下统计


group_concat():为了将分组中指定的字段进行合并(拼接)

多分组

将数据按照某个字段进行分组之后,对已经分组的数据进行再次分组

基本语法:group by字段1,字段2 // 先按照字段1进行排序,之后将结果再按照字段2进行排序,依次类推

分组排序

mysql中分组默认有排序的意义:按照分组字段进行排序,默认是升序
基本语法 group by 字段【asc或者desc】, 字段【asc或者desc】

回溯统计

当分组进行多分组之后,往上统计的过程中,需要进行层层上报,将这种层层上报统计的过程称之为回溯统计:每一次分组向上统计的过程都会产生一次新的统计数据,而且当前数据对应的分组字段为NULL

基本语法:group by 字段 [asc或者desc] with rollup

多分组回溯统计

having子句

having 的本质和where一样,是用来进行数据条件筛选
1.having是在group by 子句之后:可以针对分组数据进行统计筛选,但是where不行
查询班级人数大于四个的班级

where不能使用聚合函数:聚合函数是用在group by分组的时候,此时where已经运行完毕。where是从表中取数据,别名是在数据进入到内存之后才有的



having在group by 分组之后,可以使用聚合函数或者字段别名

强调:having是在group by之后,group by 是在where之后,where的时候表示将数据从磁盘拿到内存,where之后的所有操作都是内存操作

order by 子句

order by排序:根据校对规则对数据进行排序
基本语法:order by 字段【asc或者desc】 默认asc升序

order by可以像group by 一样进行多字段排序:先按照第一个字段进行排序,然后再按照第二个字段进行排序。
基本语法:order by 字段1 规则1,字段2 规则2;

limit 子句

limit限制子句:主要是用来限制记录数量获取

记录数限制

纯粹的限制获取数量:从第一条到指定的数量,
基本语法:limit 数量

limit通常再查询的时候如果限定为1条记录的时候,使用的比较多:有时候获取多条记录并不能解决业务问题,但是会增加服务器的压力

分页

利用limit来限制获取指定区间的数据
基本语法 limit offset,length; //offset偏移量:从哪里开始,length就是具体的获取多少条记录
MySQL中记录的数量从0开始,limit 0,2表示获取前两条记录

注意:limit 后面的length表示最多获取对应数量,但是如果不够,系统不会强求

聚合函数

count():统计每组中的数量,如果统计的目标是字段,那么不统计为空NULL字段,如果为* 代表统计记录
avg():求平均值
sum():求和
max():求最大值
min():求最小值
在上面group by子句中已有介绍,不再赘述

mysql16-高级操作之新增、更新、删除

Posted on 2019-02-06 | In mysql

新增数据

多数据插入

只要写一次insert指令,但是可以直接插入多条记录
基本语法:insert into 表名[(字段列表)]values (值列表),(值列表)…;

主键冲突

主键冲突:在有的表中,使用的是业务主键(字段有业务含义比如学生ID),但是往往在进行数据插入的时候,又不确定数据表中是否已经存在对应的主键

主键冲突的解决方案

  1. 主键冲突更新
    类似插入数据语法,如果插入的过程中主键冲突,那么采用更新方法。
    insert into 表名[(字段列表)]values (值列表) on duplicate key update 字段=新值
  2. 主键冲突替换
    当主键冲突之后,干掉原来的数据,重新插入进去
    replace into [(字段列表)]values (值列表);

    蠕虫复制

    蠕虫复制:一分为二,成倍的增加。从已有的数据中获取数据,并且将获取的数据插入到数据表中。

    基本语法
    insert into 表名 【(字段列表)】select */字段表名 from 表名

注意:

  1. 蠕虫复制的确通常是重复数据,没有太大业务意义:可以在短期内快速增加表的数据量,从而可以测试表的压力,还可以通过大量数据来测试表的效率(索引)
  2. 蠕虫复制虽好,但是要注意主键冲突。
  3. 配合 复制已有表机构语句 就可以完成表的复制
    复制已有表机构语句:从已经存在 表赋值一份(只复制结构:如果表中有数据不复制)create table 新表名 like 表名 //只要使用数据库.表名,就可以在任意数据库下访问其他数据库表

更新数据

  1. 在更新数据的时候,特别要注意:通常一定是跟随条件更新的
    update 表名 set 字段名 =新值 where 判断条件

如果没有条件,是全表更新数据。但是可以使用limit来显示更新的数量;
update 表名 set 字段名=新值【where 判断条件】limit 数量

例如:改变4个a变成e
update my_simple set name=’e’ where name=’a’ limit 4

删除数据

  1. 删除数据的时候尽量不要全部删除,应该使用where进行判定
  2. 删除的时候可以使用limit来限制要删除的具体数量

delete删除数据的时候无法重置auto_increment

mysql有一个能够重置表选项中的自增长的语法
truncate 表名;等价于 ->drop ->create

1…567…9

lh

89 posts
12 categories
© 2020 lh
Powered by Hexo v3.8.0
|
Theme – NexT.Pisces v6.7.0