Linux/CentOS安装配置Lighttpd PHP MySQL教程

运行于Linux下的Lighttpd是一个开源Web服务器软件。Lighttpd的最大特点是其“轻量级特征”:仅仅需要相对于Apache等成熟服务器软件小得多的CPU与内存资源即可达到相同的性能。Lighttpd以BSD许可证发布。
根据维基百科lighttpd条目的介绍,lighttpd支持FastCGI与SCGI的负载平衡,支持Linux下chroot安全特征,支持SSL加密连接。Lighttpd虽然小巧,但是却足以满足普通的高性能Web服务请求。本文将以CentOS为例指导安装lighttpd与PHP与MySQL全套组件,基本安装方法参考了howtoforge的《Installing Lighttpd With PHP5 and MySQL Support On CentOS 6.0》一文。
本文虽然很长,但其实质非常简单,请严格按照如下方法操作即可完美安装,安装方法已经过多系统实机验证。

安装配置方法
在进行安装前,请参考《CentOS安装教程》安装好基本的CentOS系统,以保证环境的兼容性与统一性。

1、首先安装MySQL
CentOS中安装MySQL非常简单,直接yum即可:
1
[root@www ~]# yum install mysql mysql-server
安装过程中需要输入“y”以确认。
完成后启动MySQL:
1
[root@www ~]#/etc/init.d/mysqld start
安装完MySQL后,需要立即对MySQL进行基本的安全设置,使用
1
[root@www ~]# mysql_secure_installation
此程序是MySQL的安全设置向导,首先会询问是否设置MySQL的root密码,直接回车表示确认设置。按照提示重新输入一个密码即可。随后会提示:
Remove anonymous users? [Y/n]
Disallow root login remotely? [Y/n]
Remove test database and access to it? [Y/n]
Reload privilege tables now? [Y/n]
等,均直接回车(Y)。
最后使用如下命令使MySQL开机自动启动:
1
[root@www ~]# chkconfig –levels 235 mysqld on
至此,MySQL组件已经安装成功,并且做好了基本的安全设置。下面将开始安装lighttpd组件。

2、安装Lighttpd组件
由于CentOS官方的源中没有Lighttpd包,因此需要手动导入RPMforge源。
请根据自己系统的情况选择如下32/64位、CentOS 5/CentOS 6操作系统的源并安装好:
32位CentOS 5
1
wget http://soft.bootf.com/rpm/rpmforge-release-0.5.2-2.el5.rf.i386.rpm
2

3
rpm -Uhv rpmforge-release-0.5.2-2.el5.rf.i386.rpm
32位CentOS 6
1
wget http://soft.bootf.com/rpm/rpmforge-release-0.5.2-2.el6.rf.i686.rpm
2

3
rpm -Uhv rpmforge-release-0.5.2-2.el6.rf.i686.rpm
64位CentOS 5
1
wget http://soft.bootf.com/rpm/rpmforge-release-0.5.2-2.el5.rf.x86_64.rpm
2

3
rpm -Uhv rpmforge-release-0.5.2-2.el5.rf.x86_64.rpm
64位CentOS 6
1
wget http://soft.bootf.com/rpm/rpmforge-release-0.5.2-2.el6.rf.x86_64.rpm
2

3
rpm -Uhv rpmforge-release-0.5.2-2.el6.rf.x86_64.rpm
然后即可通过yum安装Lighttpd了:
1
[root@www ~]# yum install lighttpd
安装过程将会询问,输入“y”以继续。
启动Lighttpd并设置为开机自动启动:
1
[root@www ~]# /etc/init.d/lighttpd start
2

3
启动 lighttpd:[确定]
4

5
[root@www ~]# chkconfig –levels 235 lighttpd on

如果在启动的时候提示如下错误:
(network.c.203) socket failed: Address family not supported by protocol
则打开 /etc/lighttpd/lighttpd.conf 文件
1
vi /etc/lighttpd/lighttpd.conf
找到server.use-ipv6一行配置节,将enable改为disable,如下:
## Use IPv6?
##
server.use-ipv6 = “disable“
保存后再次执行启动(/etc/init.d/lighttpd start)即可。
此时,访问服务器的IP地址,应该提示一个大大的“404 – Not Found”。表示lighttpd已经正常运行(只是没有默认的文档,因此404错误了)。如下图:

3、安装php5与Lighttpd fastcgi组件
安装php非常方便,直接执行:
1
[root@www ~]# yum install lighttpd-fastcgi php-cli
即可安装成功。

4、配置Lighttpd与PHP5
将Lighttpd配置为fastCGI模式,只需要修改三个配置文件,并且比较简单。
1、打开 /etc/php.ini 文件
1
vi /etc/php.ini
在php.ini文件最后加如下一行语句并保存:
cgi.fix_pathinfo = 1
2、打开 /etc/lighttpd/modules.conf 文件:
1
vi /etc/lighttpd/modules.conf
将 include “conf.d/fastcgi.conf” 一行取消注释并保存,如下图:

3、打开 /etc/lighttpd/conf.d/fastcgi.conf 文件:
1
vi /etc/lighttpd/conf.d/fastcgi.conf
找到 fastcgi.server这一节配置段,并将其全部反注释(使之生效),并修改为如下(注意红色为修改部分):
fastcgi.server = ( “.php” =>
( “php-local” =>
(
“socket” => “/tmp/php-fastcgi-1.socket“,
“bin-path” => “/usr/bin/php-cgi“,
“max-procs” => 1,
“broken-scriptfilename” => “enable”,
)
),
( “php-tcp” =>
(
“host” => “127.0.0.1″,
“port” => 9999,
“check-local” => “disable”,
“broken-scriptfilename” => “enable”,
)
),
( “php-num-procs” =>
(
“socket” => “/tmp/php-fastcgi-2.socket“,
“bin-path” => “/usr/bin/php-cgi“,
“bin-environment” => (
“PHP_FCGI_CHILDREN” => “16″,
“PHP_FCGI_MAX_REQUESTS” => “10000″,
),
“max-procs” => 5,
“broken-scriptfilename” => “enable”,
)
),
)
最后保存即可。
现在可以重启Lighttpd使之生效:
1
[root@www ~]# /etc/init.d/lighttpd restart
2
停止 lighttpd:[确定]
3
启动 lighttpd:[确定]

5、测试PHP5与Lighttpd
由于 /srv/www/lighttpd/ 是其网站根目录,因此执行:
[root@www ~]# echo ‘’ > /srv/www/lighttpd/test.php
然后访问 http://IP/test.php 即可看到PHP Info测试页面:

6、安装PHP5的MySQL支持
1
[root@www ~]# yum install php-mysql php-gd php-imap php-ldap php-odbc php-pear php-xml php-xmlrpc
上述命令已经同时安装好了php的MySQL、GD图形库、IMAP、ODBC、Pear、xml等支持组件。

7、最终测试
重启Lighttpd并刷新 http://IP/test.php 页面,即可找到MySQL模块的支持。
至此,Lighttpd+PHP+MySQL+GD全套组件安装配置完毕。

原文链接:
http://www.bootf.com/499.html

Mysql Cluster快速安装

Mysql-Cluster使用percona可以快速正确的安装.

跟随官方网站的每一个步骤,走一遍基本可以.

http://www.percona.com/doc/percona-xtradb-cluster/5.6/howtos/cenots_howto.html

This tutorial will show how to install the Percona XtraDB Cluster on three CentOS 6.3 servers, using the packages from Percona repositories.

This cluster will be assembled of three servers/nodes:

node #1
hostname: percona1
IP: 192.168.70.71

node #2
hostname: percona2
IP: 192.168.70.72

node #3
hostname: percona3
IP: 192.168.70.73
Prerequisites

All three nodes have a CentOS 6.3 installation.
Firewall has been set up to allow connecting to ports 3306, 4444, 4567 and 4568
SELinux is disabled
Installation

Installation information can be found in the Installing Percona XtraDB Cluster from Binaries guide.

Configuring the nodes

Individual nodes should be configured to be able to bootstrap the cluster. More details about bootstrapping the cluster can be found in the Bootstrapping the cluster guide.

Configuration file /etc/my.cnf for the first node should look like:

[mysqld]

datadir=/var/lib/mysql
user=mysql

# Path to Galera library
wsrep_provider=/usr/lib64/libgalera_smm.so

# Cluster connection URL contains the IPs of node#1, node#2 and node#3
wsrep_cluster_address=gcomm://192.168.70.71,192.168.70.72,192.168.70.73

# In order for Galera to work correctly binlog format should be ROW
binlog_format=ROW

