Shepard's Blog

Nothing is true everything is permitted


  • 首页

  • 标签

  • 分类

  • 归档

  • 公益404

  • 搜索

MongoDB配置及部分命令

发表于 2015-05-06 | 分类于 Database , MongoDB |

MongoDB安装

第一节 MongoDB介绍及下载与安装

至官网下载了压缩包后解压至任意目录,然后在目录下建立data文件夹,并在data文件夹下建立db与log两个文件夹,db文件夹用来存放数据存储文件,log文件夹用来存放日志文件。在log文件夹下建立默认的日志危机,如MongoDB.log。
这里采用注册为系统服务的方式安装。在命令行cmd中cd到mongodb目录下,运行

1
mongod --dbpath "C:\mongodb\data\db" --logpath "C:\mongodb\data\log\MongoDB.log" --install --serviceName "MongoDB"

命令即可注册名为MongoDB的服务,如果成功,可以通过net start MongoDB启动服务。
点击bin目录下的mongo.exe打开数据库可以测试一下有无成功

还可以直接通过相关程序来运行,在命令行中输入以下命令

1
mongod -dbpath "C:\mongodb\data\db"

执行此命令即将mongodb的数据库文件创建到C:\mongodb\data\db目录,关闭的华可以直接双机mongod.exe

–fork 以守护进程方式运行MongoDB,创建服务器进程

1
mongod --port 10220 --fork  --dbpath "C:\mongodb\data\db" --logpath "C:\mongodb\data\log\MongoDB.log"

如果需要停止mongodb,直接关闭的话可能会造成数据丢失,稳妥的方式为

1
2
user admin
db.shutdownServer();


MongoDB相关命令

MongoDB基本命令用

help: 显示帮助命令
show dbs: 显示所有数据库
show collections: 显示当前数据库所有集合(类似表)
show users: 显示所有用户
show logs: 显示所有日志名
show log [name]: 根据日志名输出日志到控制台

use <db_name>: 切换数据库
db.foo.find(): 查询集合foo的所有数据
db.cloneDatabase("127.0.0.1"): 将指定机器上的数据库的数据克隆到当前数据库
db.copyDatabase("mydb", "temp", "127.0.0.1"): 将本机的mydb的数据复制到temp数据库中
db.repairDatabase(): 修复当前数据库
db.getName(): 查看当前使用的数据库
db.stats(): 查看当前数据库状态
db.version(): 查看当前数据库版本
db.getMongo(): 查看当前db的主机地址

db.auth("username","password"): 数据库安全认证
db.addUser("username"): 添加新用户
db.addUser("username", "password", true): 最后一个参数为只读选项
db.removeUser("username"): 删除用户

db.createCollection("collName", {size: 20, capped: 5, max: 100}): 创建一个聚集集合
db.getCollection("collName"): 得到指定名称的聚集集合
db.getCollectionNames(): 得到当前db的所有聚集集合
db.printCollectionStats(): 显示当前db所有聚集索引的状态
db.foo.renameCollection("newCollName"): 集合重命名
db.foo.dataSize(): 查看数据空间大小
db.foo.stats(): 查看集合状态
db.userInfo.totalSize(): 查看集合总大小
db.userInfo.storageSize(): 查看集合存储空间大小

db.getPrevError(): 查询之前的错误信息
db.resetError(): 清除错误记录

Redis 相关配置

发表于 2015-05-06 | 分类于 Database , Redis |

redis windows下的环境搭建
可靠的Windows版Redis
Windows版下载地址

将下载的压缩包解压到任意目录下,通过命令行工具进入到相关目录下,直接输入命令

1
redis-server.exe redis.windows.conf

即可启动redis服务器,其中后面的redis.windows.conf为配置文件,可选输入
然后令开一个命令行进入相关目录下,输入命令

1
redis-cli.exe -h 127.0.0.1 -p 6379

指定主机名以及端口即可进入redis客户端
redis.windows.conf配置文件的主要配置:

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# 包含其他的配置文件,可以使用相对路径及绝对路径
include .\path\to\local.conf

# 端口号,默认6379
port 6379

# 绑定主机地址
bind 127.0.0.1

# 当客户端闲置多长时间后关闭连接,默认为0,即禁用此功能
timeout 0

# 指定日志记录级别,四个级别:debug、verbose、notice、warning
loglevel notice

# 指定日志输出文件,stdout为输出到控制台
logfile ""

# 设置数据库的数量
database 16

# 指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合
# 900秒(15分钟)内有1个更改
save 900 1
# 300秒(5分钟)内有10个更改
save 300 10
# 60秒内有10000个更改
save 60 10000

# 指定存储至本地数据库时是否压缩数据,默认为yes,Redis采用LZF压缩,
# 如果为了节省CPU时间,可以关闭该选项,但会导致数据库文件变的巨大
rdbcompression yes

# 指定本地数据库文件名,默认值为dump.rdb
dbfilename dump.rdb

# 指定本地数据库存放目录
dir ./

# 设置当本机为slav服务时,设置master服务的IP地址及端口,在Redis启动时,它会自动从master进行数据同步
slaveof <masterip> <masterport>

# 当master服务设置了密码保护时,slav服务连接master的密码
masterauth <master-password>

# 设置Redis连接密码,如果配置了连接密码,客户端在连接Redis时需要通过AUTH <password>命令提供密码,默认关闭
requirepass foobared

# 设置同一时间最大客户端连接数,默认无限制,
# Redis可以同时打开的客户端连接数为Redis进程可以打开的最大文件描述符数,如果设置 maxclients 0,表示不作限制。
# 当客户端连接数到达限制时,Redis会关闭新的连接并向客户端返回max number of clients reached错误信息
maxclients 10000

# 指定最大heap字节数
maxheap <bytes>

