分类目录归档:SQL

mysql插入emoji表情报错(Incorrect string value:\x…)

原因:mysql的utf8编码不支持4字节的utf8,需要使用utf8mb4编码

解决方法:

Make sure all your tables’ default character sets and text fields are converted to utf8mb4, in addition to setting the client & server character sets, e.g. ALTER TABLE mytable charset=utf8mb4, MODIFY COLUMN textfield1 VARCHAR(255) CHARACTER SET utf8mb4,MODIFY COLUMN textfield2 VARCHAR(255) CHARACTER SET utf8mb4; and so on.If your data is already in the utf8 character set, it should convert to utf8mb4 in place without any problems. As always, back up your data before trying!

Also make sure your app layer sets its database connections’ character set to utf8mb4. Double-check this is actually happening – if you’re running an older version of your chosen framework’s mysql client library, it may not have been compiled with utf8mb4 support and it won’t set the charset properly. If not, you may have to update it or compile it yourself.

When viewing your data through the mysql client, make sure you’re on a machine that can display emoji, and run a SET NAMES utf8mb4 before running any queries.

 

来自:http://stackoverflow.com/questions/7814293/how-to-insert-utf-8-mb4-characteremoji-in-ios5-in-mysql

MySQL触发器简单实例

~~语法~~

CREATE TRIGGER <触发器名称>  –触发器必须有名字,最多64个字符,可能后面会附有分隔符.它和MySQL中其他对象的命名方式基本相象.
BEFORE AFTER }  –触发器有执行的时间设置:可以设置为事件发生前或后。
INSERT UPDATE DELETE }  –同样也能设定触发的事件:它们可以在执行insert、update或delete的过程中触发。
ON <表名称>  –触发器是属于某一个表的:当在这个表上执行插入、 更新或删除操作的时候就导致触发器的激活. 我们不能给同一张表的同一个事件安排两个触发器。
FOR EACH ROW  –触发器的执行间隔:FOR EACH ROW子句通知触发器 每隔一行执行一次动作,而不是对整个表执行一次。
<触发器SQL语句>  –触发器包含所要触发的SQL语句:这里的语句可以是任何合法的语句, 包括复合语句,但是这里的语句受的限制和函数的一样。

–你必须拥有相当大的权限才能创建触发器(CREATE TRIGGER),如果你已经是Root用户,那么就足够了。这跟SQL的标准有所不同。

~~实例~~

example1:

创建表tab1

1
2
3
4
DROP TABLE IF EXISTS tab1;
CREATE TABLE tab1(
    tab1_id varchar(11)
);

创建表tab2

1
2
3
4
DROP TABLE IF EXISTS tab2;
CREATE TABLE tab2(
    tab2_id varchar(11)
);

创建触发器:t_afterinsert_on_tab1

作用:增加tab1表记录后自动将记录增加到tab2表中

1
2
3
4
5
6
7
DROP TRIGGER IF EXISTS t_afterinsert_on_tab1;
CREATE TRIGGER t_afterinsert_on_tab1
AFTER INSERT ON tab1
FOR EACH ROW
BEGIN
     insert into tab2(tab2_id) values(new.tab1_id);
END;

测试一下

1
INSERT INTO tab1(tab1_id) values('0001');

看看结果

1
2
SELECT * FROM tab1;
SELECT * FROM tab2;

example2:

创建触发器:t_afterdelete_on_tab1

作用:删除tab1表记录后自动将tab2表中对应的记录删去

1
2
3
4
5
6
7
DROP TRIGGER IF EXISTS t_afterdelete_on_tab1;
CREATE TRIGGER t_afterdelete_on_tab1
AFTER DELETE ON tab1
FOR EACH ROW
BEGIN
      delete from tab2 where tab2_id=old.tab1_id;
END;

测试一下

1
DELETE FROM tab1 WHERE tab1_id='0001';

看看结果

1
2
SELECT * FROM tab1;
SELECT * FROM tab2;

Redis命令总结

连接操作相关的命令

  • quit:关闭连接(connection)
  • auth:简单密码认证

持久化

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

远程服务控制

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

对value操作的命令

  • exists(key):确认一个key是否存在
  • del(key):删除一个key
  • type(key):返回值的类型
  • keys(pattern):返回满足给定pattern的所有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

Mongodb从配置到应用

一,Mongodb简介

