innodb_buffer_pool_size
如果用Innodb,那么这是一个重要变量。相对于MyISAM来说,Innodb对于buffer size更敏感。MySIAM可能对于大数据量使用默认的key_buffer_size也还好,但Innodb在大数据量时用默认值就感觉在爬了。 Innodb的缓冲池会缓存数据和索引,所以不需要给系统的缓存留空间,如果只用Innodb,可以把这个值设为内存的70%-80%。和 key_buffer相同,如果数据量比较小也不怎么增加,那么不要把这个值设太高也可以提高内存的使用率。

innodb_additional_pool_size
这个的效果不是很明显,至少是当操作系统能合理分配内存时。但你可能仍需要设成20M或更多一点以看Innodb会分配多少内存做其他用途。

innodb_log_file_size
对于写很多尤其是大数据量时非常重要。要注意,大的文件提供更高的性能,但数据库恢复时会用更多的时间。我一般用64M-512M,具体取决于服务器的空间。

innodb_log_buffer_size

默认值对于多数中等写操作和事务短的运用都是可以的。如果经常做更新或者使用了很多blob数据,应该增大这个值。但太大了也是浪费内存,因为1秒钟总会 flush(这个词的中文怎么说呢?)一次,所以不需要设到超过1秒的需求。8M-16M一般应该够了。小的运用可以设更小一点。

innodb_flush_log_at_trx_commit  (这个很管用)
抱怨Innodb比MyISAM慢 100倍?那么你大概是忘了调整这个值。默认值1的意思是每一次事务提交或事务外的指令都需要把日志写入(flush)硬盘,这是很费时的。特别是使用电池供电缓存(Battery backed up cache)时。设成2对于很多运用,特别是从MyISAM表转过来的是可以的,它的意思是不写入硬盘而是写入系统缓存。日志仍然会每秒flush到硬盘,所以你一般不会丢失超过1-2秒的更新。设成0会更快一点,但安全方面比较差,即使MySQL挂了也可能会丢失事务的数据。而值2只会在整个操作系统挂了时才可能丢数据。

原文: http://www.mysqlperformanceblog.com/2009/05/14/why-mysqls-binlog-do-db-option-is-dangerous/

作者: Baron Schwartz

Why MySQL’s binlog-do-db option is dangerous

为什么 MySQL的 binlog-do-db 选项是危险的.

I see a lot of people filtering replication with binlog-do-db, binlog-ignore-db, replicate-do-db, and replicate-ignore-db. Although there are uses for these, they are dangerous and in my opinion, they are overused. For many cases, there's a safer alternative.

我发现很多人通过 binlog-do-db, binlog-ignore-db, replicate-do-db 和 replicate-ignore-db 来过滤复制(某些数据库), 尽管有些使用, 但是,在我看来,他们是危险的,并且他们被滥用了. 对于很多的实例,有更安全的替换方案.

The danger is simple: they don't work the way you think they do. Consider the following scenario: you set binlog-ignore-db to "garbage" so data in the garbage database (which doesn't exist on the slave) isn't replicated. (I'll come back to this in a second, so if you already see the problem, don't rush to the comment form.)

为什么危险很简单: 他们并不像你想的那样工作. 想象如下的场景: 你设置了 binlog-ignore-db = garbage, 所以 garbage数据库(在slave上不存在这个数据库) 中的数据不会被复制,(待会儿我再讲这个,如果你已经发现问题了,不要急于到评论表单)

Now you do the following:

现在做下面的事情:

$ mysql
mysql> delete from garbage.junk;
mysql> use garbage;
mysql> update production.users set disabled = 1 where user = "root";

You just broke replication, twice. Once, because your slave is going to execute the first query and there's no such table "garbage.junk" on the slave. The second time, silently, because the update to production.users isn't replicated, so now the root user isn't disabled on the slave.

复制会broke2次, 第一次,因为 slave尝试着去之西你给第一条语句,但是slave上并没有这样的表"garbage.junk" , 第二次, 隐含的, 因为 对 production.users不会被 复制,因为 root帐号并没有在slave上被禁用掉.

Why? Because binlog-ignore-db doesn't do what you think. The phrase I used earlier, "data in the garbage database isn't replicated," is a fallacy. That's not what it does. In fact, it filters out binary logging for statements issued from connections whose default database is "garbage." In other words, filtering is not based on the contents of the query -- it is based on what database you USE.