# MyISAM storage engine has only experimental support
default_storage_engine=InnoDB

# This changes how InnoDB autoincrement locks are managed and is a requirement for Galera
innodb_autoinc_lock_mode=2

# Node #1 address
wsrep_node_address=192.168.70.71

# SST method
wsrep_sst_method=xtrabackup-v2

# Cluster name
wsrep_cluster_name=my_centos_cluster

# Authentication for SST method
wsrep_sst_auth=”sstuser:s3cret”
After this, first node can be started with the following command:

[root@percona1 ~]# /etc/init.d/mysql bootstrap-pxc
This command will start the cluster with initial wsrep_cluster_address set to gcomm://. This way the cluster will be bootstrapped and in case the node or MySQL have to be restarted later, there would be no need to change the configuration file.

After the first node has been started, cluster status can be checked by:

mysql> show status like ‘wsrep%’;
+—————————-+————————————–+
| Variable_name | Value |
+—————————-+————————————–+
| wsrep_local_state_uuid | c2883338-834d-11e2-0800-03c9c68e41ec |

| wsrep_local_state | 4 |
| wsrep_local_state_comment | Synced |

| wsrep_cluster_size | 1 |
| wsrep_cluster_status | Primary |
| wsrep_connected | ON |

| wsrep_ready | ON |
+—————————-+————————————–+
40 rows in set (0.01 sec)
This output shows that the cluster has been successfully bootstrapped.

It’s recommended not to leave the empty password for the root account. Password can be changed with:

mysql@percona1> UPDATE mysql.user SET password=PASSWORD(“Passw0rd”) where user=’root’;
mysql@percona1> FLUSH PRIVILEGES;
In order to perform successful State Snapshot Transfer using XtraBackup new user needs to be set up with proper privileges:

mysql@percona1> CREATE USER ‘sstuser’@’localhost’ IDENTIFIED BY ‘s3cret’;
mysql@percona1> GRANT RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO ‘sstuser’@’localhost’;
mysql@percona1> FLUSH PRIVILEGES;
Note MySQL root account can also be used for setting up the SST with Percona XtraBackup, but it’s recommended to use a different (non-root) user for this.
Configuration file /etc/my.cnf on the second node (percona2) should look like this:

[mysqld]

datadir=/var/lib/mysql
user=mysql

# Path to Galera library
wsrep_provider=/usr/lib64/libgalera_smm.so

# Cluster connection URL contains IPs of node#1, node#2 and node#3
wsrep_cluster_address=gcomm://192.168.70.71,192.168.70.72,192.168.70.73

# In order for Galera to work correctly binlog format should be ROW
binlog_format=ROW

# MyISAM storage engine has only experimental support
default_storage_engine=InnoDB

# This changes how InnoDB autoincrement locks are managed and is a requirement for Galera
innodb_autoinc_lock_mode=2

# Node #2 address
wsrep_node_address=192.168.70.72

# Cluster name
wsrep_cluster_name=my_centos_cluster

# SST method
wsrep_sst_method=xtrabackup-v2

#Authentication for SST method
wsrep_sst_auth=”sstuser:s3cret”
Second node can be started with the following command:

[root@percona2 ~]# /etc/init.d/mysql start
After the server has been started it should receive the state snapshot transfer automatically. This means that the second node won’t have the empty root password anymore. In order to connect to the cluster and check the status changed root password from the first node should be used. Cluster status can now be checked on both nodes. This is the example from the second node (percona2):

mysql> show status like ‘wsrep%’;
+—————————-+————————————–+
| Variable_name | Value |
+—————————-+————————————–+
| wsrep_local_state_uuid | c2883338-834d-11e2-0800-03c9c68e41ec |

| wsrep_local_state | 4 |
| wsrep_local_state_comment | Synced |

| wsrep_cluster_size | 2 |
| wsrep_cluster_status | Primary |
| wsrep_connected | ON |

| wsrep_ready | ON |
+—————————-+————————————–+
40 rows in set (0.01 sec)
This output shows that the new node has been successfully added to the cluster.

MySQL configuration file /etc/my.cnf on the third node (percona3) should look like this:

[mysqld]

datadir=/var/lib/mysql
user=mysql

# Path to Galera library
wsrep_provider=/usr/lib64/libgalera_smm.so

# Cluster connection URL contains IPs of node#1, node#2 and node#3
wsrep_cluster_address=gcomm://192.168.70.71,192.168.70.72,192.168.70.73

# In order for Galera to work correctly binlog format should be ROW
binlog_format=ROW

# MyISAM storage engine has only experimental support
default_storage_engine=InnoDB

# This changes how InnoDB autoincrement locks are managed and is a requirement for Galera
innodb_autoinc_lock_mode=2

# Node #3 address
wsrep_node_address=192.168.70.73

# Cluster name
wsrep_cluster_name=my_centos_cluster

# SST method
wsrep_sst_method=xtrabackup-v2

#Authentication for SST method
wsrep_sst_auth=”sstuser:s3cret”
Third node can now be started with the following command:

[root@percona3 ~]# /etc/init.d/mysql start
After the server has been started it should receive the SST same as the second node. Cluster status can now be checked on both nodes. This is the example from the third node (percona3):

mysql> show status like ‘wsrep%’;
+—————————-+————————————–+
| Variable_name | Value |
+—————————-+————————————–+
| wsrep_local_state_uuid | c2883338-834d-11e2-0800-03c9c68e41ec |

| wsrep_local_state | 4 |
| wsrep_local_state_comment | Synced |

| wsrep_cluster_size | 3 |
| wsrep_cluster_status | Primary |
| wsrep_connected | ON |

| wsrep_ready | ON |
+—————————-+————————————–+
40 rows in set (0.01 sec)
This output confirms that the third node has joined the cluster.

Testing the replication

Although the password change from the first node has replicated successfully, this example will show that writing on any node will replicate to the whole cluster. In order to check this, new database will be created on second node and table for that database will be created on the third node.

Creating the new database on the second node:

mysql@percona2> CREATE DATABASE percona;
Query OK, 1 row affected (0.01 sec)
Creating the example table on the third node:

mysql@percona3> USE percona;
Database changed

mysql@percona3> CREATE TABLE example (node_id INT PRIMARY KEY, node_name VARCHAR(30));
Query OK, 0 rows affected (0.05 sec)
Inserting records on the first node:

mysql@percona1> INSERT INTO percona.example VALUES (1, ‘percona1’);
Query OK, 1 row affected (0.02 sec)
Retrieving all the rows from that table on the second node:

mysql@percona2> SELECT * FROM percona.example;
+———+———–+
| node_id | node_name |
+———+———–+
| 1 | percona1 |
+———+———–+
1 row in set (0.00 sec)
This small example shows that all nodes in the cluster are synchronized and working as intended.

若, 想要看到出错日志, 则可以在my.cnf中加上以下两行:
log_error = /data3/mysql/data/mysql-error.log
slow_query_log_file = /data3/mysql/data/mysql-slow.log
其中等号后面的是存放error-log, query-log的绝对路径.
通过查看出错日志,一步步排除错误.

MySQL中授权(grant)和撤销授权(revoke)

授权命令:

grant select,delete on database.table to user@’ip/localhost’ identified by ‘password’

取消授权:

revoke select,delete on database.table to user@’ip/localhost’ identified by ‘password’

注意,revoke只能取消用户的某权利(select,delete,update等),而即使取消掉所有权利,该用户还仍然存在.该用户仍然可以登陆该mysql.

若想要删掉该用户行,或者不让该用户从某一地址登陆,则只能使用delete命令删除掉mysql.user表中对应的行.

命令:

delete from mysql.user where user=’username’ and host = ‘hostip/localhost’;

你懂的.

 

权限变更或者用户变更之后需要立即刷新授权列表,才能生效.

命令:

flush privileges;

 

参阅文章:

http://blog.csdn.net/andy_yf/article/details/7487519

http://leeon.me/a/mysql-delete-authorization

MongoDB 学习笔记(python操作)

交流QQ群:26651479
一、MongoDB 数据库操作
1. 连接数据库
import pymongo
conn = pymongo.Connection() # 连接本机数据库
# conn = pymongo.Connection(host=”192.168.1.202″) # 连接指定IP的数据库
db = conn.test # 进入指定名称的数据库
users = db.users # 获取数据库里的 users 集合
users = db[‘users’] # 获取数据库里的 users 集合,也可以用字典来获取

2. 插入
u = dict(name = “user1”, age = 23)
# db.users.save(u) # 用 save 也可以插入
db.users.insert(u) # 将数据插入到 users 集合

