今天盯上了我的“MySQL”收藏夹,打开一看,总共有18篇。简单筛选了一下,有15篇将会在这篇做出选择。
来吧!!!
MySQL入门之旅
今天初面腾讯,发现MySQL是很重要的。
高性能MySQL系列,虽然停更了,但是等这波忙完之后还是要续更的!
事务控制今天面试的时候被问到了,由于之前写了“高性能MySQL”那个系列,所以答上来了。但是这个锁定语句,其实不是不知道,但是好像真的,忘记了。
所以,再写一下。
MySQL 的锁定语句主要有两个 Lock 和 unLock,Lock Tables 可用于锁定当前线程的表,如果表锁定,意味着其他线程不能再操作表,直到锁定被释放为止。
lock table test read;
上了读锁,这时候有什么不一样的地方呢?从此对于别的线程来说,增删查改里面只能查了。
那么他们的操作会这么样呢?会被阻塞。直到这把锁被撤销掉。
unlock tables;
系统的看一下这些锁吧。
NoBlock(不加锁):不加锁就是不加锁了嘛。
HoldLock(保持锁):
SELECT * FROM table WITH (HOLDLOCK)
其他事务可以读取表,但不能更新删除
SELECT * FROM myTable WITH (UPDLOCK) WHERE Id in (1,2,3)
有时候需要控制某条记录在我读取后就不许再进行更新,那么我就可以将所有要处理当前记录的查询都加上更新锁,以防止查询后被其它事务修改。将事务的影响降低到最小。
TABLOCK(表锁)
此选项被选中时,SQL Server 将在整个表上置共享锁直至该命令结束。
注意,上面那个是行级锁。
TABLOCKX(排它表锁)
此选项被选中时,SQL Server 将在整个表上置排它锁直至该命令或事务结束。这将防止其他进程读取或修改表中的数据。
好,那你要是哪天把表锁上了,然后忘了解锁,怎么搞?
不慌啊:
show OPEN TABLES where In_use > 0;
show status like 'table%';
Table_locks_immediate 指的是能够立即获得表级锁的次数
Table_locks_waited 指的是不能立即获取表级锁而需要等待的次数,值比较高,则说明存在着较严重的表级锁争用情况。
show status like 'innodb_row_lock%';
如果发现锁争用比较严重,如InnoDB_row_lock_waits和InnoDB_row_lock_time_avg的值比较高
show processlist;
kill 123;
解锁之后,那些被阻塞的任务就继续往下走了。
(默认是自动提交的)
在自动提交的模式下,每个 SQL 语句都会当作一个事务执行提交操作。
如果需要手动 commit 和 rollback 的话,就需要明确的事务控制语句了:
start transaction;
... # 一条或者多条语句
commit; # 或者 rollback
糟糕,腰酸背痛,歇了歇了。
SQL 注入就是利用某些数据库的外部接口将用户数据插入到实际的 SQL 中,从而达到入侵数据库的目的。SQL 注入是一种常见的网络攻击的方式,它不是利用操作系统的 BUG 来实现攻击的。SQL 主要是针对程序员编写时的疏忽来入侵的。
1 web 开发人员无法保证所有的输入都已经过滤
2 攻击者利用发送给服务器的输入参数构造可执行的 SQL 代码(可加入到 get 请求、 post 请求、 http 头信息、 cookie 中)
3 数据库未做相应的安全配置
在浏览器地址栏输入:
learn.me/me/sql/article.php?id = 1
这是一个 get 型接口,发送这个请求相当于调用一个查询语句
$ sql = SELECT * from article where id= $ id
正常情况下,应该返回一个 id = 1 的文章信息。那么,如果在浏览器地址栏输入:
learn.me/me/sql/article.php?id = -1 or 1=1
这就是一个 SQL 注入攻击,可能会返回所有文章的相关倍息。为什么会这样呢?这是因为, id = 1 永远是 false , 1 = 1 永远是 true ,所有整个 where 语句永远是 ture ,所以 where 条件相当于没有加 where 条件,那么查询的结果相当于致张表的内容
有这样一个用户登录场景:登录界面包括用户名和密码输入框,以及提交按钮.输入用户名和密码,提交。这是一个post请求,登录时调用接口。
首先连接数据库,然后后台对 post 请求参数中携带的用户名、密码进行参数校验,即 sql 的查询过程.假设正确的用户名和密码为 user 和 pwdl23 ,输入正确的用户名和密码、提交,相当于调用了以下的 SQL 语句:
SELECT * FROM user where usernanme= 'user' ADN password = 'pwd123'
由于用户名和密码都是字符串, SQL 注入方法即把参数携带的数据变成 mysql 中注释的字符串。 mysql 中有 2 种注释的方法
1.’ # ’ : ’ # ’后所有的字符串都会被当成注释来处理
用户名输入: user’# (单引号闭合 user的单引号),密码随意输入,如: 111 ,然后点击提交按钮.等价于 SQL 语句:
SELECT * from username WHERE username= 'user'# ADN password =' 111 '
要知道#后面都被注释掉了,相当于:
SELECT * from username WHERE username= 'user'
SELECT * from username WHERE username= 'user'-- ADN password =' 111 '
和上面情况一样。
因此,以上两种情况可能输入一个错误的密码或者不输入密码就可登录用户名为user 的账号,这是十分危险的事倩。
1 )严格检查输入变量的类型和格式对于整数参数,加判断条件:不能为空、参数类型必须为数字
对于字符串参数,可以使用正则表达式进行过滤:如:必须为[0-9] [a-z] [A-Z]范围内的字符串
2 )过滤和转义特殊字符在 username 这个变量前进行转义,对’、"、等特殊字符进行转义
3 )利用 mysql 的预编译机制
本部分仅供查询参考,如果不会具体使用的话,请拿着函数名百度一下。
MySQL题集
LeetCode MySQL解题目录
免费教程《图解SQL面试题》
Oracle从小白到大牛的刷题之路(建议收藏学习)
注意:操作完一个数据库一定要把数据库连接关闭,不然 mysql 会以为一直连接的同一个数据库
MySQL教程(满足80%的程序员实用):
这个是我从CSDN程序员学院中,找到的应该算是最适合大众程序员学习的MySQL教程了,包含了80%程序员日常开发中需要使用的MySQL技术。不多说了,扫码一看便知。
相关教程传送门:MySQL数据库从入门到实战课