为什么? 因为 binlog-ignore-db 并不像你想的那样执行, 我之前说的, "在garbage数据库中的数据不会被复制" 是错的, 实际上(数据库)并没有这么做.事实上, 他是通过默认的数据库为“garbage" 的连接, 过滤二进制的(SQL)语句日志的. 换句话说, 过滤不是基于 查询的字符串的, 而实际于你used的数据库.

The other configuration options I mentioned work similarly. The binlog-do-db and binlog-ignore-db statements are particularly dangerous because they keep statements from ever being written to the binary log, which means you can't use the binary log for point-in-time recovery of your data from a backup.

其他我提到的配置选项也都类似. binlog-do-db 和 binlog-ignore-db 语句是特别危险的,因为他们将语句写入了二进制日志. 意味着你不能使用二进制日志从备份恢复指定时间的数据.

In a carefully controlled environment, these options can have benefits, but I won't talk about that here. (We covered that in our book.)

在严格控制的环境中, 这些选项是很有用的,但是我不会谈论这些(这些包含在我们的书中),

The safer alternative is to configure filters on the slave, with options that actually operate on the tables mentioned in the query itself. These are replicate-wild-* options. For example, the safer way to avoid replicating data in the garbage database is to configure replicate-wild-ignore-table=garbage.%. There are still edge cases where that won't work, but it works in more cases and has fewer gotchas.

安全的替换方案是 在 slave上配置过滤, 使用基于查询中真正涉及到的表的选项, 这些是: replicate-wild-* 选项, 例如, 避免复制 garbage数据库中的数据的安全的方案是 配置:  replicate-wild-ignore-table=garbage.%. 这样做仍然有一些特殊的情况, 不能正常工作,但可以在更多的情况下正常工作,并且会遇到更少的意外 (gotchas).

If you are confused, you should read the replication rules section of the manual until you know it by heart :-)

如果你有些疑惑了,你应该去读一读手册上的复制规则一节,直到你真正明白为止.

MySQL 主从复制(master->slave)

[不指定 2009/09/08 14:45 | by ipaddr ]
1、在MASTER主机(192.168.128.132)上创建数据库mytest:

create database mytest;

然后配置my.cnf
在[mysqld]配置段添加如下字段中增加

log-bin=mysql-bin.log
binlog-do-db=mytest #要同步的数据库的名字
server-id=1

重启mysql

进入MySQL,然后同步账号:

mysql>grant replication slave on *.* to ‘replication’@'%’ identified by ‘aaa’;
mysql>show master status;

+——————+———-+————–+——————+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+——————+———-+————–+——————+
| mysql-bin.000008 |      106 | blog         |                  |
+——————+———-+————–+——————+

2、配置SLAVE数据库(192.168.128.130 and 192.168.128.133)

分别进入MySQL创建数据库
mysql>create database mytest; #建一个与主服务器的数据库名字相同的数据库
mysql>quit;

3、在两个SLAVE数据库的[mysqld]配置段添加如下字段中增加

# 192.168.128.130
server-id=2
master-host=192.168.128.132
master-user=replication
master-password=aaa
master-connect-retry=60
replicate-do-db=mytest

# 192.168.128.133
server-id=3
master-host=192.168.128.132
master-user=replication
master-password=aaa
master-connect-retry=60
replicate-do-db=mytest

3、分别重启两个SLAVE数据库

4、分别进入两个SLAVE数据库中

在SLAVE1上(192.168.128.130)

mysql> slave stop;
Query OK, 0 rows affected (0.00 sec)

mysql> CHANGE MASTER TO
-> MASTER_HOST=’192.168.128.132′,
-> MASTER_USER=’replication’,
-> MASTER_PASSWORD=’aaa’,
-> MASTER_LOG_FILE=’mysql-bin.000008′,
-> MASTER_LOG_POS=106;
Query OK, 0 rows affected (0.03 sec)

mysql> START SLAVE;
Query OK, 0 rows affected (0.00 sec)

在SLAVE2上(192.168.128.133)

mysql> slave stop;
Query OK, 0 rows affected (0.00 sec)

mysql> CHANGE MASTER TO
-> MASTER_HOST=’192.168.128.132′,
-> MASTER_USER=’replication’,
-> MASTER_PASSWORD=’aaa’,
-> MASTER_LOG_FILE=’mysql-bin.000008′,
-> MASTER_LOG_POS=106;
Query OK, 0 rows affected (0.03 sec)

mysql> START SLAVE;
Query OK, 0 rows affected (0.00 sec)

然后,随便在那个SLAVE上
mysql> show processlist;