3. 更新
# 更新指定一条记录
u2 = db.users.find_one({“name”:”user9″})
u2[‘age’] += 3
db.users.save(u2)

# 更新多条记录
db.users.update({“name”:”user1″}, {“$set”:{“age”:100, “sex”:0}}) # update users set age = 100, sex = 0 where name = ‘user1’
db.users.update({}, {“$inc”:{“age”:10}}, multi=True) # update users set age = age + 10
db.users.update({“name”:”user1″}, {“$inc”:{“age”:10}, “$set”:{“sex”:1}}) # update users set age = age + 10, sex = 1 where name = ‘user1’

# update() 有几个参数需要注意:
db.集合名.update(criteria, objNew, upsert, mult)
criteria: 需要被更新的条件表达式
objNew: 更新表达式
upsert: 如目标记录不存在,是否插入新文档。
multi: 是否更新多个文档。

4. 删除
db.users.drop()  # 删除集合

# remove() 用于删除单个或全部文档,删除后的文档无法恢复。
id = db.users.find_one({“name”:”user2″})[“_id”]
db.users.remove(id)  # 根据 id 删除一条记录
db.users.remove()  # 删除集合里的所有记录
db.users.remove({‘yy’:5}) # 删除yy=5的记录

5. 查询
# 查询 age 小于 15 的
for u in db.users.find({“age”:{“$lt”:15}}): print u

5.1 查询一条记录
# 查询 name 等于 user8 的
for u in db.users.find({“name”:”user8″}): print u

# 获取查询的一个
u2 = db.users.find_one({“name”:”user9″}) # 查不到时返回 None
print u2

5.2 查询特定键 (fields)
# select name, age from users where age = 21
for u in db.users.find({“age”:21}, [“name”, “age”]): print u
for u in db.users.find(fields = [“name”, “age”]): print u

5.3 排序(SORT)
pymongo.ASCENDING  # 也可以用 1 来代替
pymongo.DESCENDING # 也可以用 -1 来代替
for u in db.users.find().sort([(“age”, pymongo.ASCENDING)]): print u   # select * from 集合名 order by 键1
for u in db.users.find().sort([(“age”, pymongo.DESCENDING)]): print u  # select * from 集合名 order by 键1 desc
for u in db.users.find().sort([(“键1”, pymongo.ASCENDING), (“键2”, pymongo.DESCENDING)]): print u # select * from 集合名 order by 键1 asc, 键2 desc
for u in db.users.find(sort = [(“键1”, pymongo.ASCENDING), (“键2”, pymongo.DESCENDING)]): print u # sort 的另一种写法
for u in db.users.find({“name”:”user9″}, sort=[[‘name’,1],[‘sex’,1]], fields = [“name”, “age”, ‘sex’]): print u  # 组合写法

5.4 从第几行开始读取(SLICE),读取多少行(LIMIT)
# select * from 集合名 skip 2 limit 3
# MySQL 的写法: select * from 集合名 limit 2, 3
for u in db.users.find().skip(2).limit(3): print u
for u in db.users.find(skip = 2, limit = 3): print u

# 可以用切片代替 skip & limit (mongo 中的 $slice 貌似有点问题)。
for u in db.users.find()[2:5]: print u

# 单独的写
for u in db.users.find().skip(2): print u
for u in db.users.find(skip=1): print u
for u in db.users.find().limit(5): print u
for u in db.users.find(limit = 3): print u

5.5 多条件查询(Conditional Operators)    # like 的可使用正则表达式查询
# select * from users where name = ‘user3’ and age > 12 and age < 15
for u in db.users.find({‘age’: {‘$gt’: 12, ‘$lt’: 15}, ‘name’: ‘user3’}): print u
# select * from users where name = ‘user1’ and age = 21
for u in db.users.find({“age”:21, “name”:”user1″}): print u

5.6 IN
for u in db.users.find({“age”:{“$in”:(23, 26, 32)}}): print u   # select * from users where age in (23, 26, 32)
for u in db.users.find({“age”:{“$nin”:(23, 26, 32)}}): print u  # select * from users where age not in (23, 26, 32)

5.7 统计总数(COUNT)
print(db.users.count())  # select count(*) from users
print(db.users.find({“age”:{“$gt”:30}}).count()) # select count(*) from users where age > 30

5.8 OR
for u in db.users.find({“$or”:[{“age”:25}, {“age”:28}]}): print u  # select * from 集合名 where 键1 = 值1 or 键1 = 值2
for u in db.users.find({“$or”:[{“age”:{“$lte”:23}}, {“age”:{“$gte”:33}}]}): print u  # select * from 集合名 where 键1 <= 值1 or 键1 >= 值2

6. 是否存在 (exists)
db.users.find({‘sex’:{‘$exists’:True}})  # select * from 集合名 where exists 键1
db.users.find({‘sex’:{‘$exists’:False}}) # select * from 集合名 where not exists 键1

7. 正则表达式查询
for u in db.users.find({“name” : {“$regex” : r”(?i)user[135]”}}, [“name”]): print u # 查询出 name 为 user1, user3, user5 的

8. 多级路径的元素值匹配
Document 采取 JSON-like 这种层级结构,因此我们可以直接用嵌入(Embed)代替传统关系型数据库的关联引用(Reference)。
MongoDB 支持以 “.” 分割的 namespace 路径,条件表达式中的多级路径须用引号

# 如果键里面包含数组,只需简单匹配数组属性是否包含该元素即可查询出来
db.集合名.find_one({‘address’:”address1″}) # address 是个数组,匹配时仅需包含有即可
# 查询结果如:{“_id” : ObjectId(“4c479885089df9b53474170a”), “name” : “user1”, “address” : [“address1”, “address2”]}

# 条件表达式中的多级路径须用引号,以 “.” 分割
u = db.集合名.find_one({“im.qq”:12345678})
# 查询结果如:{“_id” : ObjectId(“4c479885089df9b53474170a”), “name” : “user1”, “im” : {“msn” : “user1@hotmail.com“, “qq” : 12345678}}

print u[‘im’][‘msn’]  #显示: user1@hotmail.com

# 多级路径的更新
db.集合名.update({“im.qq”:12345678}, {‘$set’:{“im.qq”:12345}})

# 查询包含特定键的
for u in db.users.find({“im.qq”:{‘$exists’:True}}, {“im.qq”:1}): print u
# 显示如: { “_id” : ObjectId(“4c479885089df9b53474170a”), “im” : { “qq” : 12345 } }
for u in db.users.find({‘data’:”abc”}): print u
# 显示如: { “_id” : ObjectId(“4c47a481b48cde79c6780df5”), “name” : “user8”, “data” : [ { “a” : 1, “b” : 10 }, 3, “abc” ] }
for u in db.users.find({‘data’:{‘$elemMatch’:{‘a’:1, ‘b’:{‘$gt’:5}}}}): print u
# 显示如: { “_id” : ObjectId(“4c47a481b48cde79c6780df5”), “name” : “user8”, “data” : [ { “a” : 1, “b” : 10 }, 3, “abc” ] }
{data:”abc”} 仅简单匹配数组属性是否包含该元素。$elemMatch 则可以处理更复杂的元素查找条件。当然也可以写成如下方式:
db.集合名.find({“data.a”:1, “data.b”:{‘$gt’:5}})

对数组, 还可以直接使用序号进行操作:
db.集合名.find({“data.1”:3}) # 序号从0开始
# 如集合的一列内容
{“classifyid”:”test1″,
“keyword”:[
{“name”:’test1′, # 将修改此值为 test5 (数组下标从0开始,下标也是用点)
“frequence”:21,
},
{“name”:’test2′, # 子表的查询,会匹配到此值
“frequence”:50,
},
]
}
# 子表的修改(子表的其它内容不变)
db.集合名.update({“classifyid”:”test1″}, {“$set”:{“keyword.0.name”:’test5′}})
# 子表的查询
db.集合名.find({“classifyid”:”test1″, “keyword.0.name”:”test2″})
操作符
$lt         小于
$lte        小于等于
$gt         大于
$gte        大于等于
$ne         不等于
$in         in  检查目标属性值是条件表达式中的一员
$nin        not in
$set        set(用于 update 语句)
$unset      与 $set 相反,表示移除文档属性。
$inc        += (用于 update 语句)
$exists     exists (判断是否存在,仅有 True 和 False 两个值)
$all        属性值包含全部条件元素,注意和 $in 的区别
$size       匹配数组属性元素的数量
$type       判断属性类型
$regex      正则表达式查询
$elemMatch  子属性里的查询
$push       向数组属性添加元素
$pushAll    向数组属性添加元素
$addToSet   和 $push 类似,不过仅在该元素不存在时才添加 (Set 表示不重复元素集合)
$each       添加多个元素用
$pop        移除数组属性的元素(按数组下标移除)
$pull       按值移除
$pullAll    移除所有符合提交的元素
$where      用 JS 代码来代替有些丑陋的 $lt、$gt

 
二、Operator
(1) $all: 判断数组属性是否包含全部条件。
db.users.insert({‘name’:”user3″, ‘data’:[1,2,3,4,5,6,7]})
db.users.insert({‘name’:”user4″, ‘data’:[1,2,3]})