Mongo(http://www.mongodb.org/)是一个高性能,开源(代震军大牛正在研究Mongodb的源码,大家可以去看看http://www.cnblogs.com/daizhj/),模式自由(schema-free)的文档型数据库,它在许多场景下可用于替代传统的关系型数据库或键/值(key-value)存储方式。Mongo使用C++开发,

具有以下特性:

  1. 面向集合的存储:适合存储对象及JSON形式的数据。
  2. 动态查询:Mongo支持丰富的查询表达式。查询指令使用JSON形式的标记,可轻易查询文档中内嵌的对象及数组。
  3. 完整的索引支持:包括文档内嵌对象及数组。Mongo的查询优化器会分析查询表达式,并生成一个高效的查询计划。
  4. 查询监视:Mongo包含一个监视工具用于分析数据库操作的性能。
  5. 复制及自动故障转移:Mongo数据库支持服务器之间的数据复制,支持主-从模式及服务器之间的相互复制。复制的主要目标是提供冗余及自动故障转移。
  6. 高效的传统存储方式:支持二进制数据及大型对象(如照片或图片)。
  7. 自动分片以支持云级别的伸缩性(处于早期alpha阶段):自动分片功能支持水平的数据库集群,可动态添加额外的机器。
  8. 模式自由(schema-free),意味着对于存储在mongodb数据库中的文件,我们不需要知道它的任何结构定义。如果需要的话,你完全可以把不同结构的文件存储在同一个数据库里。
  9. 支持Python,PHP,Ruby,Java,C,C#,Javascript,Perl及C++语言的驱动程序,社区中也提供了对Erlang及.NET等平台的驱动程序。

使用场合:

  1. 网站数据:Mongo非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。
  2. 缓存:由于性能很高,Mongo也适合作为信息基础设施的缓存层。在系统重启之后,由Mongo搭建的持久化缓存层可以避免下层的数据源 过载。
  3. 大尺寸,低价值的数据:使用传统的关系型数据库存储一些数据时可能会比较昂贵,在此之前,很多时候程序员往往会选择传统的文件进行存储。
  4. 高伸缩性的场景:Mongo非常适合由数十或数百台服务器组成的数据库。Mongo的路线图中已经包含对MapReduce引擎的内置支持。
  5. 用于对象及JSON数据的存储:Mongo的BSON数据格式非常适合文档化格式的存储及查询。

所谓“面向集合”(Collenction-Orented),意思是数据被分组存储在数据集中,被称为一个集合(Collenction)。每个集合在数据库中都有一个唯一的标识名,并且可以包含无限数目的文档。集合的概念类似关系型数据库(RDBMS)里的表(table),不同的是它不需要定义任何模式(schema)。

继续阅读

MongoDB 连接数高产生原因及解决

MongoDB Sharding架构下连接数很容易达到很高,这里连接数分为几个概念:
tcp 连接数 netstat可以统计的,一般这个是最高.如果mongod/mongos在同一台服务器,更明显。
参考命令:netstat -ant|awk ‘{print $5}’ |awk -F: ‘{print $1}’|sort |uniq -c|sort -rn
mongos/mongod 连接数 mongostat/db.serverStatus()/connPoolStats可统计。
连接数多高算高呢?
这要看连接到mongodb集群应用服务器实例数、qps(增删改查)等判断。
应用服务器单台,如果qps<100, ,mongos连接数超过2000,肯定是高了。这一般是由于连接池配置不合理导致。
mongod/mongos 默认最大连接数maxConns=20000,2.4版本及以前版本最大不能超过这个数值,2.6版本(开发版2.5版本)取消这个限制。
相关链接http://nosqldb.org/topic/50ca8a50ee680fee790001f2

什么原因导致连接数过高

  • 连接池配置不合理
    分片情况下,现象是tcp 连接数过高(如达到20000),mongos连接数过高(如超过10000)
    java为例,connectionsPerHost 不宜配置过大,官方默认值由原来10改成100了,而且有默认5倍的乘数(threadsAllowedToBlockForConnectionMultiplier),一般20~50就可以了。
  • 应用服务器实例过多

我们遇到的场景,当连接到mongos的应用服务器(如Tomcat实例数量)过百,甚至达到近200台时,tcp连接数超高,达到15000以上,查看mongod对应端口连接数高达8000多,mongos 2000多。此时ops(query,insert,update,delete)低于200每秒,。定期重启(如一周一次)mongos可适当缓解该问题。

  • mongodb本身的原因表现为mongos连接数不高(如1000+),mongod连接数比较高(如8000+)。

如何解决
总结一下,连接数高分为几个场景:
应用服务器实例过多,可统计每个实例建立的连接数,适当调低连接池参数。
mongos连接数高,这种就是配置的问题,更改连接池参数。
mongos连接数不高,mongod连接数比较高,如超过5000,如果连接池配置合理还比较高的话,尝试启用releaseConnectionsAfterResponse参数(2.2.4版本以上),该参数为
隐藏参数releaseConnectionsAfterResponse

mongos> use admin
switched to db admin
mongos> db.runCommand({ setParameter : 1, releaseConnectionsAfterResponse : true }){ "was" : false, "ok" : 1 }

或者

shell> mongos --setParameter "releaseConnectionsAfterResponse=true" --configdb ... 

该参数注意事项:
写操作需要立即调用getLastError (w=1,即安全写模式),w=2(等待从库写确认)的时候可能会有些错误。
升级过后,或者重启mongos进程后,需要重新设置该参数,该参数只对单个mongos生效。
启用releaseConnectionsAfterResponse 参数,tcp 连接数明显降低到比较稳定数目。几个小时,tcp连接数从8000多降到4000多,效果不错。

  • releaseConnectionsAfterResponse 参数原理

通常,对于每个mongos->mongod连接是单独缓存的,并且该连接不能重复使用,即使该连接是空闲时也是如此,一直到连接关闭连接回到连接池中才能再使用;releaseConnectionsAfterResponse 参数启用后,mongos->mongod之间的连接在完成一个读操作或者安全写操作后能够重复使用(把连接放到连接池中而不是缓存,即更早的回归到连接池中),releaseConnectionsAfterResponse参数简单讲就是mongos->mongod的连接更早的回到连接池中,这样就不会开太多的连接了,从而减少连接数。
Create a new serverParameter for mongos, “releaseConnectionsAfterResponse,” which enables returning ShardConnections from the per-socket pool to the global pool after each read operation. This should reduce the total number of outgoing mongos connections to each shard.
the option allows better use of the connection pool, it doesn’t invalidate the connections in the pool. Normally, mongos->mongod connections for insert/update/delete/query are cached individually for each incoming connection, and can’t be re-used until the incoming connection is closed, even if they are idle and there are other active incoming connections.
What the releaseConnectionsAfterResponse option does is allow the mongos->mongod connection to be re-used (returned to the pool) after any read op (including getLastError(), so after safe writes as well). It shouldn’t have a significant performance impact – the connection isn’t destroyed, it’s just returned from the incoming connection cache to the shared pool early.

代码:
https://github.com/mongodb/mongo/commit/706459a8af0b278609d70e7122595243df6aeee8
https://github.com/mongodb/mongo/commit/74323d671a216c8c87fcb295ed743f830d5212ee
https://github.com/mongodb/mongo/commit/5d5fe49dfb5f452832b9d44fddbfb2a4e8b42f2a

===============
– connPoolTimeout设置

(该参数不在官方没有)
效果

mongos> db.runCommand({ setParameter : 1, connPoolTimeout : 900 }){ "was" : 1800, "ok" : 1 }

初步测试,效果不明显。

  • releaseConnections

计划添加个命令releaseConnections,从mongod运行,减少复制集连接数。

 

 

转载自:http://nosqldb.org/topic/518510c8735345ad0a04fef8

使用Java操作MongoDB

HelloWorld程序

  学习任何程序的第一步,都是编写HelloWorld程序,我们也不例外,看下如何通过Java编写一个HelloWorld的程序。

  首先,要通过Java操作Mongodb,必须先下载Mongodb的Java驱动程序,可以在这里下载

  新建立一个Java工程,将下载的驱动程序放在库文件路径下,程序代码如下:

package com.mkyong.core;

import java.net.UnknownHostException;

import com.mongodb.BasicDBObject;

import com.mongodb.DB;

import com.mongodb.DBCollection;

import com.mongodb.DBCursor;

import com.mongodb.Mongo;

import com.mongodb.MongoException;



/**

* Java + MongoDB Hello world Example



*/

public class App {

public static void main(String[] args) {

try {

//实例化Mongo对象,连接27017端口

            Mongo mongo = new Mongo(“localhost”, 27017);

//连接名为yourdb的数据库,假如数据库不存在的话,mongodb会自动建立

            DB db = mongo.getDB(“yourdb”);

// Get collection from MongoDB, database named “yourDB”

//从Mongodb中获得名为yourColleection的数据集合,如果该数据集合不存在,Mongodb会为其新建立

            DBCollection collection = db.getCollection(“yourCollection”);

// 使用BasicDBObject对象创建一个mongodb的document,并给予赋值。

            BasicDBObject document = new BasicDBObject();

document.put(“id”, 1001);

document.put(“msg”, “hello world mongoDB in Java”);

//将新建立的document保存到collection中去

            collection.insert(document);

// 创建要查询的document

            BasicDBObject searchQuery = new BasicDBObject();

searchQuery.put(“id”, 1001);

// 使用collection的find方法查找document

            DBCursor cursor = collection.find(searchQuery);

//循环输出结果

            while (cursor.hasNext()) {

System.out.println(cursor.next());

}

System.out.println(“Done”); 

catch (UnknownHostException e) {

e.printStackTrace();

catch (MongoException e) {

e.printStackTrace();

}

}

}

  最后,输出的结果为:

{ “_id” : { “$oid” : “4dbe5596dceace565d229dc3”} , 

“id” : 1001 , “msg” : “hello world mongoDB in Java”}

Done

 
继续阅读

SQLite开发入门

1。从http://www.sqlite.org/下载SQLite 3.3.4的版本
为了方便,我把它解压了,就一个SQLite3.exe,放入Windows目录下。
Cmd 进入命令行
1)
创建数据库文件:
>SQLite3 d:\test.db 回车
就生成了一个test.db在d盘。
这样同时也SQLite3挂上了这个test.db
2)
用.help可以看看有什么命令
>.help 回车即可
3)可以在这里直接输入SQL语句创建表格 用;结束,然后回车就可以看到了
4)看看有创建了多少表
>.tables
5)看表结构
>.schema 表名
6)看看目前挂的数据库
>.database
7)如果要把查询输出到文件
>.output 文件名
> 查询语句;
查询结果就输出到了文件c:\query.txt