+—-+————-+———–+——+———+——+———————————————————————–+——————+
| Id | User        | Host      | db   | Command | Time | State                                                                 | Info             |
+—-+————-+———–+——+———+——+———————————————————————–+——————+
|  3 | root        | localhost | NULL | Query   |    0 | NULL                                                                  | show processlist |
|  4 | system user |           | NULL | Connect |   13 | Waiting for master to send event                                      | NULL             |
|  5 | system user |           | NULL | Connect |   13 | Has read all relay log; waiting for the slave I/O thread to update it | NULL             |
+—-+————-+———–+——+———+——+———————————————————————–+——————+

以上信息表示同步成功!

4、同步测试过程
分别在主数据库上建立一个表,插入一条数据
在两个从数据库上看看是否更新
过程略。

ETL是什么?

[不指定 2009/07/09 11:10 | by ipaddr ]

    对于数据仓库以及ETL的知识,我基本上是个门外汉。一切都得从头开始,记个笔记,方便自已了解学习进度。
   
    首先,我们来了解最基本的定义:
    嗯,也有人将ETL简单称为数据抽取。至少在未学习之前,领导告诉我的是,你需要做一个数据抽取的工具。
    其实呢,抽取是ETL中的关键环节,顾名思义,也就将数据从不同的数据源中抓取(复制)出来。
    太简单了!
    上面的解释无首无尾,有点象能让你吃饱的第七个烧饼,
    仔细一想,抽取是不可能单独存在,我们需要将与之关联的一些其它环节拿出来。

    于是,得到ETL的定义:
    将数据抽取(Extract)、转换(Transform)、清洗(Cleansing)、装载(Load)的过程。
    好的,既然到了这一个层次,我们完全会进一步展开联想,引出上面这个抽象事件的前因后果,

    抽取的源在哪里?
    装载的目的又是什么呢?

    抽取源:大多数情况下,可以认为是关系数据库,专业一点,就是事务处理系统(OLTP)。当然,广义一点,可能会是其它数据库或者是文件系统。
    目的地:OK,我们希望是数据仓库。数据仓库是啥?在学习之前,它对我来说是个抽象的怪物,看过一些简单的资料之后,才了解这个怪物一点都不怪。堆积用来分析的数据的仓库。是了,是用来分析的,于是,它区别于OLTP中的数据存储。

    然后,我们来看看为什么要ETL?
    在我看来,有两个原因。
    一:性能  将需要分析的数据从OLTP中抽离出来,使分析和事务处理不冲突。咦?这不是数据仓库的效果吗?是了,
数据仓库,大多数情况下,也就是通过ETL工具来生成地。
    二:控制  用户可以完全控制从OLTP中抽离出来的数据,拥有了数据,也就拥有了一切。
    嗯,OLAP分析,数据挖掘等等等……。

    最后,总结一下,
    从资料上看,ETL是一门大学问,对于大学问,实在有些怕怕,所以,我觉得应该停下来想一想,下一步我该干点啥?
    嗯,时不我待,我没有办法一切从头开始,
    是了,从应用出发,看看现在工作中,最急需的是什么?

    鸭子要变成一盘菜,并不是举手将之置于油锅之劳。
    OK,要将生米变为熟饭,鸭子放上大盘,一堆废话之后,我得先看看厨房里都有了一些啥?

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/tiger119/archive/2007/01/14/1482555.aspx

Oracle大数据导出

[不指定 2009/07/07 17:22 | by ipaddr ]

1. 创建SQL脚本

set heads off
set heading off
set feedback off
set pagesize 0
set linesize 32
set echo off
set termout off
spool /data/tmp/auction_32.dat
select xxxx from tblName;
spool off

2. 使用sqlplus执行
sqlplus xxxx/xxx @tmp.sql

常见Oracle HINT的用法

[不指定 2009/07/07 17:12 | by ipaddr ]

1. /*+ALL_ROWS*/
表明对语句块选择基于开销的优化方法,并获得最佳吞吐量,使资源消耗最小化.
例如:
SELECT /*+ALL+_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';
2. /*+FIRST_ROWS*/
表明对语句块选择基于开销的优化方法,并获得最佳响应时间,使资源消耗最小化.
例如:
SELECT /*+FIRST_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';
3. /*+CHOOSE*/
表明如果数据字典中有访问表的统计信息,将基于开销的优化方法,并获得最佳的吞吐量;
表明如果数据字典中没有访问表的统计信息,将基于规则开销的优化方法;
例如:
SELECT /*+CHOOSE*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';

4. /*+RULE*/
表明对语句块选择基于规则的优化方法.
例如:
SELECT /*+ RULE */ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';