for u in db.users.find({‘data’:{‘$all’:[2,3,4]}}): print u
# 显示: { “_id” : ObjectId(“4c47a133b48cde79c6780df0”), “name” : “user3”, “data” : [ 1, 2, 3, 4, 5, 6, 7 ] }
注意和 $in 的区别。$in 是检查目标属性值是条件表达式中的一员,而 $all 则要求属性值包含全部条件元素。

(2) $size: 匹配数组属性元素数量。
for u in db.users.find({‘data’:{‘$size’:3}}): print u
# 只显示匹配此数组数量的: { “_id” : ObjectId(“4c47a13bb48cde79c6780df1”), “name” : “user4”, “data” : [ 1, 2, 3 ] }

(3) $type: 判断属性类型。
for u in db.users.find({‘t’:{‘$type’:1}}): print u  # 查询数字类型的
for u in db.users.find({‘t’:{‘$type’:2}}): print u  # 查询字符串类型的

类型值:
double:1
string: 2
object: 3
array: 4
binary data: 5
object id: 7
boolean: 8
date: 9
null: 10
regular expression: 11
javascript code: 13
symbol: 14
javascript code with scope: 15
32-bit integer: 16
timestamp: 17
64-bit integer: 18
min key: 255
max key: 127

(4) $not: 取反,表示返回条件不成立的文档。
似乎只能跟正则和 $mod 一起使用????
# 还不知如何使用

(5) $unset: 和 $set 相反,表示移除文档属性。
for u in db.users.find({‘name’:”user1″}): print u
# 显示如: { “_id” : ObjectId(“4c479885089df9b53474170a”), “name” : “user1”, “age” : 15, “address” : [ “address1”, “address2″ ] }

db.users.update({‘name’:”user1″}, {‘$unset’:{‘address’:1, ‘age’:1}})
for u in db.users.find({‘name’:”user1”}): print u
# 显示如: { “_id” : ObjectId(“4c479885089df9b53474170a”), “name” : “user1″ }

(6) $push: 和 $ pushAll 都是向数组属性添加元素。# 好像两者没啥区别
for u in db.users.find({‘name’:”user1”}): print u
# 显示如: { “_id” : ObjectId(“4c479885089df9b53474170a”), “age” : 15, “name” : “user1″ }

db.users.update({‘name’:”user1″}, {‘$push’:{‘data’:1}})
for u in db.users.find({‘name’:”user1”}): print u
# 显示如: { “_id” : ObjectId(“4c479885089df9b53474170a”), “age” : 15, “data” : [ 1 ], “name” : “user1″ }

db.users.update({‘name’:”user1″}, {‘$pushAll’:{‘data’:[2,3,4,5]}})
for u in db.users.find({‘name’:”user1”}): print u
# 显示如: { “_id” : ObjectId(“4c479885089df9b53474170a”), “age” : 15, “data” : [ 1, 2, 3, 4, 5 ], “name” : “user1″ }

(7) $addToSet: 和 $push 类似,不过仅在该元素不存在时才添加 (Set 表示不重复元素集合)。
db.users.update({‘name’:”user2″}, {‘$unset’:{‘data’:1}})
db.users.update({‘name’:”user2″}, {‘$addToSet’:{‘data’:1}})
db.users.update({‘name’:”user2″}, {‘$addToSet’:{‘data’:1}})
for u in db.users.find({‘name’:”user2”}): print u
# 显示: { “_id” : ObjectId(“4c479896089df9b53474170b”), “data” : [ 1 ], “name” : “user2″ }

db.users.update({‘name’:”user2″}, {‘$push’:{‘data’:1}})
for u in db.users.find({‘name’:”user2”}): print u
# 显示: { “_id” : ObjectId(“4c479896089df9b53474170b”), “data” : [ 1, 1 ], “name” : “user2″ }

要添加多个元素,使用 $each。
db.users.update({‘name’:”user2″}, {‘$addToSet’:{‘data’:{‘$each’:[1,2,3,4]}}})
for u in db.users.find({‘name’:”user2″}): print u
# 显示: {u’age’: 12, u’_id’: ObjectId(‘4c479896089df9b53474170b’), u’data’: [1, 1, 2, 3, 4], u’name’: u’user2′}
# 貌似不会自动删除重复

(8) $each 添加多个元素用。
db.users.update({‘name’:”user2″}, {‘$unset’:{‘data’:1}})
db.users.update({‘name’:”user2″}, {‘$addToSet’:{‘data’:1}})
for u in db.users.find({‘name’:”user2”}): print u
# 显示: { “_id” : ObjectId(“4c479896089df9b53474170b”), “data” : [ 1 ], “name” : “user2″ }

db.users.update({‘name’:”user2″}, {‘$addToSet’:{‘data’:{‘$each’:[1,2,3,4]}}})
for u in db.users.find({‘name’:”user2″}): print u
# 显示: {u’age’: 12, u’_id’: ObjectId(‘4c479896089df9b53474170b’), u’data’: [1, 2, 3, 4], u’name’: u’user2′}

db.users.update({‘name’:”user2″}, {‘$addToSet’:{‘data’:[1,2,3,4]}})
for u in db.users.find({‘name’:”user2”}): print u
# 显示: { “_id” : ObjectId(“4c479896089df9b53474170b”), “data” : [ 1, 2, 3, 4, [ 1, 2, 3, 4 ] ], “name” : “user2″ }

db.users.update({‘name’:”user2″}, {‘$unset’:{‘data’:1}})
db.users.update({‘name’:”user2″}, {‘$addToSet’:{‘data’:[1,2,3,4]}})
for u in db.users.find({‘name’:”user2”}): print u
# 显示: { “_id” : ObjectId(“4c47a133b48cde79c6780df0”), “data” : [ [1, 2, 3, 4] ], “name” : “user2″ }

(9) $pop: 移除数组属性的元素(按数组下标移除),$pull 按值移除,$pullAll 移除所有符合提交的元素。
db.users.update({‘name’:”user2″}, {‘$unset’:{‘data’:1}})
db.users.update({‘name’:”user2″}, {‘$addToSet’:{‘data’:{‘$each’:[1, 2, 3, 4, 5, 6, 7, 2, 3 ]}}})
for u in db.users.find({‘name’:”user2”}): print u
# 显示: { “_id” : ObjectId(“4c47a133b48cde79c6780df0”), “data” : [ 1, 2, 3, 4, 5, 6, 7, 2, 3 ], “name” : “user2″ }

db.users.update({‘name’:”user2″}, {‘$pop’:{‘data’:1}}) # 移除最后一个元素
for u in db.users.find({‘name’:”user2”}): print u
# 显示: { “_id” : ObjectId(“4c47a133b48cde79c6780df0”), “data” : [ 1, 2, 3, 4, 5, 6, 7, 2 ], “name” : “user2″ }

db.users.update({‘name’:”user2″}, {‘$pop’:{‘data’:-1}}) # 移除第一个元素
for u in db.users.find({‘name’:”user2”}): print u
# 显示: { “_id” : ObjectId(“4c47a133b48cde79c6780df0”), “data” : [ 2, 3, 4, 5, 6, 7, 2 ], “name” : “user2″ }

db.users.update({‘name’:”user2″}, {‘$pull’:{‘data’:2}}) # 移除全部 2
for u in db.users.find({‘name’:”user2”}): print u
# 显示: { “_id” : ObjectId(“4c47a133b48cde79c6780df0”), “data” : [ 3, 4, 5, 6, 7 ], “name” : “user2″ }

db.users.update({‘name’:”user2″}, {‘$pullAll’:{‘data’:[3,5,6]}}) # 移除 3,5,6
for u in db.users.find({‘name’:”user2”}): print u
# 显示: { “_id” : ObjectId(“4c47a133b48cde79c6780df0”), “data” : [ 4, 7 ], “name” : “user2″ }

(10) $where: 用 JS 代码来代替有些丑陋的 $lt、$gt。
MongoDB 内置了 Javascript Engine (SpiderMonkey)。可直接使用 JS Expression,甚至使用 JS Function 写更复杂的 Code Block。