把查询结果用屏幕输出
>.output stdout

8)把表结构输出,同时索引也会输出
.dump 表名
9)退出
>.exit 或者.quit

2。从http://sqlite.phxsoftware.com/下载Ado.net驱动。
下载了安装,在安装目录中存在System.Data.SQLite.dll
我们只需要拷贝这个文件到引用目录,并添加引用即可对SQLite数据库操作了
所有的Ado.net对象都是以SQLite开头的,比如SQLiteConnection
连接串只需要如下方式
Data Source=d:\test.db 或者DataSource=test.db–应用在和应用程序或者.net能够自动找到的目录
剩下的就很简单了~~

3。SQL语法
由于以前用SQLServer或者ISeries,所以DDL的语法很汗颜
1)创建一个单个Primary Key的table
CREATE TABLE  [Admin] (
[UserName] [nvarchar] (20)   PRIMARY KEY NOT NULL ,
[Password] [nvarchar] (50)   NOT NULL ,
[Rank] [smallint] NOT NULL ,
[MailServer] [nvarchar] (50)   NOT NULL ,
[MailUser] [nvarchar] (50)   NOT NULL ,
[MailPassword] [nvarchar] (50)   NOT NULL ,
[Mail] [nvarchar] (50)   NOT NULL
) ;
2)创建一个多个Primary Key的table
CREATE TABLE  [CodeDetail] (
[CdType] [nvarchar] (10)  NOT NULL ,
[CdCode] [nvarchar] (20)  NOT NULL ,
[CdString1] [ntext]   NOT NULL ,
[CdString2] [ntext]   NOT NULL ,
[CdString3] [ntext]   NOT NULL,
PRIMARY KEY (CdType,CdCode)

) ;
3)创建索引
CREATE  INDEX [IX_Account] ON  [Account]([IsCheck], [UserName]);

还可以视图等等。
4.还有很有用的SQL
Select * from Sqlite_master
Select datetime(‘now’)
Select date(‘now’)
Select time(‘now’)
以及很多函数,具体可以参考SQLite的wiki.

oh,还有就是看到有人说,好像成批插入的时候,启动事务,比不启动事务快n倍
还有就是尽量使用参数化的SQL,估计和商用DB一样能够自动Prepare.

from:http://www.sqlite.com.cn/MySqlite/4/33.Html