5. /*+FULL(TABLE)*/
表明对表选择全局扫描的方法.
例如:
SELECT /*+FULL(A)*/ EMP_NO,EMP_NAM FROM BSEMPMS A WHERE EMP_NO='SCOTT';

6. /*+ROWID(TABLE)*/
提示明确表明对指定表根据ROWID进行访问.
例如:
SELECT /*+ROWID(BSEMPMS)*/ * FROM BSEMPMS WHERE ROWID>='AAAAAAAAAAAAAA'
AND EMP_NO='SCOTT';

7. /*+CLUSTER(TABLE)*/
提示明确表明对指定表选择簇扫描的访问方法,它只对簇对象有效.
例如:
SELECT /*+CLUSTER */ BSEMPMS.EMP_NO,DPT_NO FROM BSEMPMS,BSDPTMS
WHERE DPT_NO='TEC304' AND BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;

8. /*+INDEX(TABLE INDEX_NAME)*/
表明对表选择索引的扫描方法.
例如:
SELECT /*+INDEX(BSEMPMS SEX_INDEX) USE SEX_INDEX BECAUSE THERE ARE FEWMALE BSEMPMS */ FROM BSEMPMS WHERE SEX='M';

9. /*+INDEX_ASC(TABLE INDEX_NAME)*/
表明对表选择索引升序的扫描方法.
例如:
SELECT /*+INDEX_ASC(BSEMPMS PK_BSEMPMS) */ FROM BSEMPMS WHERE DPT_NO='SCOTT';

10. /*+INDEX_COMBINE*/
为指定表选择位图访问路经,如果INDEX_COMBINE中没有提供作为参数的索引,将选择出位图索引的布尔组合方式.
例如:
SELECT /*+INDEX_COMBINE(BSEMPMS SAL_BMI HIREDATE_BMI)*/ * FROM BSEMPMS
WHERE SAL<5000000 AND HIREDATE

11. /*+INDEX_JOIN(TABLE INDEX_NAME)*/
提示明确命令优化器使用索引作为访问路径.
例如:
SELECT /*+INDEX_JOIN(BSEMPMS SAL_HMI HIREDATE_BMI)*/ SAL,HIREDATE
FROM BSEMPMS WHERE SAL<60000;

12. /*+INDEX_DESC(TABLE INDEX_NAME)*/
表明对表选择索引降序的扫描方法.
例如:
SELECT /*+INDEX_DESC(BSEMPMS PK_BSEMPMS) */ FROM BSEMPMS WHERE DPT_NO='SCOTT';

13. /*+INDEX_FFS(TABLE INDEX_NAME)*/
对指定的表执行快速全索引扫描,而不是全表扫描的办法.
例如:
SELECT /*+INDEX_FFS(BSEMPMS IN_EMPNAM)*/ * FROM BSEMPMS WHERE DPT_NO='TEC305';

14. /*+ADD_EQUAL TABLE INDEX_NAM1,INDEX_NAM2,...*/
提示明确进行执行规划的选择,将几个单列索引的扫描合起来.
例如:
SELECT /*+INDEX_FFS(BSEMPMS IN_DPTNO,IN_EMPNO,IN_SEX)*/ * FROM BSEMPMS WHERE EMP_NO='SCOTT' AND DPT_NO='TDC306';

15. /*+USE_CONCAT*/
对查询中的WHERE后面的OR条件进行转换为UNION ALL的组合查询.
例如:
SELECT /*+USE_CONCAT*/ * FROM BSEMPMS WHERE DPT_NO='TDC506' AND SEX='M';

16. /*+NO_EXPAND*/
对于WHERE后面的OR 或者IN-LIST的查询语句,NO_EXPAND将阻止其基于优化器对其进行扩展.
例如:
SELECT /*+NO_EXPAND*/ * FROM BSEMPMS WHERE DPT_NO='TDC506' AND SEX='M';

17. /*+NOWRITE*/
禁止对查询块的查询重写操作.

18. /*+REWRITE*/
可以将视图作为参数.

19. /*+MERGE(TABLE)*/
能够对视图的各个查询进行相应的合并.
例如:
SELECT /*+MERGE(V) */ A.EMP_NO,A.EMP_NAM,B.DPT_NO FROM BSEMPMS A (SELET DPT_NO
,AVG(SAL) AS AVG_SAL FROM BSEMPMS B GROUP BY DPT_NO) V WHERE A.DPT_NO=V.DPT_NO
AND A.SAL>V.AVG_SAL;