db.users.remove() # 删除集合里的所有记录
for i in range(10):
db.users.insert({‘name’:”user” + str(i), ‘age’:i})
for u in db.users.find(): print u
# 显示如下:
{ “_id” : ObjectId(“4c47b3372a9b2be866da226e”), “name” : “user0”, “age” : 0 }
{ “_id” : ObjectId(“4c47b3372a9b2be866da226f”), “name” : “user1”, “age” : 1 }
{ “_id” : ObjectId(“4c47b3372a9b2be866da2270”), “name” : “user2”, “age” : 2 }
{ “_id” : ObjectId(“4c47b3372a9b2be866da2271”), “name” : “user3”, “age” : 3 }
{ “_id” : ObjectId(“4c47b3372a9b2be866da2272”), “name” : “user4”, “age” : 4 }
{ “_id” : ObjectId(“4c47b3372a9b2be866da2273”), “name” : “user5”, “age” : 5 }
{ “_id” : ObjectId(“4c47b3372a9b2be866da2274”), “name” : “user6”, “age” : 6 }
{ “_id” : ObjectId(“4c47b3372a9b2be866da2275”), “name” : “user7”, “age” : 7 }
{ “_id” : ObjectId(“4c47b3372a9b2be866da2276”), “name” : “user8”, “age” : 8 }
{ “_id” : ObjectId(“4c47b3372a9b2be866da2277”), “name” : “user9”, “age” : 9 }

for u in db.users.find({“$where”:”this.age > 7 || this.age < 3″}): print u
# 显示如下:
{u’age’: 0.0, u’_id’: ObjectId(‘4c47b3372a9b2be866da226e’), u’name’: u’user0′}
{u’age’: 1.0, u’_id’: ObjectId(‘4c47b3372a9b2be866da226f’), u’name’: u’user1′}
{u’age’: 2.0, u’_id’: ObjectId(‘4c47b3372a9b2be866da2270′), u’name’: u’user2′}
{u’age’: 8.0, u’_id’: ObjectId(‘4c47b3372a9b2be866da2276′), u’name’: u’user8′}
{u’age’: 9.0, u’_id’: ObjectId(‘4c47b3372a9b2be866da2277′), u’name’: u’user9′}

for u in db.users.find().where(“this.age > 7 || this.age < 3”): print u
# 显示如下:
{u’age’: 0.0, u’_id’: ObjectId(‘4c47b3372a9b2be866da226e’), u’name’: u’user0′}
{u’age’: 1.0, u’_id’: ObjectId(‘4c47b3372a9b2be866da226f’), u’name’: u’user1′}
{u’age’: 2.0, u’_id’: ObjectId(‘4c47b3372a9b2be866da2270′), u’name’: u’user2′}
{u’age’: 8.0, u’_id’: ObjectId(‘4c47b3372a9b2be866da2276′), u’name’: u’user8′}
{u’age’: 9.0, u’_id’: ObjectId(‘4c47b3372a9b2be866da2277′), u’name’: u’user9′}

# 使用自定义的 function, javascript语法的
for u in db.users.find().where(“function() { return this.age > 7 || this.age < 3;}”): print u
# 显示如下:
{u’age’: 0.0, u’_id’: ObjectId(‘4c47b3372a9b2be866da226e’), u’name’: u’user0′}
{u’age’: 1.0, u’_id’: ObjectId(‘4c47b3372a9b2be866da226f’), u’name’: u’user1′}
{u’age’: 2.0, u’_id’: ObjectId(‘4c47b3372a9b2be866da2270′), u’name’: u’user2′}
{u’age’: 8.0, u’_id’: ObjectId(‘4c47b3372a9b2be866da2276′), u’name’: u’user8′}
{u’age’: 9.0, u’_id’: ObjectId(‘4c47b3372a9b2be866da2277′), u’name’: u’user9′}

 

三、封装查询工具类

{“age”:{“$lt”:15}} 这样的查询语法实在太另类,忒难看了。试试封装查询工具类吧。原理很简单,就是重载操作符。

from pymongo import *
conn = Connection()
db = conn.test

# 插入数据
for i in range(10):
u = dict(name = “user” + str(i), age = 10 + i)
db.users.insert(u)

# 查询 age 小于 15 的
for u in db.users.find({“age”:{“$lt”:15}}): print u

# 查询结果如下:
{u’age’: 10, u’_id’: ObjectId(‘4c9b7465499b1408f1000000′), u’name’: u’user0′}
{u’age’: 11, u’_id’: ObjectId(‘4c9b7465499b1408f1000001′), u’name’: u’user1′}
{u’age’: 12, u’_id’: ObjectId(‘4c9b7465499b1408f1000002′), u’name’: u’user2′}
{u’age’: 13, u’_id’: ObjectId(‘4c9b7465499b1408f1000003′), u’name’: u’user3′}
{u’age’: 14, u’_id’: ObjectId(‘4c9b7465499b1408f1000004′), u’name’: u’user4′}
################# 查询工具类 start #################################
class Field(object):
def __init__(self, name):
self.name = name

# 小于
def __lt__(self, value):
return { self.name: { “$lt”:value } }
# 小于等于
def __le__(self, value):
return { self.name: { “$lte”:value } }

# 大于
def __gt__(self, value):
return { self.name: { “$gt”:value } }
# 大于等于
def __ge__(self, value):
return { self.name: { “$gte”:value } }

# 等于
def __eq__(self, value):
return { self.name: value }
# 不等于
def __ne__(self, value):
return { self.name: { “$ne”:value } }

# in (由于 in 是关键字,故该用首字母大写来避免冲突)
def In(self, *value):
return { self.name: { “$in”:value } }
# not in
def not_in(self, *value):
return { self.name: { “$nin”:value } }

def all(self, *value):
”’
注意和 in 的区别。in 是检查目标属性值是条件表达式中的一员,而 all 则要求属性值包含全部条件元素。
”’
return { self.name: { “$all”:value } }

def size(self, value):
”’
匹配数组属性元素的数量
”’
return { self.name: { “$size”:value } }

def type(self, value):
”’
判断属性类型
@param value 可以是类型码数字,也可以是类型的字符串
”’
# int 类型,则认为是属性类型的编码,不再做其它处理
if type(value) is int and value >= 1 and value <= 255:
return { self.name: { “$type”:value } }
if type(value) is str:
value = value.strip().lower()
code = 2 # 默认为字符串类型
# 数字类型
if value in (“int”, “integer”, “long”, “float”, “double”, “short”, “byte”, “number”):
code = 1
# 字符串类型
elif value in (“str”, “string”, “unicode”):
code = 2
# object 类型
elif value == “object”:
code = 3
# array 类型
elif value in (“array”, “list”, “tuple”):
code = 4
# binary data 类型
elif value in (“binary data”, “binary”):
code = 5
# object id 类型
elif value in (“object id”, “id”):
code = 7
# boolean 类型
elif value in (“boolean”, “bool”):
code = 8
# date 类型
elif value == “date”:
code = 9
# null 类型
elif value in (“null”, “none”):
code = 10
# regular expression 类型
elif value in (“regular expression”, “regular”):
code = 11
# javascript code 类型
elif value in (“javascript code”, “javascript”, “script”):
code = 13
# symbol 类型
elif value == “symbol”:
code = 14
# javascript code with scope 类型
elif value == “javascript code with scope”:
code = 15
# 32-bit integer 类型
elif value in (“32-bit integer”, “32-bit”):
code = 16
# timestamp 类型
elif value in (“timestamp”, “time”):
code = 17
# 64-bit integer 类型
elif value in (“64-bit integer”, “64-bit”):
code = 18
# min key 类型
elif value == “min key”:
code = 255
# max key 类型
elif value == “max key”:
code = 127
return { self.name: { “$type”:code } }
# 查询工具类 使用范例
age = Field(“age”)
# 查询 age 小于 15 的
for u in db.users.find(age < 15): print u

# 查询结果如下:
{u’age’: 10, u’_id’: ObjectId(‘4c9b7465499b1408f1000000′), u’name’: u’user0′}
{u’age’: 11, u’_id’: ObjectId(‘4c9b7465499b1408f1000001′), u’name’: u’user1′}
{u’age’: 12, u’_id’: ObjectId(‘4c9b7465499b1408f1000002′), u’name’: u’user2′}
{u’age’: 13, u’_id’: ObjectId(‘4c9b7465499b1408f1000003′), u’name’: u’user3′}
{u’age’: 14, u’_id’: ObjectId(‘4c9b7465499b1408f1000004′), u’name’: u’user4′}

