一 coalesce
-- Return 1
SELECT COALESCE(NULL, NULL, NULL, NULL);
-- Return NULL
这个参数使用的场合为:假如某个字段默认是null,你想其返回的不是null,而是比如0或其他值,可以使用这个函数
SELECT COALESCE(field_name,0) as value from table;
二 mysql dump shell
#!/bin/bash dump_sql='mysqldump -hxxx.xxx.com -P3316 -uuser_r -ppassword db' config_where=" --where" config="--no-create-info --complete-insert --single-transaction --default-character-set=utf8mb4" qadmin_user_file=qadmin_user.txt qadmin_user_org_file=qadmin_user_org.txt tmp1_file=tmp1.txt tmp2_file=tmp2.txt ${dump_sql} qadmin_user ${config_where} "1 = 1" ${config} >> ./${tmp1_file} cat ${tmp1_file} | grep 'INSERT INTO' | sed 's/),(/), (/g' >> ./${qadmin_user_file} ${dump_sql} qadmin_user_org ${config_where} "1 = 1" ${config} >> ./${tmp2_file} cat ${tmp2_file} | grep 'INSERT INTO' | sed 's/),(/), (/g' >> ./${qadmin_user_org_file} rm ${tmp1_file} rm ${tmp2_file}
三. grant all privileges on
遇到了 SQLException: access denied for @'localhost' (using password: no)
解决办法 grant all privileges on *.* to joe@localhost identified by '1';
flush privileges;
拿 joe 1 登陆
MySQL> grant 权限1,权限2,…权限n on 数据库名称.表名称 to 用户名@用户地址 identified by ‘连接口令’;
权限1,权限2,…权限n代表select,insert,update,delete,create,drop,index,alter,grant,references,reload,shutdown,process,file等14个权限。
当权限1,权限2,…权限n被all privileges或者all代替,表示赋予用户全部权限。
当数据库名称.表名称被*.*代替,表示赋予用户操作服务器上所有数据库所有表的权限。
用户地址可以是localhost,也可以是ip地址、机器名字、域名。也可以用’%'表示从任何地址连接。
‘连接口令’不能为空,否则创建失败。
mysql>grant select,insert,update,delete,create,drop on vtdc.employee to joe@10.163.225.87 identified by ‘123′;
给来自10.163.225.87的用户joe分配可对数据库vtdc的employee表进行select,insert,update,delete,create,drop等操作的权限,并设定口令为123。
四 mysql中不能插入中文
(1)#vim /etc/mysql/my.cnf 。(5.5以前系统)在【client】下面加入 default-character-set=utf8
在【mysqld】下面加入default-character-set=utf8
Notice:注意 如果修改后不能启动报错试试把default-character-set=utf8改为character_set_server=utf8,仅仅加入到mysqld下面的.client就不需要加了
(2)#vim /etc/mysql/my.cnf 。(5.5以后系统)如下修改:
[client]
default-character-set=utf8
[mysqld]
default-storage-engine=INNODB
character-set-server=utf8
collation-server=utf8_general_ci
五、重启mysql(/etc/init.d/mysql stop /etc/init.d/mysql start) service mysql restart
六、修成成功,进入mysql查看字符集(mysql>show variables like ‘character_set_%’;)
五 mybatis中的 ${} 和 #{} 有什么区别
动态sql时mybatis的强大特性之一,也是它优于其他orm框架的一个重要原因。mybatis在对sql语句进行预编译之前,会对sql进行动态解析,解析为一个BoundSql对象,也是在此处对动态sql进行处理的。在动态sql解析阶段, #{}和${} 会有不同的表现
(1) #{}
select * from user where name = #{name};
#{} 在动态解析的时候, 会解析成一个参数标记符。就是解析之后的语句是:
select * from user where name = ?;
(2) ${}
select * from user where name = ${name};
${}在动态解析的时候,会将我们传入的参数当做String字符串填充到我们的语句中,就会变成下面的语句
select * from user where name = "zhangsan";
预编译之前的 SQL 语句已经不包含变量了,完全已经是常量数据了。相当于我们普通没有变量的sql了。
综上${} 变量的替换阶段实在动态sql解析阶段,而#{} 变量的替换是在dbms中,#方式能够很大程度防止sql注入,一般而言能用#就别用$
六 数据库三范式
1 第一范式1NF
在任何一个关系数据库中,1NF是对关系模型的基本要求,不满足1NF的数据库就不是关系数据库。所谓1NF是指数据库表的每一列都是不可分割的基本数据项,同一列不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。简而言之,1NF就是无重复的列
2 第二范式2NF
满足2NF的前提是满足1NF,2NF要求数据库表中的每个实例或行必须可以被唯一地区分,为实现这个通常需要为表加上一个列,以存储各个实例的唯一标识。这个唯一标识被称为主关键字或主键。2NF要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性。如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。简而言之,2NF就是非主属性非部分依赖于主关键字。
3 第三范式3NF
满足3NF的前提是满足2NF,3NF要求一个数据库表中不包含已在其他表中包含的非关键字信息。例如,有一个部门信息表(部门编号,部门名称,部门简介),那么在员工信息表中列出部门编号后就不能再将部门名称,部门简介等于部门有关的信息再加入员工信息表中。如果不存在部门信息表,则根据3NF也应该构建它,否则就会有大量的数据冗余。简而言之,3NF就是属性不依赖于其他非主属性。
七 数据库连接池配置
<jdbc name="server1" url="jdbc:mysql://xxxxx:xxxx/?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull" username="xxxxxxx" password="xxxxxxxx" driverClassName="com.mysql.jdbc.Driver" removeAbandoned="true" removeAbandonedTimeout="600" logAbandoned="true" maxWait="500" minIdle="100" maxIdle="200" initialSize="100" maxActive="200" testOnBorrow="true" testWhileIdle="true" timeBetweenEvictionRunsMillis="5000" minEvictableIdleTimeMillis="60000" validationQuery="select 1"/>
我们来看一下各个参数的含义:
maxActive="100": 并发情况下最大连接数。通过设置maxActive参数可以避免某个应用无限制地获取连接
maxIdle="30": 例如并发时最大线程数达到了100(maxActive="100"),那么连接池就必须从数据库获得100个连接来供应用程序使用。当应用程序关闭连接后,例如maxIdle为30的话,那么并不是所有的连接都会归还给数据库,将会有30个连接保持在连接池中,状态为空闲。设0为无限制
minIdle="2": 最小默认情况下并不生效,它的含义是当连接池中的连接少于minIdle,系统监控线程将启动补充功能,一般情况下我们并不启动补充线程。
removeAbandoned="true":如果说从连接池中获得连接使用后忘了关闭,这样连接池的连接就会逐渐达到maxActive直至连接池无法提供服务,而进行了这个设置的话当连接池连接数达到一定时便会启动连接回收
removeAbandonedTimeout="60": 活动时间超过60s的会被回收
logAbandoned="true" 回收连接的同时会打印日志
maxWait: 最大等待毫秒数,单位是ms,超过时间会出错误信息
initialSize: 连接池启动时创建的初始化连接数量(默认值为0)
testOnBorrow: 取得对象时是否进行验证,默认为false即不验证
testWhileIdle: 空闲时是否进行验证,默认为false即不验证(当使用dbcp时,数据库连接因为某种原因断掉后,再从连接池中取得连接又不进行验证,这是的连接实际是无效的数据库连接,很多网上的badcase分析也都是这个dbcp的bug导致。只要把这些属性设为true, 再提供validationQuery语句就可以保证数据库连接始终有效了)
八 重复记录相关查询的实战
1 查找表中多余的重复记录,重复记录是根据单个字段peopleId来判断
select * from people where peopleId in (select peopleId from people group by peopleId having count(peopleId) > 1)
2 删除表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断,只留有rowid最小的记录
delete from people where peopleId in (select peopleId from people group by peopleId having count(peopleId) > 1) and rowid not in (select min(rowid) from people group by peopleId having count(peopleId )>1)
3 查找表中多余的重复记录(多个字段)
select * from vitae a where (a.peopleId, a.seq) in (select peopleId, seq from vitae group by peopleId, seq having count(*) > 1)
4 删除表中多余的重复记录(多个字段),只留有rowId最小的记录
delete from vitae a where (a.peopleId,a.seq) in (select peopleId,seq from vitae group by peopleId,seq having count(*) > 1) and rowid not in (select min(rowid) from vitae group by peopleId,seq having count(*)>1)
5 查找表中多余的重复记录(多个字段),不包含rowid最小的记录
select * from vitae a where (a.peopleId,a.seq) in (select peopleId,seq from vitae group by peopleId,seq having count(*) > 1) and rowid not in (select min(rowid) from vitae group by peopleId,seq having count(*)>1)