20. /*+NO_MERGE(TABLE)*/
对于有可合并的视图不再合并.
例如:
SELECT /*+NO_MERGE(V) */ A.EMP_NO,A.EMP_NAM,B.DPT_NO FROM BSEMPMS A (SELECT DPT_NO,AVG(SAL) AS AVG_SAL FROM BSEMPMS B GROUP BY DPT_NO) V WHERE A.DPT_NO=V.DPT_NO AND A.SAL>V.AVG_SAL;

21. /*+ORDERED*/
根据表出现在FROM中的顺序,ORDERED使ORACLE依此顺序对其连接.
例如:
SELECT /*+ORDERED*/ A.COL1,B.COL2,C.COL3 FROM TABLE1 A,TABLE2 B,TABLE3 C WHERE A.COL1=B.COL1 AND B.COL1=C.COL1;

22. /*+USE_NL(TABLE)*/
将指定表与嵌套的连接的行源进行连接,并把指定表作为内部表.
例如:
SELECT /*+ORDERED USE_NL(BSEMPMS)*/ BSDPTMS.DPT_NO,BSEMPMS.EMP_NO,BSEMPMS.EMP_NAM FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;

23. /*+USE_MERGE(TABLE)*/
将指定的表与其他行源通过合并排序连接方式连接起来.
例如:
SELECT /*+USE_MERGE(BSEMPMS,BSDPTMS)*/ * FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;

24. /*+USE_HASH(TABLE)*/
将指定的表与其他行源通过哈希连接方式连接起来.
例如:
SELECT /*+USE_HASH(BSEMPMS,BSDPTMS)*/ * FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;

25. /*+DRIVING_SITE(TABLE)*/
强制与ORACLE所选择的位置不同的表进行查询执行.
例如:
SELECT /*+DRIVING_SITE(DEPT)*/ * FROM BSEMPMS,DEPT@BSDPTMS WHERE BSEMPMS.DPT_NO=DEPT.DPT_NO;

26. /*+LEADING(TABLE)*/
将指定的表作为连接次序中的首表.

27. /*+CACHE(TABLE)*/
当进行全表扫描时,CACHE提示能够将表的检索块放置在缓冲区缓存中最近最少列表LRU的最近使用端
例如:
SELECT /*+FULL(BSEMPMS) CAHE(BSEMPMS) */ EMP_NAM FROM BSEMPMS;

28. /*+NOCACHE(TABLE)*/
当进行全表扫描时,CACHE提示能够将表的检索块放置在缓冲区缓存中最近最少列表LRU的最近使用端
例如:
SELECT /*+FULL(BSEMPMS) NOCAHE(BSEMPMS) */ EMP_NAM FROM BSEMPMS;

29. /*+APPEND*/
直接插入到表的最后,可以提高速度.
insert /*+append*/ into test1 select * from test4 ;

30. /*+NOAPPEND*/
通过在插入语句生存期内停止并行模式来启动常规插入.
insert /*+noappend*/ into test1 select * from test4 ;


在SQL Server 2000中,需要修改启动参数,并重新启动SQL Server才可以跟踪到Deadlock的详细信息。
在SQL Server 2005(2008)中,可以通过DBCC来启用Deadlock的跟踪,将详细的信息输出到SQL Server的Error Log

DBCC TRACEON (1204, -1)
DBCC TRACEON (1222, -1)

(鱼漂提醒:SQL Server 2005中已经没有3605 Flag了。)

详情可参考:
http://msdn.microsoft.com/en-us/library/ms178104.aspx
http://msdn.microsoft.com/en-us/library/ms188396.aspx
http://msdn.microsoft.com/en-us/library/ms190737.aspx


在SQL Server中,如果安装并启动了SQL Server Agent,你可以使用“维护计划”来自动备份数据库。

鱼漂提醒:SQL Server 2005 & 2008的维护计划自动备份数据库,还需要安装“SQL Server Integration service ”,否则,维护计划里的备份数据库无法执行。

SQLite适用的范围

[不指定 2008/10/30 00:05 | by ipaddr ]

SQLite不同于其他大部分的SQL数据库引擎,因为它的首要设计目标就是简单化:

  • 易于管理
  • 易于使用
  • 易于嵌入其他大型程序
  • 易于维护和配置

许多人喜欢SQLite因为它的小巧和快速. 但是这些特性只是它的部分优点, 使用者还会发现SQLite是非常稳定的. 出色的稳定性源于它的简单, 越简单就越不容易出错. 除了上述的简单、小巧和稳定性外, 最重要的在于SQLite力争做到简单化.