# 指定Redis最大内存限制,
# Redis在启动时会把数据加载到内存中,达到最大内存后,Redis会先尝试清除已到期或即将到期的Key,
# 当此方法处理后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作
maxmemory <bytes>

# 指定是否在每次更新操作后进行日志记录,
# Redis在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。
# 因为 redis本身同步数据文件是按上面save条件来同步的,所以有的数据会在一段时间内只存在于内存中。默认为no
appendonly no

# 指定更新日志条件,共有3个可选值:
# no:表示等操作系统进行数据缓存同步到磁盘(快)
# always:表示每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全)
# everysec:表示每秒同步一次(折衷,默认值)
appendfsync everysec

# 指定Redis内存映射文件(memory mapped file)存放的路径 默认在系统盘,会占用很大的空间,关闭redis后自动删除
heapdir <directory path(absolute or relative)>


redis 常用命令

Redis常用命令

进入redis目录在命令行输入redis-cli即可启动redis客户端,前提是已经打开了redis-server服务器,--help参数可以查看redis-cli支持的参数

  • 连接操作命令
    quit:关闭连接(connection)
    auth:简单密码认证
    help cmd: 查看cmd帮助,例如:help get

  • 持久化
    save:将数据同步保存到磁盘
    bgsave:将数据异步保存到磁盘
    lastsave:返回上次成功将数据保存到磁盘的Unix时戳
    shundown:将数据同步保存到磁盘,然后关闭服务

  • 远程服务控制
    info:提供服务器的信息和统计
    monitor:实时转储收到的请求
    slaveof:改变复制策略设置
    config:在运行时配置Redis服务器

  • 清空数据库
    flushdb: 清除当前数据库的所有keys
    flushall: 清除所有数据库的所有keys

  • 对value操作的命令
    exists key:确认一个key是否存在
    del key:删除一个key
    type key:返回值的类型
    keys pattern:返回满足给定pattern的所有key,*为所有key
    randomkey:随机返回key空间的一个
    keyrename oldname newname:重命名key
    dbsize:返回当前数据库中key的数目
    expire:设定一个key的活动时间(s)
    ttl:获得一个key的活动时间
    select index:按索引查询
    move key dbindex:移动当前数据库中的key到dbindex数据库
    flushdb:删除当前选择数据库中的所有key
    flushall:删除所有数据库中的所有key

  • 对String操作的命令
    set key value:给数据库中名称为key的string赋予值value
    get key:返回数据库中名称为key的string的value
    getset key value:给名称为key的string赋予上一次的value
    mget key1 key2 … key N:返回库中多个string的value
    setnx key value:添加string,名称为key,值为value
    setex key time value:向库中添加string,设定过期时间time
    mset key N value N:批量设置多个string的值
    msetnx key N value N:如果所有名称为key i的string都不存在
    incr key:名称为key的string增1操作
    incrby key integer:名称为key的string增加integer
    decr key:名称为key的string减1操作
    decrby key integer:名称为key的string减少integer
    append key value:名称为key的string的值附加value
    substr key start end:返回名称为key的string的value的子串

  • 对List操作的命令
    rpush key value:在名称为key的list尾添加一个值为value的元素
    lpush key value:在名称为key的list头添加一个值为value的 元素
    llen key:返回名称为key的list的长度
    lrange key start end:返回名称为key的list中start至end之间的元素
    ltrim key start end:截取名称为key的list
    lindex key index:返回名称为key的list中index位置的元素
    lset key index value:给名称为key的list中index位置的元素赋值
    lrem key count value:删除count个key的list中值为value的元素
    lpop key:返回并删除名称为key的list中的首元素
    rpop key:返回并删除名称为key的list中的尾元素
    blpop key1 key2 … key N timeout:lpop命令的block版本。?
    brpop key1 key2 … key N timeout:rpop的block版本。?
    rpoplpush srckey dstkey:返回并删除名称为srckey的list的尾元素,并将该元素添加到名称为dstkey的list的头部

  • 对Set操作的命令
    sadd key member:向名称为key的set中添加元素member
    srem key member:删除名称为key的set中的元素member
    spop key:随机返回并删除名称为key的set中一个元素
    smove srckey dstkey member:移到集合元素
    scard key:返回名称为key的set的基数
    sismember key member:member是否是名称为key的set的元素
    sinter key1 key2 … key N:求交集
    sinterstore dstkey, [keys] :求交集并将交集保存到dstkey的集合
    sunion key1, [keys] :求并集
    sunionstore dstkey, [keys] :求并集并将并集保存到dstkey的集合
    sdiff key1, [keys]:求差集
    sdiffstore dstkey, [keys]:求差集并将差集保存到dstkey的集合
    smembers key:返回名称为key的set的所有元素
    srandmember key:随机返回名称为key的set的一个元素

  • 对Hash操作的命令
    hset key field value:向名称为key的hash中添加元素field
    hget key field:返回名称为key的hash中field对应的value
    hmget key [fields]:返回名称为key的hash中field i对应的value
    hmset key [fields]:向名称为key的hash中添加元素field
    hincrby key field integer:将名称为key的hash中field的value增加integer
    hexists key field:名称为key的hash中是否存在键为field的域
    hdel key field:删除名称为key的hash中键为field的域
    hlen key:返回名称为key的hash中元素个数
    hkeys key:返回名称为key的hash中所有键
    hvals key:返回名称为key的hash中所有键对应的value
    hgetall key:返回名称为key的hash中所有的键(field)及其对应的value

Oracle函数命令

发表于 2015-05-05 | 分类于 Database , Oracle |

查看oracle版本

查看oracle版本命令

1
2
select * from v$instance
select * from product_component_version
阅读全文 »

MySQL函数命令

发表于 2015-05-05 | 分类于 Database , MySQL |

MySQL函数

Every derived table must have its own alias

关于子查询 Every derived table must have its own alias 的错误

在子查询中必须给查询的结果一个别名,不然会报上述错误