# 其它查询写法例如:
for u in db.users.find(age <= 12): print u
for u in db.users.find(age > 17): print u
for u in db.users.find(age == 15): print u
for u in db.users.find(age != 15): print u
# 查询 name 为 user2 的
for u in db.users.find(Field(“name”) == “user2”): print u

# in 和 not in 的写法较之前的不同(可考虑更优雅的写法)
for u in db.users.find(age.In(13,14)): print u  # in
for u in db.users.find(age.not_in(13,14)): print u  # not in
for u in db.users.find(Field(“data”).all(1,2,3)): print u  # all: 查询data数组中至少包含 1、2、3 的
for u in db.users.find(Field(“data”).size(3)): print u # size: 查询data数组的长度为3的
# for u in db.users.find({‘t’:{‘$type’:1}}): print u
for u in db.users.find(Field(“t”).type(“number”)): print u # 按类型查询,结果同上句

################# 查询工具类 end #################################
################# 多条件查询工具类 start #################################
# (下面的 AND 函数很简陋,仅用于演示,不建议用于正式场合)
import copy
def AND(*args):
ret = copy.deepcopy(args[0])

for d in args[1:]:
for k, v in d.items():
if k in ret and type(v) is dict:
ret[k].update(v)
else:
ret[k] = v

return ret
# 多条件查询工具类 使用范例
age = Field(“age”)
AND(name == “user3”, age > 12, age < 15)
# 相当于如下写法:
{‘age’: {‘$gt’: 12, ‘$lt’: 15}, ‘name’: ‘user3’}

# 使用多条件查询范例
for u in db.users.find(AND(age > 12, age < 15)): print u
for u in db.users.find(AND(name == “user3”, age > 12, age < 15)): print u

################# 多条件查询工具类 end #################################

 
四、索引(Index)
索引信息被保存在 system.indexes 中,且默认总是为 _id 创建索引。

1. 创建、查看索引
# 查看索引
for u in db.system.indexes.find(): print u
# 显示: { “name” : “_id_”, “ns” : “test.users”, “key” : { “_id” : 1 }, ‘v’: 0 }

# 删除 集合的全部索引(不包括 _id 等系统索引)
db.users.drop_indexes()

# 创建索引
db.users.ensure_index([(“name”, pymongo.ASCENDING)]) # 相当于js的: db.users.ensureIndex({name:1})
db.users.ensure_index([(“name”, pymongo.ASCENDING), (“age”, pymongo.DESCENDING)]) # 相当于js的: db.users.ensureIndex({name:1, age:-1})

# 删除指定索引
db.users.drop_index([(“name”, pymongo.ASCENDING)])
db.users.drop_index([(“name”, pymongo.ASCENDING), (“age”, pymongo.DESCENDING)])

# 重建索引,在python里不知道怎么写
db.users.reIndex() # 会报错
2. explain
explain 命令让我们获知系统如何处理查询请求。
利用 explain 命令,我们可以很好地观察系统如何使用索引来加快检索,同时可以针对性优化索引。

print db.users.find({‘age’:{‘$gt’:4}}).explain()
# 显示如: {u’nYields’: 0, u’allPlans’: [{u’cursor’: u’BtreeCursor age_1′, u’indexBounds’: {u’age’: [[4, 1.7976931348623157e+308]]}}], u’nChunkSkips’: 0, u’millis’: 0, u’n’: 0, u’cursor’: u’BtreeCursor age_1′, u’indexBounds’: {u’age’: [[4, 1.7976931348623157e+308]]}, u’nscannedObjects’: 0, u’isMultiKey’: False, u’indexOnly’: False, u’nscanned’: 0}

# 深层索引
print db.users.find({“contact”:{“postcode”:{“$lt”:100009}}}).explain()
# 显示如: {u’nYields’: 0, u’allPlans’: [{u’cursor’: u’BtreeCursor contact_1′, u’indexBounds’: {u’contact’: [[{u’postcode’: {u’$lt’: 100009}}, {u’postcode’: {u’$lt’: 100009}}]]}}], u’nChunkSkips’: 0, u’millis’: 0, u’n’: 0, u’cursor’: u’BtreeCursor contact_1′, u’indexBounds’: {u’contact’: [[{u’postcode’: {u’$lt’: 100009}}, {u’postcode’: {u’$lt’: 100009}}]]}, u’nscannedObjects’: 0, u’isMultiKey’: False, u’indexOnly’: False, u’nscanned’: 0}

print db.users.find({“contact.postcode”:{“$lt”:100009}}).explain()
# 显示如: {u’nYields’: 0, u’allPlans’: [{u’cursor’: u’BtreeCursor contact.postcode_1′, u’indexBounds’: {u’contact.postcode’: [[-1.7976931348623157e+308, 100009]]}}], u’nChunkSkips’: 0, u’millis’: 0, u’n’: 9, u’cursor’: u’BtreeCursor contact.postcode_1′, u’indexBounds’: {u’contact.postcode’: [[-1.7976931348623157e+308, 100009]]}, u’nscannedObjects’: 9, u’isMultiKey’: False, u’indexOnly’: False, u’nscanned’: 9}

返回结果信息包括:
cursor: 返回游标类型(BasicCursor 或 BtreeCursor)。
nscanned: 被扫描的文档数量。
n: 返回的文档数量。
millis: 耗时(毫秒)。
indexBounds: 所使用的索引。
5. 唯一索引(Unique Index) # 未知怎样使用
只需在 ensureIndex 命令中指定 unique 即可创建唯一索引。
如果创建唯一索引前已经有重复文档,那么可以用 dropDups 删除多余的数据。

# 不允许重复,但之前已经重复的不会被删除
db.users.ensure_index({name:1}, {unique:true})
# 还会删除之前重复的资料
db.users.ensure_index({name:1}, {unique:true, dropDups:true})
7. hint
hint 命令可以强制使用某个索引。
db.users.find({“age”:{“$lt”:30}}).hint([(“name”, pymongo.ASCENDING), (“age”, pymongo.DESCENDING)]).explain()
8. 全部索引数据大小(totalIndexSize) # 未知如何实现
MongoDB 会将索引数据载入内存,以提高查询速度。我们可以用 totalIndexSize 获取全部索引数据大小。
db.users.totalIndexSize()

 

五、Map/Reduce
执行函数:
db.runCommand(
{
mapreduce : <collection>,
map : <mapfunction>,
reduce : <reducefunction>
[, query : <query filter object>]
[, sort : <sort the query.  useful   optimization>] for
[, limit : <number of objects to   from collection>] return
[, out : <output-collection name>]
[, keeptemp: < | >] true false
[, finalize : <finalizefunction>]
[, scope : <object where fields go into javascript global scope >]
[, verbose :  ] true
});

参数说明:
mapreduce: 要操作的目标集合。
map: 映射函数 (生成键值对序列,作为 reduce 函数参数)。
reduce: 统计函数。
query: 目标记录过滤。
sort: 目标记录排序。
limit: 限制目标记录数量。
out: 统计结果存放集合 (不指定则使用临时集合,在客户端断开后自动删除)。
keeptemp: 是否保留临时集合。
finalize: 最终处理函数 (对 reduce 返回结果进行最终整理后存入结果集合)。
scope: 向 map、reduce、finalize 导入外部变量。
verbose: 显示详细的时间统计信息。
例:
# 表如下:
record = {
“ci” : “test_classify”,
“si” : number,
“ac” : random.randint(1, 50),
“ic” : random.randint(1, 50),
“cv” : random.randint(1, 50),
“ao” : datetime.datetime.strptime(‘%Y-%m-%d %H:%M:%S’),
“ssi” : number,
}

# map 生成 key 序列, 必须使用 emit 函数
map = “””function () {
emit({classifyid: this.ci, siteid: this.si}, {archivecount: this.ac});
}”””

# 对 key 的处理,以及返回值
reduce = “””function (key, values) {
var total = 0;
for (var i = 0; i < values.length; i++) {
total += values[i].archivecount;
}
return {archivecount:total};
}”””

condition = {“ci” : “test_classify”}
result = db[TABLE].map_reduce(map, reduce, “temp_top10”, keeptemp=False, query=condition)
result = result.find().sort(‘value.archivecount’, -1).limit(10)

From :  http://blog.csdn.net/daillo/article/details/7030910

MySQL导入.sql文件及常用命令

MySQL导入.sql文件及常用命令

 

 

在MySQL Qurey   Brower中直接导入*.sql脚本,是不能一次执行多条sql命令的,在mysql中执行sql文件的命令:

mysql> source   d:/myprogram/database/db.sql;

另附mysql常用命令:

一) 连接MYSQL:

格式: mysql -h主机地址 -u用户名 -p用户密码

1、例1:连接到本机上的MYSQL

首先在打开DOS窗口,然后进入mysql安装目录下的bin目录下,例如: D:/mysql/bin,再键入命令mysql -uroot -p,回车后提示你输密码,如果刚安装好MYSQL,超级用户root是没有密码的,故直接回车即可进入到MYSQL中了,MYSQL的提示符是:mysql>

2、例2:连接到远程主机上的MYSQL (远程:IP地址)

假设远程主机的IP为:10.0.0.1,用户名为root,密码为123。则键入以下命令:

mysql -h10.0.0.1 -uroot -p123

(注:u与root可以不用加空格,其它也一样)

3、退出MYSQL命令

exit (回车)

(二) 修改密码:

格式:mysqladmin -u用户名 -p旧密码 password 新密码

1、例1:给root加个密码123。首先在DOS下进入目录C:/mysql/bin,然后键入以下命令:

mysqladmin -uroot -password 123

注:因为开始时root没有密码,所以-p旧密码一项就可以省略了。

2、例2:再将root的密码改为456

mysqladmin -uroot -pab12 password 456

(三) 增加新用户:(注意:和上面不同,下面的因为是MYSQL环境中的命令,所以后面都带一个分号作为命令结束符)

格式:grant select on 数据库.* to 用户名@登录主机 identified by “密码”

例1、增加一个用户test1密码为abc,让他可以在任何主机上登录,并对所有数据库有查询、插入、修改、删除的权限。首先用以root用户连入MYSQL,然后键入以下命令:     grant select,insert,update,delete on *.* to test2@localhost identified by “abc”;

如果你不想test2有密码,可以再打一个命令将密码消掉。     grant select,insert,update,delete on mydb.* to test2@localhostidentified by “”;

(四) 显示命令

1、显示数据库列表:

show databases;     刚开始时才两个数据库:mysql和test。mysql库很重要它里面有MYSQL的系统信息,我们改密码和新增用户,实际上就是用这个库进行操作。

2、显示库中的数据表:

use mysql; //打开库    show tables;

3、显示数据表的结构:

describe 表名;

4、建库:

create database 库名;

5、建表:

use 库名;     create table 表名 (字段设定列表);

6、删库和删表:

drop database 库名;     drop table 表名;

7、将表中记录清空:

delete from 表名;

8、显示表中的记录:

select * from 表名;

导出sql脚本

 

mysqldump -u 用户名 -p 数据库名 > 存放位置

mysqldump -u root -p test > c:/a.sql

 

导入sql脚本

 

mysql -u 用户名 -p 数据库名 < 存放位置

mysqljump -u root -p test < c:/a.sql

 

注意,test数据库必须已经存在

MySQL导出导入命令的用例

1.导出整个数据库

 

mysqldump -u 用户名 -p 数据库名 > 导出的文件名

mysqldump -u wcnc -p smgp_apps_wcnc > wcnc.sql

 

2.导出一个表

 

mysqldump -u 用户名 -p 数据库名表名> 导出的文件名

mysqldump -u wcnc -p smgp_apps_wcnc users> wcnc_users.sql

 

3.导出一个数据库结构

 

mysqldump -u wcnc -p -d –add-drop-table smgp_apps_wcnc >d:wcnc_db.sql

-d 没有数据 –add-drop-table 在每个create语句之前增加一个drop table

 

4.导入数据库

 

常用source 命令

进入mysql数据库控制台,

如mysql -u root -p

mysql>use 数据库

然后使用source命令,后面参数为脚本文件(如这里用到的.sql)

mysql>source d:wcnc_db.sql

【转】Illegal mix of collations (gbk_chinese_ci,IMPLICIT) and (latin1_swedish_ci,COERCIBLE)

MYSQL错误:Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (gbk_chinese_ci,COERCIBLE) for operation ‘=’ 一个解决办法

异常的意思是:字段字符集编码不同,不合法的连接。

用show full columns from tenant;命令查看tenant表各个字段的字符编码。

再用show full columns from employees;命令查看employees表各个字段的字符编码。

发现 tenant中的unitno字段和 employee中的unitno字段的字符编码类型不一致。一个是GBK的,一个是GB2312的。

然后用

ALTER TABLE `tenant` CHANGE `unitno` `unitno` VARCHAR( 32) CHARACTER SET gb2312 COLLATE gb2312_bin NOT NULL

命令修改tenant表中的nuitno字段的字符编码为gb2312类型。保证与整个数据库的字符编码gb2312一致。

或者使用alter table tenant convert to character set gb2312;命令,把整个表的字符编码设为gb2312。

另外,值得注意的是:

[mysql]

default-character-set=gbk 或者 default-character-set=gb2312

还有一个在服务端的 default-character-set=gbk 也要改
然后重起mysql 服务器.

这个方法。本人试了,是不行的。不知道其他的什么情况。

参考文章如下:

1.http://space.itpub.net/7380741/viewspace-50854

最重要的是这个问题:

Illegal mix of collations (gbk_chinese_ci,IMPLICIT) and (gb2312_chinese_ci,IMPLICIT) for operation ‘=’

相信有很多人碰到,意思是说字符编码不一样,不能进行比较,也就是说数据库内部的编码都不一样,有的数据是

gbk_chinese_ci,有的数据是gb2312_chinese_ci,因此解决此问题的核心就是将数据库所有的编码进行统一。

进入命令行模式,

如果MySQL数据库已经安装好,可以使用下列SQL命令查看MySQL当前的字符集设置:
mysql> SHOW VARIABLES LIKE ‘character_set_%’;
+————————–+—————————-+
| Variable_name | Value |
+————————–+—————————-+
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | latin1 |
| character_set_results | latin1 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+————————–+—————————-+
7 rows in set (0.00 sec)

mysql> SHOW VARIABLES LIKE ‘collation_%’;
+———————-+——————-+
| Variable_name | Value |
+———————-+——————-+
| collation_connection | latin1_swedish_ci |
| collation_database | latin1_swedish_ci |
| collation_server | latin1_swedish_ci |
+———————-+——————-+
3 rows in set (0.00 sec)

依次执行:

set character_set_client =gb2312;

set character_set_connection =gb2312;

set character_set_database =gb2312;

set character_set_results =gb2312;

set character_set_server =gb2312;

set character_set_system =gb2312; –此处utf-8也可以

然后执行:

SET collation_server = gb2312_chinese_ci

SET collation_database = gb2312_chinese_ci

SET collation_connection =gb2312_chinese_ci

执行完之后,请检查mysql下每个数据库,表,字段是否都是gb2312,不是则改过来,这样子就不会出现

Illegal mix of collations (gbk_chinese_ci,IMPLICIT) and (gb2312_chinese_ci,IMPLICIT) for operation ‘=’这个错误了,网上有资料说要重装,其实根本就不必,改动其编码即可

……………..

2.http://hi.baidu.com/lym0719/blog/item/54f2d43e1be218c77d1e7193.html