简单化在一个数据库引擎中可以说是一个优点, 但也可能是个缺点, 主要决定于你想要做什么. 为了达到简单化, SQLite省略了一些人们认为比较有用的特性, 例如高并发性、 严格的存取控制、 丰富的内置功能、 存储过程、复杂的SQL语言特性、 XML以及Java的扩展, 超大的万亿级别的数据测量等等. 如果你需要使用上述的这些特性并且不介意它们的复杂性, 那么SQLite也许就不适合你了. SQLite没有打算作为一个企业级的数据库引擎, 也并不打算和Oracle或者PostgreSQL竞争.

仅凭经验来说SQLite适用于以下场合: 当你更看中简单的管理、使用和维护数据库, 而不是那些企业级数据库提供的不计其数的复杂功能的时候,使用SQLite是一个比较明智的选择. 事实也证明, 人们在许多情况下已经清楚的认识到简单就是最好的选择.

SQLite最佳试用场合

  • 网站

    作为数据库引擎SQLite适用于中小规模流量的网站(也就是说, 99.9%的网站). SQLite可以处理多少网站流量在于网站的数据库有多大的压力. 通常来说, 如果一个网站的点击率少于100000次/天的话, SQLite是可以正常运行的. 100000次/天是一个保守的估计, 不是一个准确的上限. 事实证明, 即使是10倍的上述流量的情况下SQLite依然可以正常运行.

  • 嵌入式设备和应用软件

    因为SQLite数据库几乎不需要管理, 因此对于那些无人值守运行或无人工技术支持的设备或服务, SQLite是一个很好的选择. SQLite能很好的适用于手机, PDA, 机顶盒, 以及其他仪器. 作为一个嵌入式数据库它也能够很好的应用于客户端程序.

  • 应用程序文件格式

    SQLite作为桌面应用程序的本地磁盘文件格式取得了巨大成功.例如金融分析工具、CAD 包、档案管理程序等等. 一般的数据库打开操作需要调用sqlite3_open()函数,并且标记一个显式本地事务的起始点(BEGIN TRANSACTION)来保证以独占的方式得到文件的内容. 文件保存将执行一个提交(COMMIT)同时标记另一个显式本地事务起始点. 这种事务处理的作用就是保证对于应用程序数据文件的更新是原子的、持久的、独立的和一致的.

    数据库里可以加入一些临时的触发器,用来把所有的改变记录在一张临时的取消/重做日志表中. 当用户按下取消/重做按钮的时候这些改变将可以被回滚. 应用这项技术实现一个无限级的取消/重做功能只需要编写很少的代码.

  • 替代某些特别的文件格式

    许多程序使用fopen(), fread(), 或 fwrite()函数创建和管理一些自定义的文件用来保存数据. 使用SQLite替代这些自定义的文件格式将是一种很好的选择.

  • 内部的或临时的数据库

    对于那些有大量的数据需要用不同的方式筛选分类的程序, 相对于编写同样功能的代码, 如果你把数据读入一个内存中的SQLite数据库, 然后使用连接查询和ORDER BY子句按一定的顺序和排列提取需要的数据, 通常会更简单和快速. 按照上述的方法使用内嵌的SQLite数据库将会使程序更富有灵活性, 因为添加新的列或索引不用重写任何查询语句.

  • 命令行数据集分析工具

    有经验的SQL用户可以使用SQLite命令行程序去分析各种混杂的数据集. 原是数据可以从CSV(逗号分隔值文件)文件中导入, 然后被切分产生无数的综合数据报告. 可能得用法包括网站日志分析, 运动统计分析, 编辑规划标准, 分析试验结果.

    当然你也可以用企业级的客户端/服务器数据库来做同样的事情. 在这种情况下使用SQLite的好处是: SQLite的部署更为简单并且结果数据库是一个单独的文件, 你可以把它存储在软盘或者优盘或者直接通过email发给同事.

  • 在Demo或测试版的时候作为企业级数据库的替代品

    如果你正在编写一个使用企业级数据库引擎的客户端程序, 使用一个允许你连接不同SQL数据库引擎的通用型数据库后台将是很有意义的. 其更大的意义在于将SQLite数据库引擎静态的连接到客户端程序当中,从而内嵌SQLite作为混合的数据库支持. 这样客户端程序就可以使用SQLite数据库文件做独立的测试或者验证.

  • 数据库教学

    因为SQLite的安装和使用非常的简单(安装过程几乎忽略不计, 只需要拷贝SQLite源代码或sqlite.exe可执行文件到目标主机, 然后直接运行就可以) 所以它非常适合用来讲解SQL语句. 同学们可以非常简单的创建他们喜欢的数据库, 然后通过电子邮件发给老师批注或打分. 对于那些感兴趣怎样实现一个关系型数据库管理系统(RDBMS)的高层次的学生, 按照模块化设计且拥有很好的注释和文档的SQLite源代码, 将为他们打下良好的基础. 这并不是说SQLite就是如何实现其他数据库引擎的精确模型, 但是很适合学生们了解SQLite是如何快速工作的, 从而掌握其他数据库系统的设计实现原则.

  • 试验SQL语言的扩展

    SQLite简单且模块化的设计使得它可以成为一个用来测试数据库语言特性或新想法的优秀的原型平台.