1
select * from (select * from table1) as t


SELECT INTO 和 INSERT INTO SELECT 两种表复制语句

来自SELECT INTO 和 INSERT INTO SELECT 两种表复制语句

insert into select要求目标表Table2必须存在,由于目标表Table2已经存在,所以我们除了插入源表Table1的字段外,还可以插入常量。

1
insert into Table2(field1,field2,...) select value1,value2,... from Table1

select into要求目标表Table2不存在,因为在插入时会自动创建表Table2,并将Table1中指定字段数据复制到Table2中。

1
select vale1, value2 into Table2 from Table1


mysql update查询结果

mysql update不能直接使用select的结果

SQL Server中可以直接使用结果集更新

1
update table1 set a.field = (select field from table2)

在MySQL中上述语句是行不通的,如果需要完成上述效果,需要使用inner join

1
update table1 a inner join table2 b set a.field1 = b.field1 where a.field2 = b.field2


mysql查询区分大小写

来自mysql查询区分大小写

Mysql默认查询是不分大小写的,可以在SQL语句中加入binary来区分大小写;
BINARY不是函数,是类型转换运算符,它用来强制它后面的字符串为一个二进制字符串,可以理解为在字符串比较的时候区分大小写

1
select * from table1 a where a.id = BINARY 'a'


MySQL行转列

case when 语句

mysql中case when语句的使用示例

基本用法

1
2
3
4
5
6
7
select filed1,
case
when filed2 = 'a' then 'a'
when filed2 = 'b' then 'b'
else 'c'
end
from table1;

1
2
3
4
5
6
7
select filed1,
case field2
when 'a' then 'a'
when 'b' then 'b'
else 'c'
end
from table1;

复合?

1
2
3
4
5
6
7
select filed1,filed2
case
when filed1 = 'a' then 'a'
when filed2 = 'b' then 'b'
else 'c'
end
from table1;


if sum语句

mysql行转列(if + sum)

mysql行转列可以使用sum与if函数配合完成
所用数据如下

name type score
a chinese 80
a math 70
b chinese 90
b math 100
1
2
3
4
5
select name, 
sum(if(type='chinese',score,0)) as chinese,
sum(if(type='math',score,0)) as math
from table1
group by name

结果如下

name chinese math
a 80 70
b 90 100

总结:if主要是用来创建新列,并将非对应学科的分数写为0,用sum或max配合group by保证取出的值是学科对应的值,这样就可以完成行转列了


多行记录合并成一行

Oracle和Mysql中将多行记录合并为一行

MySQL使用函数group_concat

1
2
3
4
5
6
select 
field1,
field2,
group_concat(field3 order by field3 separator "|")
from table1
group by field1

这里的separator指定分隔符为”|”

Oracle使用函数WMSYS.WM_CONCAT

1
2
3
4
5
select
field1,
WMSYS.WM_CONCAT(field2) as field2
from table1
group by field1


获取小数点后两位

mysql格式化小数保留小数点后两位
MySQL CAST与CONVERT 函数的用法
mysql数据库,结果保留4位小数,小数点后四位

  • 使用format函数
    1
    select format(12345.678,2)

返回结果为 12,345.68
此函数整数部分超过三位的时候以逗号分割,并且返回的结果是string类型的。

  • 使用truncate函数
    1
    select truncate(12345.678,2)

返回结果为 12345.67
此函数并不能达到四舍五入的效果

  • 使用convert函数
    1
    select convert(12345.678,decimal)

返回结果为 12346
此函数为转换格式,将所选数字转换为浮点数类型,接收参数主要有 二进制BINARY,字符型CHAR(),日期DATE,时间TIME,日期时间型DATETIME,浮点数DECIMAL,整数SIGNED,无符号整数UNSIGNED.

  • 使用round函数
    1
    select round(12345.678,2)

返回结果为 12345.68
符合预期


NULL与空值的区别

Mysql探究之null与not null

首先,我们要搞清楚“空值” 和 “NULL” 的概念:

  1. 空值是不占用空间的
  2. mysql中的NULL其实是占用空间的

NOT NULL的字段是不能插入“NULL”的,只能插入“空值”(即'')
NULL 其实并不是空值,而是要占用空间,所以mysql在进行比较的时候,NULL 会参与字段比较,所以对效率有一部分影响,而且对表索引时不会存储NULL值的,所以如果索引的字段可以为NULL,索引的效率会下降很多

判断不为空

1
select * from table1 where field1 <> ''

判断不为NULL

1
select * from table1 where field1 is not null


IFNULL,NULLIF与ISNULL的区别