1.如果安装mysql的编码已不能更改,很多朋友是购买虚拟主机建立网站,无权更改MYSQL的安装编码,这一关我们可以跳过,因为只要后面的步聚正确,一样能解决乱码问题
2.修改数据库编码,如果是数据库编码不正确: 可以在phpmyadmin 执行如下命令: ALTER DATABASE `test` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin
以上命令就是将test数据库的编码设为utf8
3.修改表的编码:ALTER TABLE `category` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin
以上命令就是将一个表category的编码改为utf8
4.修改字段的编码:
ALTER TABLE `test` CHANGE `dd` `dd` VARCHAR( 45 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL
以上命令就是将test表中 dd的字段编码改为utf8
5.如果是这种情况容易解决,只需检查下页面,修改源文件的charset即可
, //这个正确就无问题了
6.这种情况也是修改页面charset即可,
。。。。。。。

3.http://hi.baidu.com/yaolihui/blog/item/cf0ee2c48260efcd38db4945.html

查看 MySQL 数据列(column)的字符集。

mysql> show full columns from countries;

 

命令:

 

SHOW VARIABLES LIKE ‘collation%’;
SHOW VARIABLES LIKE ‘character%’;

SET collation_connection = gbk_chinese_ci;
SET collation_database = gbk_chinese_ci;
SET collation_server = gbk_chinese_ci;

SET character_set_client = gbk;
SET character_set_connection = gbk;
SET character_set_database = gbk;
SET character_set_results = gbk;
SET character_set_server = gbk;
SET character_set_system = gbk;
SHOW FULL COLUMNS FROM tb_user;
ALTER TABLE tb_user CONVERT TO CHARACTER SET gbk;

sql2008数据库备份命令

sqlserver备份两种方式

1. 通过维护计划

2. 通过job运行命令

--差异备份
EXECUTE master.dbo.xp_create_subdir N'D:\pic\RE\TEST'
GO
BACKUP DATABASE [TEST] TO  DISK = N'D:\pic\RE\TEST\TEST_backup_201101051801.bak' 
WITH  DIFFERENTIAL , NOFORMAT, NOINIT,  
NAME = N'TEST_backup_20110105180152', SKIP, REWIND, NOUNLOAD,  STATS = 10
go

--完整备份
BACKUP DATABASE [TEST] TO  DISK = N'D:\pic\RE\TEST_backup_201101051802.bak' 
WITH NOFORMAT, NOINIT,  
NAME = N'TEST_backup_20110105180256', SKIP, REWIND, NOUNLOAD,  STATS = 10
go

--强制还原
--REPLACE覆盖已存在数据库
RESTORE DATABASE TEST 
   FROM DISK = 'C:\Program Files\Microsoft SQL Server\MSSQL.2\MSSQL\Backup\TEST.BAK'
   WITH MOVE 'TEST' TO 'D:\pic\TEST.mdf', 
   MOVE 'TEST_log' TO 'D:\pic\TEST_log.ldf',
   STATS = 10, REPLACE
GO

--显示备份列表
RESTORE FILELISTONLY 
   FROM DISK = 'C:\Program Files\Microsoft SQL Server\MSSQL.2\MSSQL\Backup\TEST.BAK'
go

生成年月日的备份文件

declare @databasename nvarchar(50)
set @databasename = 'ExtDB'
DECLARE @strPath NVARCHAR(200)
set @strPath = convert(NVARCHAR(19),getdate(),120)
set @strPath = REPLACE(@strPath, ':' , '.')
set @strPath = 'E:\工作目录\bk\' + @databasename+@strPath + '.bak'
BACKUP DATABASE @databasename  TO DISK = @strPath WITH NOINIT , NOUNLOAD , NOSKIP , STATS = 10, NOFORMAT

数据库备份的命令及方法汇总(oracle备份)

oracle数据库:

1):命令行备份:
 1 将数据库TEST完全导出,用户名system 密码manager 导出到D:\daochu.dmp中
exp system/manager@TEST file=d:\daochu.dmp full=y
2 将数据库中system用户与sys用户的表导出
exp system/manager@TEST file=d:\daochu.dmp owner=(system,sys)
3 将数据库中的表inner_notify、notify_staff_relat导出
exp aichannel/aichannel@TESTDB2 file= d:\data\newsmgnt.dmp tables=(inner_notify,notify_staff_relat)
4 将数据库中的表table1中的字段filed1以”00″打头的数据导出
exp system/manager@TEST file=d:\daochu.dmp tables=(table1) query=\” where filed1 like ‘00%’\” 上面是常用的导出,对于压缩,既用winzip把dmp文件可以很好的压缩。
也可以在上面命令后面 加上 compress=y 来实现。

数据的导入:
1 将D:\daochu.dmp 中的数据导入 TEST数据库中。
imp system/manager@TEST  file=d:\daochu.dmp
imp aichannel/aichannel@HUST full=y  file=file= d:\data\newsmgnt.dmp ignore=y
上面可能有点问题,因为有的表已经存在,然后它就报错,对该表就不进行导入。
在后面加上 ignore=y 就可以了。
2 将d:\daochu.dmp中的表table1 导入
imp system/manager@TEST  file=d:\daochu.dmp  tables=(table1)
基本上上面的导入导出够用了。不少情况要先是将表彻底删除,然后导入。 注意:
操作者要有足够的权限,权限不够它会提示。
数据库时可以连上的。可以用tnsping TEST 来获得数据库TEST能否连上。

附录一:
给用户增加导入数据权限的操作
第一,启动sql*puls
第二,以system/manager登陆
第三,create user 用户名 IDENTIFIED BY 密码(如果已经创建过用户,这步可以省略)
第四,GRANT CREATE USER,DROP USER,ALTER USER ,CREATE ANY VIEW ,
DROP ANY VIEW,EXP_FULL_DATABASE,IMP_FULL_DATABASE,
DBA,CONNECT,RESOURCE,CREATE SESSION  TO 用户名字
第五, 运行-cmd-进入dmp文件所在的目录,
imp userid=system/manager full=y file=*.dmp
或者 imp userid=system/manager full=y file=filename.dmp
执行示例:
F:\Work\Oracle_Data\backup>imp userid=test/test full=y file=inner_notify.dmp
屏幕显示
Import: Release 8.1.7.0.0 – Production on 星期四 2月 16 16:50:05 2006
(c) Copyright 2000 Oracle Corporation.  All rights reserved.
连接到: Oracle8i Enterprise Edition Release 8.1.7.0.0 – Production
With the Partitioning option
JServer Release 8.1.7.0.0 – Production
经由常规路径导出由EXPORT:V08.01.07创建的文件
已经完成ZHS16GBK字符集和ZHS16GBK NCHAR 字符集中的导入
导出服务器使用UTF8 NCHAR 字符集 (可能的ncharset转换)
. 正在将AICHANNEL的对象导入到 AICHANNEL
. . 正在导入表  “INNER_NOTIFY”  4行被导入
准备启用约束条件…
成功终止导入,但出现警告。

附录二:
Oracle 不允许直接改变表的拥有者, 利用Export/Import可以达到这一目的.
先建立import9.par,
然后,使用时命令如下:imp parfile=/filepath/import9.par
例 import9.par 内容如下:
FROMUSER=TGPMS
TOUSER=TGPMS2(注:把表的拥有者由FROMUSER改为TOUSER,FROMUSER和TOUSER的用户可以不同)
ROWS=Y
INDEXES=Y
GRANTS=Y
CONSTRAINTS=Y
BUFFER=409600
file==/backup/ctgpc_20030623.dmp
log==/backup/import_20030623.log 

 2):plsql方式导入导出:

导出表结构:

  打开PLsql,选择工具>导出用户对象出现如图界面

 

 导出表数据:打开PLSQL 选择工具>导出表出现如图界面
导入表结构和数据:打开PLSQL 选择工具>导入表出现如图界面
选择导出文件导入。

delphi连接数据库-入门级笔记

delphi7

windows xp

连接远程mysql

步骤如下:

1.  添加控件 :

ADO- > ADOConnection            用于连接数据库

ADO -> ADOQuery                     用于执行sql语句

假如 ADOConnection的对象名为: ADOCon,  ADOQuery的对象名为ADOQuery1

右击ADOConnection控件,-> 编辑属性 ->use Connection String ->Build->使用连接字符串 ->编译 ->搜索范围 为 Data Sources(这个是默认) ->新建 ->跳出来一个框框“创建新数据源” ->选择“mySql ODBC 5.1 Driver” -> 下一步 -> 浏览里面填写上 远程mysql的ip地址 ->下一步 ->在蹦出来的界面里面填写上远程数据库的ip地址,端口,用户名,密码,数据库名,然后点击test.. ->确定。就Ok.   经过实际测试上述过程完全可以。

那么这样就形成了Connection String

在主窗口初始化函数中写入如下代码对ADOCon和ADOQuery1进行初始化:

 

 
[delphi]
procedure TForm1.FormCreate(Sender: TObject);
begin
try
ADOConnection1.ConnectionString := ( ‘Provider=MSDASQL.1;’
+’Persist Security Info=False;’
+’Extended Properties="Driver=MySQL ODBC 5.1 Driver;’
+’SERVER=100.170.210.90;’
+’UID=root;’
+’PASSWORD=密码;’
+’DATABASE=数据库名;’
+’PORT=3306;’
+’COLUMN_SIZE_S32=1"’ );
ADOConnection1.Close;
ADOConnection1.Open;
except
APPlication.MessageBox(‘无法连接数据库服务器.’,’Error’,MB_ICONINFORMATION);
end;
ADOQuery1.Close;
// ADOQuery1.SQL.Text := ‘SET NAMES "GB2312";’;
// ADOQuery1.ExecSQL;
// ADOQuery1.Close;
ADOQuery1.SQL.Text := ‘SET character_set_client = GB2312;’;
ADOQuery1.ExecSQL;
ADOQuery1.Close;
ADOQuery1.SQL.Text := ‘SET character_set_results = GB2312;’;
ADOQuery1.ExecSQL;
ADOQuery1.Close;
ADOQuery1.SQL.Text := ‘SET character_set_connection = GB2312;’;
ADOQuery1.ExecSQL;
ADOQuery1.Close;

end;

[/delphi]