哪些场合适合使用其他的关系型数据库管理系统(RDBMS)

  • 客户端/服务器程序

    如果你有许多的客户端程序要通过网络访问一个共享的数据库, 你应当考虑用一个客户端/服务器数据库来替代SQLite. SQLite可以通过网络文件系统工作, 但是因为和大多数网络文件系统都存在延时, 因此执行效率不会很高. 此外大多数网络文件系统在实现文件逻辑锁的方面都存在着bug(包括Unix 和windows). 如果文件锁没有正常的工作, 就可能出现在同一时间两个或更多的客户端程序更改同一个数据库的同一部分, 从而导致数据库出错. 因为这些问题是文件系统执行的时候本质上存在的bug, 因此SQLite没有办法避免它们.

    好的经验告诉我们, 应该避免在许多计算机需要通过一个网络文件系统同时访问同一个数据库的情况下使用SQLite.

  • 高流量网站

    SQLite通常情况下用作一个网站的后台数据库可以很好的工作. 但是如果你的网站的访问量大到你开始考虑采取分布式的数据库部署, 那么你应当毫不犹豫的考虑用一个企业级的客户端/服务器数据库来替代SQLite.

  • 超大的数据集

    当你在SQLite中开始一个事务处理的时候(事务处理会在任何写操作发生之前产生, 而不是必须要显示的调用BEGIN...COMMIT), 数据库引擎将不得不分配一小块脏页(文件缓冲页面)来帮助它自己管理回滚操作. 每1MB的数据库文件SQLite需要256字节. 对于小型的数据库这些空间不算什么, 但是当数据库增长到数十亿字节的时候, 缓冲页面的尺寸就会相当的大了. 如果你需要存储或修改几十GB的数据, 你应该考虑用其他的数据库引擎.

  • 高并发访问

    SQLite对于整个数据库文件进行读取/写入锁定. 这意味着如果任何进程读取了数据库中的某一部分, 其他所有进程都不能再对该数据库的任何部分进行写入操作. 同样的, 如果任何一个进程在对数据库进行写入操作, 其他所有进程都不能再读取该数据库的任何部分. 对于大多数情况这不算是什么问题. 在这些情况下每个程序使用数据库的时间都很短暂, 并且不会独占, 这样锁定至多会存在十几毫秒. 但是如果有些程序需要高并发, 那么这些程序就需要寻找其他的解决方案了.


Problem
One problem with SQL Server 2005 Express is that it does not offer a way to schedule jobs. In a previous tip, Free Job Scheduling Tool for SQL Server Express and MSDE, we looked at a free tool that allows you to create scheduled jobs for SQL Server. The one issue people often face though is what to install and what not to install on their production servers and therefore these items go without resolution. One very important part of managing SQL Server is to ensure you run backups on a set schedule. I often hear about corrupt databases and no backups, so let's take a look at another approach of scheduling backups using the included tools in both the operating system and SQL Server.

Solution
There are two components to this; the first is the backup command and the second is the scheduling needed to run the backups.

Backup Commands
There are a few things that we need to setup. The first is to create a stored procedure that allows us to dynamically generate the backup file name as well as what type of backup to run Full, Differential or Transaction Log backup. The default for this stored procedure is to create the backups in the "C:\Backup" folder. This can be changed to any folder you like.

The following stored procedure should be created in the master database. This is just one way of handling this. There are several other options and enhancements that can be made.

USE [master]
GO
/****** Object: StoredProcedure [dbo].[sp_BackupDatabase] Script Date: 02/07/2007 11:40:47 ******/
SET ANSI_NULLS
ON
GO
SET QUOTED_IDENTIFIER
ON
GO