MySql 里的IFNULL、NULLIF和ISNULL用法

  • ifnull(expr1,expr2): 如果expr1不为NULL时,返回expr1,否则返回expr2`
  • nullif(expr1,expr2): 如果expr1=expr2,则返回NULL,否则返回expr1
  • isnull(expr): 如果expr为NULL,则返回1,否则返回0

操作字符串函数

来自Mysql字符串截取函数SUBSTRING的用法说明

  • left(被截取字符串,截取长度): 从左开始截取字符串
  • right(被截取字符串,截取长度): 从右开始截取字符串
  • substring(被截取字段,[从第几位开始截取],截取长度): 截取字符串,中括号内的参数为可选,如果为负数则是从字符串右边开始计数
  • substring_index(被截取字段,关键字,关键字出现的次数): 按关键字截取字符串,如果关键字出现的次数为负数,则是从字符串右边开始计数

日期函数

来自
MySQL日期时间函数大全
mysql相似于oracle的to_char() to_date()方法
MYSQL如何计算两个日期间隔天数

  • DAYOFWEEK(date): 返回日期date是星期几(1=星期天···7=星期六,ODBC标准)
  • WEEKDAY(date): 返回日期date是星期几(0=星期一···6= 星期天)
  • DAYOFMONTH(date): 返回date是一月中的第几日(在1到31范围内)
  • DAYOFYEAR(date): 返回date是一年中的第几日(在1到366范围内)
  • DAYNAME(date): 返回date是星期几(按英文名返回)
  • MONTHNAME(date): 返回date是几月(按英文名返回)
  • QUARTER(date): 返回date是一年的第几个季度
  • WEEK(date,first): 返回date是一年的第几周(first默认值0,first取值1表示周一是周的开始,0从周日开始)
  • YEAR(date): 返回date的年份
  • MONTH(date): 返回date中的月份
  • HOUR(time): 返回time的小时数(范围是0到23)
  • MINUTE(time): 返回time的分钟数(范围是0到59)
  • SECOND(time): 返回time的秒数(范围是0到59)
  • PERIOD_ADD(P,N): 增加N个月到时期P并返回(P的格式YYMM或YYYYMM)
  • PERIOD_DIFF(P1,P2): 返回在时期P1和P2之间月数(P1和P2的格式YYMM或YYYYMM) (P1<P2为负数)
  • DATE_ADD(date,INTERVAL expr type),
    DATE_SUB(date,INTERVAL expr type),
    ADDDATE(date,INTERVAL expr type),
    SUBDATE(date,INTERVAL expr type): 对日期时间进行加减法运算。ADDDATE()和SUBDATE()是DATE_ADD()和DATE_SUB()的同义词,date是一个DATETIME或DATE值,expr对date进行加减法的一个表达式字符串,type指明表达式expr应该如何被解释,例如
    1
    2
    3
    4
    5
    6
    7
    8
    select date_add('2015-05-04', INTERVAL -1 DAY)
    --返回结果2015-05-03
    select date_add('2015-05-04', INTERVAL '1 2:3:4' DAY_SECOND)
    --返回结果2015-05-05 02:03:04
    select date_add('2015-05-04', INTERVAL '2:3' MINUTE_SECOND)
    --返回结果2015-05-04 00:02:03
    select date_add('2015-05-04', INTERVAL '-1 10' DAY_HOUR)
    --返回结果2015-05-02 14:00:00
type 意义 expr
SECOND 秒 SECONDS
MINUTE 分 MINUTES
HOUR 时 HOURS
DAY 天 DAYS
MONTH 月 MONTHS
YEAR 年 YEARS
MINUTE_SECOND 分钟:秒 “MINUTES:SECONDS”
HOUR_MINUTE 小时:分钟 “HOURS:MINUTES”
DAY_HOUR 天和小时 “DAYS HOURS”
YEAR_MONTH 年和月 “YEARS-MONTHS”
HOUR_SECOND 小时, 分钟 “HOURS:MINUTES:SECONDS”
DAY_MINUTE 天, 小时, 分钟 “DAYS HOURS:MINUTES”
DAY_SECOND 天, 小时, 分钟, 秒 “DAYS HOURS:MINUTES:SECONDS”

expr中允许任何标点做分隔符,如果所有是DATE值时结果是一个DATE值,否则结果是一个DATETIME值
如果type关键词不完整,则MySQL从右端取值,DAY_SECOND因为缺少小时分钟等于MINUTE_SECOND
如果增加MONTH、YEAR_MONTH或YEAR,天数大于结果月份的最大天数则使用最大天数

  • TO_DAYS(date): 返回日期date是西元0年至今多少天(不计算1582年以前)
  • FROM_DAYS(N): 给出西元0年至今多少天返回DATE值(不计算1582年以前)
  • STR_TO_DATE(date,format): 将date字符串转成date格式
  • DATE_FORMAT(date,format): 根据format字符串格式化date值
标识符 意义
%M 月名字(January……December)
%W 星期名字(Sunday……Saturday)
%D 有英语前缀的月份的日期(1st, 2nd, 3rd, 等等)
%Y 年, 数字, 4 位
%y 年, 数字, 2 位
%a 缩写的星期名字(Sun···Sat)
%d 月份中的天数, 数字(00···31)
%e 月份中的天数, 数字(0……31)
%m 月, 数字(01……12)
%c 月, 数字(1……12)
%b 缩写的月份名字(Jan……Dec)
%j 一年中的天数(001……366)
%H 小时(00……23)
%k 小时(0……23)
%h 小时(01……12)
%I 小时(01……12)
%l 小时(1……12)
%i 分钟, 数字(00……59)
%r 时间,12 小时(hh:mm:ss [AP]M)
%T 时间,24 小时(hh:mm:ss)
%S 秒(00……59)
%s 秒(00……59)
%p AM或PM
%w 一个星期中的天数(0=Sunday···6=Saturday)
%U 星期(0……52), 这里星期天是星期的第一天
%u 星期(0……52), 这里星期一是星期的第一天
%% 字符%
1
2
select date_format('2015-05-04 17:13:40','%W %M %Y %H:%i:%s')
--返回结果 Monday May 2015 17:13:40
  • TIME_FORMAT(time,format): 和DATE_FORMAT()类似,但TIME_FORMAT只处理小时、分钟和秒(其余符号产生一个NULL值或0)
  • CURDATE()与CURRENT_DATE(): 以’YYYY-MM-DD’或YYYYMMDD格式返回当前日期值(根据返回值所处上下文是字符串或数字)
  • CURTIME()与CURRENT_TIME():以’HH:MM:SS’或HHMMSS格式返回当前时间值(根据返回值所处上下文是字符串或数字)
  • NOW(),SYSDATE()与CURRENT_TIMESTAMP(): 以’YYYY-MM-DD HH:MM:SS’或YYYYMMDDHHMMSS格式返回当前日期时间(根据返回值所处上下文是字符串或数字)
  • UNIX_TIMESTAMP()与UNIX_TIMESTAMP(date): 返回一个Unix时间戳(从’1970-01-01 00:00:00’GMT开始的秒数,date默认值为当前时间)
  • FROM_UNIXTIME(unix_timestamp): 以’YYYY-MM-DD HH:MM:SS’或YYYYMMDDHHMMSS格式返回时间戳的值
  • FROM_UNIXTIME(unix_timestamp,format): 以format字符串格式返回时间戳的值
  • SEC_TO_TIME(seconds): 以’HH:MM:SS’或HHMMSS格式返回秒数转成的TIME值
  • TIME_TO_SEC(time): 返回time值有多少秒
  • datediff(date1,date2): 计算两个日期之间间隔的天数

MySQL批量更新数据,有则更新,无则插入

ON DUPLICATE KEY UPDATE重复插入时更新

insert on duplicate key update
在INSERT语句中指定了ON DUPLICATE KEY UPDATE,并且插入行后会导致在一个UNIQUE索引或PRIMARY KEY中出现重复值,则执行旧行UPDATE
您可以在UPDATE子句中使用VALUES(col_name)函数从INSERT...UPDATE语句的INSERT部分引用列值。换句话说,如果没有发生重复关键字冲突,则UPDATE子句中的VALUES(col_name)可以引用被插入的col_name的值。本函数特别适用于多行插入。VALUES()函数只在INSERT...UPDATE语句中有意义,其它时候会返回NULL。

1
INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6) ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);

replace
我们在使用数据库时可能会经常遇到这种情况。如果一个表在一个字段上建立了唯一索引,当我们再向这个表中使用已经存在的键值插入一条记录,那将会抛出一个主键冲突的错误。当然,我们可能想用新记录的值来覆盖原来的记录值。如果使用传统的做法,必须先使用DELETE语句删除原先的记录,然后再使用INSERT插入新的记录。而在MySQL中为我们提供了一种新的解决方案,这就是REPLACE语句。使用REPLACE插入一条记录时,如果不重复,REPLACE就和INSERT的功能一样,如果有重复记录,REPLACE就使用新记录的值来替换原来的记录值。
使用REPLACE的最大好处就是可以将DELETE和INSERT合二为一,形成一个原子操作。这样就可以不必考虑在同时使用DELETE和INSERT时添加事务等复杂操作了。
在使用REPLACE时,表中必须有唯一索引,而且这个索引所在的字段不能允许空值,否则REPLACE就和INSERT完全一样的。
在执行REPLACE后,系统返回了所影响的行数,如果返回1,说明在表中并没有重复的记录,如果返回2,说明有一条重复记录,系统自动先调用了DELETE删除这条记录,然后再记录用INSERT来插入这条记录。如果返回的值大于2,那说明有多个唯一索引,有多条记录被删除和插入。
REPLACE的语法和INSERT非常的相似,如下面的REPLACE语句是插入或更新一条记录。

1
REPLACE INTO users (id,name,age) VALUES(123, 'a', 10);

REPLACE也可以使用SET语句

1
REPLACE INTO users SET id = 123, name = 'a', age = 10;


####中文排序

让MySQL支持中文排序的实现方法

使用CONVERT来转换字符集

1
select * from mytable order by CONVERT(chineseColumnName USING gbk);

MySQL基本配置

发表于 2015-05-05 | 分类于 Database , MySQL |

MySQL免安装版配置

MySQL Win免安装版配置
MySQL-5.6.13免安装版配置方法
安装 mysql-5.7.5-m15-winx64

修改文件目录下的my-default.ini为my.ini

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
41
[mysqld]

basedir = D:/mysql
datadir = D:/mysql/data
port = 3306
server_id = 1
log-error = "D:/mysql/log/mysql_error_log.err"
# 服务端使用的字符集
character-set-server = utf8
# mysql服务器支持的最大并发连接数(用户数)
max_connections = 100
# 设置table高速缓存的数量
table_open_cache = 256
# 查询缓存大小,用于缓存SELECT查询结果
query_cache_size = 1M
# 内存中的每个临时表允许的最大大小
tmp_table_size = 32M
# 缓存的最大线程数
thread_cache_size = 8

# InnoDB
innodb_data_home_dir = D:/mysql/data
# 事务相关参数
# 如果值为1,则InnoDB在每次commit都会将事务日志写入磁盘(磁盘IO消耗较大),这样保证了完全的ACID特性。
# 如果值为0,则表示事务日志写入内存log和内存log写入磁盘的频率都为1次/秒。
# 如果值为2,则表示事务日志在每次commit都写入内存log,但内存log写入磁盘的频率为1次/秒。
innodb_flush_log_at_trx_commit = 1
# InnoDB日志数据缓冲大小
innodb_log_buffer_size = 2M
# InnoDB使用缓冲池来缓存索引和行数据。该值设置的越大,则磁盘IO越少。
innodb_buffer_pool_size = 128M
# 每一个InnoDB事务日志的大小
innodb_log_file_size = 32M
# InnoDB内核最大并发线程数
innodb_thread_concurrency = 8

join_buffer_size = 128M
sort_buffer_size = 2M
read_rnd_buffer_size = 2M
explicit_defaults_for_timestamp = true
sql-mode = STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

改后保存,进入命令行工具,定位到mysql目录下的bin目录里,在命令行输入

1
mysqld --install MySQL --defaults-file="D:/mysql/my.ini"

即可注册MySQL服务为系统服务,然后通过net stary MySQL启动,或者使用service.msc命令启动服务管理界面启动MySQL服务

  • 5.7版本之后首先输入命令mysqld --initialize-insecure初始化

密码设置

Mysql 免安装版 root@localhost 密码设置

使用set password命令

1
2
mysql -u root
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpass');

使用mysqladmin

1
mysqladmin -u root password "newpass"

如果root已经设置过密码,采用如下方法

1
mysqladmin -u root password oldpass "newpass"

编辑user表

1
2
3
4
mysql -u root
use mysql;
UPDATE user SET Password = PASSWORD('newpass') WHERE user = 'root';
FLUSH PRIVILEGES;

5.7之后,上述语句无效,应为

1
ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password';

终极办法

1
2
3
mysql -u root mysql
UPDATE user SET password=PASSWORD("new password") WHERE user='root';
FLUSH PRIVILEGES;


数据备份

全量备份

windows mysql 自动备份的几种方法

1
2
3
4
5
6
7
rem *******************************Code Start*****************************
@echo off
set "Ymd=%date:~,4%%date:~5,2%%date:~8,2%"
C:\MySQL\bin\mysqldump --opt -u root --password=123456 bbs > D:\db_backup\bbs_%Ymd%.sql

@echo on
rem *******************************Code End*****************************

将以上脚本代码保存为bat文件
然后使用Windows的“计划任务”定时执行该脚本即可
注意要备份的路径必须存在
通过%date:~5,2%来组合得出当前日期,组合的效果为yyyymmdd,date命令得到的日期格式默认为yyyy-mm-dd(如果不是此格式可以通过pause命令来暂停命令行窗口看通过%date:~,20%得到的当前计算机日期格式),所以通过%date:~5,2%即可得到日期中的第五个字符开始的两个字符,例如今天为2015-05-04,通过%date:~5,2%则可以得到05。(日期的字符串的下标是从0开始的)


增量备份

【SQL】MySQL之使用mysqlbinlog进行增量备份及恢复详解

在my.ini中添加如下语句

1
2
log-bin="C:/Program Files/mysql-5.6.22-winx64/logbin/log"
expire_logs_days=7

log-bin为记录日志的文件路径,最后的/log为文件名
expire_log_days为指定间隔多少日后删除所有的日志文件
重启mysql服务后,在指定文件夹logbin下可以发现有log.index,log.000001这样的文件。其中log.index为备份文件的索引,指明有哪些备份文件,其他的为备份文件,存放用户对数据库的所有操作
log.index的文件内容如下

1
2
3
C:\Program Files\mysql-5.6.22-winx64\logbin\log.000001
C:\Program Files\mysql-5.6.22-winx64\logbin\log.000002
C:\Program Files\mysql-5.6.22-winx64\logbin\log.000003

通过mysqlbinlog程序可以看到日志文件的内容

1
mysqlbinlog "C:\Program Files\mysql-5.6.22-winx64\logbin\log.000001"

按时间导出其中的内容

1
mysqlbinlog --start-datetime="2015-05-04 00:00:00" --stop-datetime="2015-05-04 23:59:59" juelog.000001 -r test.sql

这样可以把处于时间段的所有操作记录导入到test.sql文件中,test.sql文件在mysqlbinlog同级目录。
--start-datetime与--stop-datetime是可选参数

按位置进行恢复
清空表后输入

1
mysqlbinlog --stop-position="行数" log.000001 | mysql -u root -p

输入密码后即可恢复数据

总结
Mysql数据库会以二进制形式,自动把用户对mysql数据库的操作,记录到备份文件中。
当用户希望恢复的时候,可以使用备份文件,来进行相应的恢复。
备份文件中会记录创建表的语句、删除表的语句、insert语句、delect语句、update语句等,而不会记录select语句。
增量备份记录的内容包括:

  1. 操作语句本身。
  2. 操作的时间。
  3. 操作的位置。

MySQL 5.6 中 TIMESTAMP 的变化

MySQL 5.6 中 TIMESTAMP 的变化

在my.ini中的[mysqld]节点下添加

1
explicit_defaults_for_timestamp=true

重启MySQL后错误消失,这时TIMESTAMP的行为如下:

  • TIMESTAMP如果没有显示声明NOT NULL,是允许NULL值的,可以直接设置改列为NULL,而没有默认填充行为。
  • TIMESTAMP不会默认分配DEFAULT CURRENT_TIMESTAMP和ON UPDATE CURRENT_TIMESTAMP属性。
  • 声明为NOT NULL且没有默认子句的TIMESTAMP列是没有默认值的。往数据表中插入列,又没有给TIMESTAMP列赋值时,如果是严格SQL模式,会抛出一个错误,如果严格SQL模式没有启用,该列会赋值为’0000-00-00 00:00:00′,同时出现一个警告。(这和MySQL处理其他时间类型数据一样,如DATETIME)

CommunicationsException异常处理

来自 com.mysql.jdbc.exceptions.jdbc4.CommunicationsException

mysql5将其连接的等待时间(wait_timeout)缺省为8小时.如果在wait_timeout秒期间内,数据库连接(java.sql.Connection)一直处于等待状态,mysql5就将该连接关闭。这时,你的JavaEE应用的连接池仍然合法地持有该连接的引用。当用该连接来进行数据库操作时,就碰到上述错误。
解决这个错误需要在my.ini配置文件中[mysqld]节点下配置wait_timeout将超时时间改为自己需要的时间

1
2
[mysqld]
wait_timeout=1814400


Mac下的MySQL卸载

How do you uninstall MySQL from Mac OS X?
Remove MySQL completely from Mac OSX

运行终端,输入下列命令

1
2
3
4
5
6
7
8
9
sudo rm /usr/local/mysql
sudo rm -rf /usr/local/mysql*
sudo rm -rf /Library/StartupItems/MySQLCOM
sudo rm -rf /Library/PreferencePanes/MySQL*
rm -rf ~/Library/PreferencePanes/MySQL*
sudo rm -rf /Library/Receipts/mysql*
sudo rm -rf /Library/Receipts/MySQL*
sudo rm -rf /var/db/receipts/com.mysql.*
sudo rm -rf /private/var/db/receipts/*mysql*

log4j配置

发表于 2015-04-27 | 分类于 Java |

Log4j使用指南
如何使用Log4j?
玩转log4j
Tomcat下log4j设置文件路径和temp目录
log4j输出多个自定义日志文件

log4j的配置文件支持key=value格式的properties文件以及xml文件。

日志优先级

它的日志优先级别有: OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者自定义级别。一般使用的从低到高为DEBUG、INFO、WARN、ERROR.假如在一个级别为q的Logger中发生一个级别为p的日志请求,如果p>=q,那么请求将被启用。这是Log4j的核心原则。 比如在这里定义了INFO级别,则应用程序中所有DEBUG级别的日志信息将不被打印出来。

输出源

一个输出源被称做一个Appender。 Appender包括console(控制台), files(文件), GUI components(图形的组件), remote socket servers(socket 服务), JMS(java信息服务), NT Event Loggers(NT的事件日志), and remote UNIX Syslog daemons(远程UNIX的后台日志服务)。它也可以做到异步记录。
一个logger可以设置超过一个的appender。 用addAppender 方法添加一个appender到一个给定的logger。对于一个给定的logger它每个生效的日志请求都被转发到该logger所有的appender上和该logger的父辈logger的appender上。
Log4j提供的appender有以下几种:

org.apache.log4j.ConsoleAppender(控制台)
org.apache.log4j.FileAppender(文件)
org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件)
org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生新文件)
org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)

样式设置

布局样式

org.apache.log4j.HTMLLayout(以HTML表格形式布局),
org.apache.log4j.PatternLayout(可以灵活地指定布局模式),
org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),
org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)

格式

%m 输出代码中指定的消息
%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
%r 输出自应用启动到输出该log信息耗费的毫秒数
%c 输出所属的类目,通常就是所在类的全名
%t 输出产生该日志事件的线程名
%n 输出一个回车换行符,Windows平台为”rn”,Unix平台为”n”
%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921
%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(Test Log4.java:10)

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# log4j.rootLogger=INFO,stdout
# 指定多个输出源
log4j.logger.com.framework=INFO,stdout,R

# 指定控制台输出
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
# 输出级别为INFO
log4j.appender.stdout.Threshold=INFO
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%p] %d{yyyy-MM-dd HH:mm:ss} %m%n

# 指定输出日志到文件
log4j.appender.R=org.apache.log4j.RollingFileAppender
# 指定文件目录,这里为tomcat主目录,需要在环境变量中配置
log4j.appender.R.File=${catalina.base}/logs/ilog.txt
# 大于20MB则另起文件
log4j.appender.R.MaxFileSize=20MB
log4j.appender.R.Threshold=INFO
log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=[%p] %d{yyyy-MM-dd HH:mm:ss} %m%n

在代码中调用日志:

1
2
3
4
5
6
public class LogTest {
Logger log = Logger.getLogger(LogTest.class);
public static void main(String[] args) {
log.info("test");
}
}

jQuery UI控件知识点整理

发表于 2015-04-23 | 分类于 JavaScript , jQuery |

收集平时使用jQuery UI控件碰到的一些问题与知识点。

阅读全文 »

Jetty相关知识

发表于 2015-04-23 | 分类于 Java , Jetty |

Jetty/Tutorial/Embedding Jetty
Java / Jetty: How to Add Filter to Embedded Jetty
EnumSet的几个例子

使用代码运行jetty

运行一个war包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class OneWebApp {
public static void main(String[] args) throws Exception {
String jetty_home = System.getProperty("jetty.home","..");

Server server = new Server(8080);

WebAppContext webapp = new WebAppContext();
webapp.setContextPath("/");
webapp.setWar(jetty_home+"/webapps/test.war");
server.setHandler(webapp);

server.start();
server.join();
}
}

运行一个web项目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class OneWebAppUnassembled {
public static void main(String[] args) throws Exception {
Server server = new Server(8080);

WebAppContext context = new WebAppContext();
context.setDescriptor(webapp+"/WEB-INF/web.xml");
context.setResourceBase("../test-jetty-webapp/src/main/webapp");
context.setContextPath("/");
context.setParentLoaderPriority(true);

server.setHandler(context);

server.start();
server.join();
}
}

运行spring mvc项目

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
public static void main(String[] args) throws Exception {
Server server = new Server(8090);
WebAppContext context = new WebAppContext();
//添加log4j监听器
context.setInitParameter("log4jConfigLocation", "classpath:log4j.properties");
context.addEventListener(new Log4jConfigListener());
//设置访问路径
context.setContextPath("/test1");
//设置页面资源文件夹
context.setResourceBase("../test1/src/main/webapp");
EnumSet<DispatcherType> es = EnumSet.of(DispatcherType.ASYNC,DispatcherType.ERROR,DispatcherType.REQUEST,DispatcherType.FORWARD);
//添加Filter
context.addFilter(new FilterHolder(WebAppFilter.class), "/*", es);
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
//加载spring注解配置类
ctx.register(WebMvcConfig.class);
DispatcherServlet ds = new DispatcherServlet(ctx);
context.addServlet(new ServletHolder(ds), "/");
//添加servlet
context.addServlet(HelloServlet.class, "/helloServlet");

server.setHandler(context);

server.start();
server.join();
}


jetty相关配置

来自
jetty配置文件详解
Jetty 的配置

Jetty 的配置文件放在 etc 路径下,jetty.xml文件是默认的配置文件,jetty-jmx.xml是启动 JMX 控制的配置文件; jetty-plus.xm1文件是在增加 Jetty 扩展功能的配置文件。启动Jetty的命令为(配置环境路径或者进入Jetty目录下执行下面命令):

1
java -jar startup.jar

默认使用jetty.xm1文件时启动Jetty,即与如下命令效果相同

1
java -jar startup.jar etc/jetty.xml

启动时也可以指定多个配置文件,可输入如下命令

1
java -jar startup.jaretc/jetty.xml etc/jetty-plus.xml

打开 Jetty 配置文件,该配置文件的根元素是Configure,另外还会看到有如下的配
置元素。

  • Set: 相当于调用 setxx 方法。
  • Get: 相当于调用 getXxx 方法。
  • New: 创建某个类的实例。
  • Arg: 为方法或构造器传入参数。
  • Array: 设置一个数组。
  • Item: 设置数组或集合的-J页。
  • Call: 调用某个方法。

Jetty 是个嵌入式 Web 容器,因此它的服务对应一个 Server 实例,可以看到配置文件中有如下片段:

1
2
<!--配置了一个Jetty服务器进程-->
<Configure id="Server" class="org.mortbay.jetty.Server">

上述是整个配置文件的root元素,读到它的时候会创建一个server对象,当然这个server对象的创建采用的是默认构造函数,因而可以理解为它是一个空的server

把相应的war包丢到jetty目录下的webapps目录里即可运行,在jetty目录下新建一个文件夹work,这样war包解压的文件就不会放到默认临时文件夹而放到work目录下

windows下nginx配置

发表于 2015-04-22 | 分类于 其他 |

windows下nginx配置

Windows下nginx+tomcat的负载均衡
tomcat结合nginx使用小结
Nginx - Windows下Nginx基本安装和配置
Nginx之虚拟目录-root与alias的区别

基本配置

反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器。
启动nginx命令:

1
start nginx

如果修改了配置文件只想验证有没有出错可以输入以下命令:

1
nginx -t

修改了配置文件重启的命令为:

1
nginx -s reload

停止的命令为

1
nginx -s stop

配置文件conf/nginx.conf

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#Nginx所用用户和组,window下不指定  
#user nobody;

#工作的子进程(通常等于CPU数量或者1倍于CPU)
worker_processes 1;

#错误日志存放路径
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;

#指定pid存放文件
#pid logs/nginx.pid;
events {
#允许最大连接数
worker_connections 1024;
}


http {
include mime.types;
default_type application/octet-stream;

#定义日志格式
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';

#access_log logs/access.log main;

sendfile on;
#tcp_nopush on;

#keepalive_timeout 0;
keepalive_timeout 65;

#客户端上传文件大小控制
client_max_body_size 8m;

#gzip on;
upstream localhost {
server localhost:8080;
server localhost:8000;
#根据ip计算将请求分配各那个后端tomcat,许多人误认为可以解决session问题,其实并不能。
#同一机器在多网情况下,路由切换,ip可能不同
ip_hash;
}

server {
listen 9999;
server_name localhost;

#charset koi8-r;

#access_log logs/host.access.log main;

location / {
root html;
index index.html index.htm;
#此处的 http://localhost与upstream localhost对应
proxy_pass http://localhost;

proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 100;
proxy_send_timeout 100;
proxy_read_timeout 100;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}

#error_page 404 /404.html;

# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}

server节点下的配置意义如下:
listen: 表示当前的代理服务器监听的端口,默认的是监听80端口。注意,如果我们配置了多个server,这个listen要配置不一样,不然就不能确定转到哪里去了
server_name: 表示监听到之后需要转到哪里去
location: 表示匹配的路径,这时配置了/表示所有请求都被匹配到这里
root: 里面配置了root这时表示当匹配这个请求的路径时,将会在这个文件夹内寻找相应的文件,这里对我们之后的静态文件伺服很有用
index: 当没有指定主页时,默认会选择这个指定的文件,它可以有多个,并按顺序来加载,如果第一个不存在,则找第二个,依此类推
proxy_pass: 它表示代理路径,相当于转发,而不像之前说的root必须指定一个文件夹
error_page: 发生错误时显示的页面

如果需要代理多台服务器,则如上述配置文件里的模块upstream中添加相应的服务器访问路径

1
2
3
4
5
6
7
8
9
10
upstream local_tomcat {  
server localhost:8080;
server localhost:9999;
}
server{
location / {
proxy_pass http://local_tomcat;
}
#......其他省略
}

在server外添加了一个upstream,而直接在proxy_pass里面直接用http://+upstream的名称来使用。
我们还是直接来http://localhost,还是和第一个一样的效果,所有链接都没问题,说明我们配置正确。
upstream中的server元素必须要注意,不能加http://,但proxy_pass中必须加

但有时我们就不想它挂的时候访问另外一个,而只是希望一个服务器访问的机会比另外一个大,这个可以在server最后加上一个weight=数字来指定,数字越大,表明请求到的机会越大

1
2
3
4
upstream local_tomcat {  
server localhost:8080 weight=1;
server localhost:9999 weight=5;
}

这时我们给了jetty一个更高的权值,让它更有机会访问到,实际上当我们刷新http://localhost访问的时候发现第二台服务器访问机率大很多,第一台服务器几乎没机会访问,一般情况下,如果我们必须这样用,不要相关太大,以免一个服务器负载太大


Nginx之虚拟目录-root与alias的区别

1、alias后跟的指定目录是准确的,并且末尾必须加“/”,否则找不到文件

1
2
3
location /c/ {
alias /a/
}

如果访问站点http://location/c访问的就是/a/目录下的站点信息

2、root后跟的指定目录是上级目录,并且该上级目录下要含有和location后指定名称的同名目录才行,末尾“/”加不加无所谓。

1
2
3
location /c/ {
root /a/
}

如果访问站点http://location/c访问的就是/a/c目录下的站点信息。

3、一般情况下,在location /中配置root,在location /other中配置alias是一个好习惯。

Git 相关知识点收集

发表于 2015-04-22 | 分类于 其他 |

这里收集了一些关于Git的相关命令及一些Git组件的问题解决办法。

阅读全文 »
1…456
Shepard

Shepard

59 日志
25 分类
67 标签
GitHub
© 2015 — 2020 Shepard
由 Hexo 强力驱动
|
主题 — NexT.Mist v5.1.4