-- =============================================
-- Author: Edgewood Solutions
-- Create date: 2007-02-07
-- Description: Backup Database
-- Parameter1: databaseName
-- Parameter2: backupType F=full, D=differential, L=log
-- =============================================
CREATE PROCEDURE
[dbo].[sp_BackupDatabase]
@databaseName sysname, @backupType CHAR(1
)
AS
BEGIN
SET
NOCOUNT ON
;

DECLARE @sqlCommand NVARCHAR(1000
)
DECLARE @dateTime NVARCHAR(20
)

SELECT @dateTime = REPLACE(CONVERT(VARCHAR, GETDATE(),111),'/',''
) +
REPLACE(CONVERT(VARCHAR, GETDATE(),108),':',''
)

IF @backupType =
'F'
SET @sqlCommand = 'BACKUP DATABASE ' + @databaseName
+
' TO DISK = ''C:\Backup\' + @databaseName + '_Full_' + @dateTime +
'.BAK'''

IF @backupType =
'D'
SET @sqlCommand = 'BACKUP DATABASE ' + @databaseName
+
' TO DISK = ''C:\Backup\' + @databaseName + '_Diff_' + @dateTime +
'.BAK'' WITH DIFFERENTIAL'

IF @backupType =
'L'
SET @sqlCommand = 'BACKUP LOG ' + @databaseName
+
' TO DISK = ''C:\Backup\' + @databaseName + '_Log_' + @dateTime +
'.TRN'''

EXECUTE sp_executesql
@sqlCommand
END

The second part of this is to create a SQLCMD file to run the backup commands. Here is a simple SQLCMD file that backups databases master, model and msdb.

This file gets saved as backup.sql and for our purposes this is created in the "C:\Backup" folder, but again this could be put anywhere.

sp_BackupDatabase 'master', 'F'
GO
sp_BackupDatabase 'model', 'F'
GO
sp_BackupDatabase 'msdb', 'F'
GO
QUIT


Scheduling
Included with the Windows operating system is a the ability to setup and run scheduled tasks. This is generally not used for SQL Server environments, because SQL Server Agent is so robust and gives you a lot more control and options for setting up re-occurring jobs. With SQL Server 2005 Express the only choice is to set a scheduled task at the operating system level or look for some third party tool.

To setup a scheduled task you need to open the folder where you can create a new scheduled task. This can be found under Accessories -> System Tools -> Scheduled Tasks or under Control Panel.

Run Command: sqlcmd -S serverName -E -i C:\Backup\Backup.sql
Start In: C:\Program Files\Microsoft SQL Server\90\Tools\Binn

This is broken down as follows:

  • sqlcmd
  • -S (this specifies the server\instance name for SQL Server)
  • serverName (this is the server\instance name for SQL Server)
  • -E (this allows you to make a trusted connection)
  • -i (this specifies the input command file)
  • C:\Backup\Backup.sql (this is the file that we created above with the command steps)
鱼漂修改过的存储过程:

 USE [master] 
GO 
 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 


CREATE PROCEDURE [dbo].[sp_BackupDatabase]
       @databaseName sysname, @backupType CHAR(1) 
AS 
BEGIN 
       SET NOCOUNT ON; 

       DECLARE @sqlCommand NVARCHAR(1000) 
       DECLARE @dateTime NVARCHAR(20)  
       DECLARE @backupPath NVARCHAR(50)
    
       SET @backupPath='D:\Backups\SQLServer\';

       SELECT @dateTime = REPLACE(CONVERT(VARCHAR, GETDATE(),111),'/','') +  REPLACE(CONVERT(VARCHAR, GETDATE(),108),':','')

       IF @backupType = 'F' 
               SET @sqlCommand = 'BACKUP DATABASE [' + @databaseName + 
               '] TO DISK = ''' + @backupPath + @databaseName + '_Full_' + @dateTime + '.BAK''' 
        
       IF @backupType = 'D' 
               SET @sqlCommand = 'BACKUP DATABASE [' + @databaseName + 
               '] TO DISK = ''' + @backupPath + @databaseName + '_Diff_' + @dateTime + '.BAK'' WITH DIFFERENTIAL' 
        
       IF @backupType = 'L' 
               SET @sqlCommand = 'BACKUP LOG [' + @databaseName + 
               '] TO DISK = ''' + @backupPath + @databaseName + '_Log_' + @dateTime + '.TRN''' 
        
       EXECUTE sp_executesql @sqlCommand 
END

分页: 2/5 第一页 上页 1 2 3 4 5 下页 最后页 [ 显示模式: 摘要 | 列表 ]