一篇文带你零基础玩转mysql触发器 | 超级干货,建议收藏(一)
一、环境说明系统要求:Ubuntu20.04二、前言 MySQL 作为当今最流行的关系型数据库管理系统之一,由瑞典MySQL AB 公司开发,属于 Oracle 旗下的产品。由于 MySQL已源码,因此大大降低了成本,但也可以从Oracle购买商业许可证版本,以获得高级支持服务(特殊企业用户需要)。 与其他数据库软件(如Oracle数据库或Microsoft SQL Server)相比,MySQL已经非常容易学习和掌握。MySQL可以在各种平台上运行UNIX,Linux,Windows等;也可以将其安装在服务器甚至桌面系统上。 此外,MySQL是可靠,可扩展和快速的。如果您开发网站或Web应用程序,MySQL是一个不错的选择(强烈建议使用)。MySQL是LAMP堆栈的重要组成部分,包括Linux,Apache,MySQL和PHP。更多mysql介绍使用请上官网学习,此处就不多言阐述啦。 奉上MySQL官网址: MySQL ,MySQL社区版本下载地址: MySQL :: Download MySQL Community Server三、前言: 想必使用过mysql的小伙伴,都知道,mysql有事务、索引、触发器、存储过程等;那么今天,bug菌今天就来给大家聊一聊它但是不会鸽太久啦,顶多鸽一两个礼拜...啊呸,一两天啦;此期也是为了允诺私聊bug菌的小伙伴啦,单独更一期mysql触发器的相关基础教学;还请小伙伴们细品~ 阅读文章的同时若是发现途中有讲述的不对或者理解有偏差的地方,还请小伙伴们多多谅解,毕竟bug菌也经验水平有限啦,但非常欢迎小伙伴们能留下观点、提出宝贵建议和意见,下方留言评论,找出我的不足,bug菌的成长同时也是见证你的成长!万事尽力!尽力而为。**如果最后觉得该文章对你有所帮助,还请不要吝啬你的赞哦,直接pia的点亮就完事了啦 up up up!!!**你们的鼓励就是对bug菌写作最大的支持!那么接下来,干正事啦!bug菌要开始上课了喔~四、本章内容:1. MySQL触发器是什么?#1基本概念:触发器是一种特殊类型的存储过程,它不同于存储过程,主要是通过事件触发而被执行的,即不是主动调用而执行的;而存储过程则需要主动调用其名字执行。触发器:trigger,是指事先为某张表绑定一段代码,当表中的某些内容发生改变(增、删、改)的时候,系统会自动触发代码并执行。#2作用:可在写入数据前,强制检验或者转换数据(保证护数据安全)。触发器发生错误时,前面用户已经执行成功的操作会被撤销,类似事务的回滚。#3版本:MySQL 5.0开始才支持存储过程、触发器2. 为什么要用MySQL触发器?触发器可以检查或修改新数据值,这意味着我们可以利用触发器强制实现数据完整性,比如检查某个百分比数值是否在0-100之间,还可以用来对输入数据进行必要的过滤;触发器可以将表达式的结果赋值给数据列作为默认值。因此我们可以绕开数据列定义里的默认值必须为常数的限制;触发器可以在删除或修改数据行之前先检查它的当前内容。利用这种能力可以实现许多功能,比如把对现有数据的修改记载到一个日志里。3. 如何创建MySQL触发器?#1基本语法delimiter 自定义结束符号
create trigger 触发器名字 触发时间 触发事件 on 表 for each row
begin
-- 触发器内容主体,每行用分号结尾
end
自定义的结束符合
delimiter ;on 表 for each:触发对象,触发器绑定的实质是表中的所有行,因此当每一行发生指定改变时,触发器就会发生;其中:触发器名称:标识触发器名称,用户自行指定;触发时间:标识触发时间,取值为 BEFORE 或 AFTER;触发事件:标识触发事件,取值为 INSERT、UPDATE 或 DELETE;触发器表名:标识建立触发器的表名,即在哪张表上建立触发器;触发器程序体:可以是一句SQL语句,或者用 BEGIN 和 END 包含的多条语句。由此可见,可以建立6种触发器,即:BEFORE INSERT、BEFORE UPDATE、BEFORE DELETE、AFTER INSERT、AFTER UPDATE、AFTER DELETE。#2触发时间当 SQL 指令发生时,会令行中数据发生变化,而每张表中对应的行有两种状态:数据操作前和操作后before:表中数据发生改变前的状态after:表中数据发生改变后的状态PS:如果 before 触发器失败或者语句本身失败,将不执行 after 触发器(如果有的话)#3触发事件触发器是针对数据发送改变才会被触发,对应的操作只有INSERTDELETEUPDATE#4注意事项在 MySQL 5 中,触发器名必须在每个表中唯一,但不是在每个数据库中唯一,即同一数据库中的两个表可能具有相同名字的触发器每个表的每个事件每次只允许一个触发器,因此,每个表最多支持 6 个触发器before/after insert、before/after delete、before/after update另外有一个限制是不能同时在一个表上建立2个相同类型的触发器,因此在一个表上最多建立6个触发器。#5实例演示1、创建完整触发器示例:我先来先来创建一个名为 trigger_demo 的完整触发器;目的:当user表发生update 操作后,自动往 log_info表中插入一条日志记录,具体记录 操作时间、更新前的那条数据用户名称、用户id;delimiter ||
create trigger trigger_demo AFTER UPDATE ON user for each row
BEGIN
INSERT into log_info ( create_time,user_id,user_name )VALUES (now(), old.user_id,old.user_name);
END ||
delimiter;a、变量详解MySQL 中使用 delimiter 来定义一局部变量,该变量只能在 BEGIN … END 复合语句中使用,并且应该定义在复合语句的开头,默认情况下,delimiter是分号 ; ,在命令行客户端中,如果有一行命令以分号结束,那么回车后,mysql将会执行该命令。delimiter || 其中DELIMITER 定好结束符为"|| ", 然后最后又定义为";", MYSQL的默认结束符为";"。b、NEW 与 OLD 详解上述示例中使用了NEW关键字,和 MS SQL Server 中的 INSERTED 和 DELETED 类似,MySQL 中定义了 NEW 和 OLD,用来表示触发器的所在表中,触发了触发器的那一行数据。具体地:在 INSERT 型触发器中,NEW 用来表示将要(BEFORE)或已经(AFTER)插入的新数据;在 UPDATE 型触发器中,OLD 用来表示将要或已经被修改的原数据,NEW 用来表示将要或已经修改为的新数据;在 DELETE 型触发器中,OLD 用来表示将要或已经被删除的原数据;使用方法: NEW.columnName (columnName 为相应数据表某一列名)另外,old是只读的,而 new 则可以在触发器中使用 set赋值,这样不会再次触发 触发器,造成循环调用(比如每插入一个用户前,都在其用户code前拼接“20210617”),这就可以使用set 定义一个临时变量了。如下:定义一个临时变量,一般都以@前缀命名,比如 @new_user_id ;然后在你要执行的事件sql中直接拿来用即可!delimiter ||
create trigger trigger_demo_update AFTER update ON sys_user for each row
BEGIN
SET @new_user_id = CONCAT('20210617',new.id);
INSERT into log_info ( create_time,user_id,user_name )VALUES (now(), @new_user_id,new.user_name);
END ||
delimiter;演示:测试update获取更新前更新后数据UPDATE user SET user_name= '改名字',user_id='999' where user_id = '30' #对user表执行update操作delimiter || create trigger trigger_demo_update AFTER UPDATE ON user for each row BEGIN INSERT into log_info ( create_time,user_id,user_name )VALUES (now(), old.user_id,old.user_name); INSERT into log_info ( create_time,user_id,user_name )VALUES (now(), new.user_id,new.user_name); END || delimiter;经测试,更新user后立马执行触发器,可以看到log_info表操作日志插入进去了! 如下是log_info表数据截图。测试insert获取更新后数据INSERT into user (user_name,user_account) VALUES('张三','zhangsan'); #对user表执行insert操作delimiter || create trigger trigger_demo_insert AFTER Insert ON user for each row BEGIN INSERT into log_info ( create_time,user_id,user_name )VALUES (now(), new.user_id,new.user_name); END || delimiter;经测试,新增user后立马执行触发器,成功将插入后的数据写入log_info表中,如下是log_info表数据截图。测试delete获取更新后数据DELETE FROM user where user_old = '999' #对user表执行delete操作delimiter || create trigger trigger_demo_delete AFTER delete ON user for each row BEGIN INSERT into log_info ( create_time,user_id,user_name )VALUES (now(), old.user_id,old.user_name); END || delimiter;经测试,删除后立马执行触发器,成功将删除前的数据写入log_info表中,如下是log_info表数据截图。2、查看触发器和查看数据库(show databases;)查看表格(show tables;)一样,查看触发器的语法如下:show triggers; #查看全部触发器
show create3、删除触发器和删除数据库、删除表格一样,删除触发器的语法如下:切记:触发器不能修改,只能删除。drop trigger + 触发器名演示:直接命令删除;DROP trigger trigger_demo_delete; #删除触发器 也可以通过navicat 选择要删除的触发器,点击【删除触发器】摁钮,会弹出二次确认,点击【删除】即可。提问:触发器可以批量删除吗?回答:经测试,不可以。验证下方删除多个,结果执行失败了!显而易见,不支持批量删除。单删成功。切记:如果某个触发器不需要用了,一定要立即把这个触发器给删掉,以免造成意外操作,这很关键。切记切记!!!#6触发器的执行顺序我们建立的数据库一般都是 InnoDB 数据库,其上建立的表是事务性表,也就是事务安全的。这时,若SQL语句或触发器执行失败,MySQL 会回滚事务,有:①如果 BEFORE 触发器执行失败,SQL 无法正确执行。②SQL 执行失败时,AFTER 型触发器不会触发。③AFTER 类型的触发器执行失败,SQL 会回滚。
MySQL sql_mode 说明(及处理一起 sql_mode 引发的问题)
1. MySQL莫名变成了 Strict SQL Mode
最近测试组那边反应数据库部分写入失败,app层提示是插入成功,但表里面里面没有产生数据,而两个写入操作的另外一个表有数据。因为 insert 失败在数据库层面是看不出来的,于是找php的同事看下错误信息:
[Err] 1364 - Field `f_company_id` doesn't have a default value
很明显2个 insert 操作,第一条成功,第二条失败了,但因为没有控制在一个事务当中,导致app里面依然提示成功,这是客户入库操作,心想如果线上也有这个问题得是多大的代价。
不说开发的问题,好端端的mysql怎么突然就部分表写入失败呢?根据上面的问题很快能猜到是 sql_mode 问题: NOT NULL 列没有默认值但代码里也没给值,在非严格模式下,int列默认为0,string列默认为''了,所以不成问题;但在严格模式下,是直接返回失败的。
一看,果然:
mysql> show variables like "sql_mode";
+---------------+--------------------------------------------+
| Variable_name | Value |
+---------------+--------------------------------------------+
| sql_mode | STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION |
+---------------+--------------------------------------------+
但是一直是没问题的的,就突然出现了,有谁会去改 sql_mode 呢,生产环境产生这个问题的风险有多大?所以必须揪出来。
先 set global sql_mode='' ,让他们用着先(文后会给解决问题根本的办法),同时打开general_log看是哪一个用户有类似设置 sql_mode 命令:
1134456 Query SET autocommit=1
1134456 Query Set sql_mode='NO_ENGINE_SUBSITUTION,STRICT_TRANS_TABLES'
1134457 Connect ecuser@10.0.200.173 on
1134457 Query /* mysql-connector-java-5.1.35 ...
看出是java组那边哪个框架建立连接的时候使用设置了sql_mode,但这是session级别的,不影响php那边用户的连接。
那会是什么原因在 set global 之后又变回strict模式呢,于是想到 mysqld_safe 启动实际是一个保护进程,在mysqld异常停止之后会拉起来,会不会中间有异常导致 mysqld 重启,致使 global 失效?看了mysql错误日志,才想到前些天断过电,所以决定直接改 /etc/my.cnf配置:
[mysqld]
sql_mode=NO_ENGINE_SUBSTITUTION
重启myqld之后,还是STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION,很少遇到my.cnf里面配置不生效的情况。无独有偶,在 stackoverflow上找到同样的问题 how-to-make-sql-mode-no-engine-substitution-permanent-in-mysql-my-cnf ,原因很简单,sql_mode这个选项被其它地方的配置覆盖了。
了解一下mysql配置文件的加载顺序:
$ mysqld --help --verbose|grep -A1 -B1 cnf
Default options are read from the following files in the given order:
/etc/my.cnf /etc/mysql/my.cnf /usr/etc/my.cnf ~/.my.cnf
mysql按照上面的顺序加载配置文件,后面的配置项会覆盖前面的。最后终于在 /usr/my.cnf 找到有一条sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES,把这个文件删掉,/etc/my.cnf 里面的就生效了。
但是目前没能整明白的是,mysql运行这么长时间怎么突然在/usr (MYSQL_BASE)下多个my.cnf,也不像人为创建的。其它实例也没这样的问题。
类似还出现过一例:存储过程里把 '' 传给int型的,严格模式是不允许,而非严格模式只是一个warning。(命令行执行完语句后,show warnings 可看见)
那么解决这类问题的终极(推荐)办法其实是,考虑到数据的兼容性和准确性,MySQL就应该运行在严格模式下!无论开发环境还是生产环境,否则代码移植到线上可能产生隐藏的问题。
sql_mode 问题可以很简单,也可以很复杂。曾经在一个交流群里看到有人提到,主从sql_mode设置不一致导致复制异常,这里自己正好全面了解一下几个常用的值,方便以后排除问题多个方向。
2. sql_mode 常用值说明
官方手册专门有一节介绍 https://dev.mysql.com/doc/refman/5.6/en/sql-mode.html 。 SQL Mode 定义了两个方面:MySQL应支持的SQL语法,以及应该在数据上执行何种确认检查。
SQL语法支持类
ONLY_FULL_GROUP_BY 对于GROUP BY聚合操作,如果在SELECT中的列、HAVING或者ORDER BY子句的列,没有在GROUP BY中出现,那么这个SQL是不合法的。是可以理解的,因为不在 group by 的列查出来展示会有矛盾。
在5.7中默认启用,所以在实施5.6升级到5.7的过程需要注意:
Expression #1 of SELECT list is not in GROUP BY
clause and contains nonaggregated column
'1066export.ebay_order_items.TransactionID' which
is not functionally dependent on columns in GROUP BY
clause; this is incompatible with sql_mode=only_full_group_by
ANSI_QUOTES 启用 ANSI_QUOTES 后,不能用双引号来引用字符串,因为它被解释为识别符,作用与 ` 一样。
设置它以后,update t set f1="" ...,会报 Unknown column '' in 'field list 这样的语法错误。
PIPES_AS_CONCAT 将 || 视为字符串的连接操作符而非 或 运算符,这和Oracle数据库是一样的,也和字符串的拼接函数 CONCAT() 相类似
NO_TABLE_OPTIONS 使用 SHOW CREATE TABLE 时不会输出MySQL特有的语法部分,如 ENGINE ,这个在使用 mysqldump 跨DB种类迁移的时候需要考虑。
NO_AUTO_CREATE_USER 字面意思不自动创建用户。在给MySQL用户授权时,我们习惯使用 GRANT ... ON ... TO dbuser 顺道一起创建用户。设置该选项后就与oracle操作类似,授权之前必须先建立用户。5.7.7开始也默认了。
数据检查类
NO_ZERO_DATE 认为日期 '0000-00-00' 非法,与是否设置后面的严格模式有关。
1.如果设置了严格模式,则 NO_ZERO_DATE 自然满足。但如果是 INSERT IGNORE 或 UPDATE IGNORE,'0000-00-00'依然允许且只显示warning 2.如果在非严格模式下,设置了NO_ZERO_DATE,效果与上面一样,'0000-00-00'允许但显示warning;如果没有设置NO_ZERO_DATE,no warning,当做完全合法的值。 3.NO_ZERO_IN_DATE情况与上面类似,不同的是控制日期和天,是否可为 0 ,即 2010-01-00 是否合法。
NO_ENGINE_SUBSTITUTION 使用 ALTER TABLE或CREATE TABLE 指定 ENGINE 时, 需要的存储引擎被禁用或未编译,该如何处理。启用NO_ENGINE_SUBSTITUTION时,那么直接抛出错误;不设置此值时,CREATE用默认的存储引擎替代,ATLER不进行更改,并抛出一个 warning .
STRICT_TRANS_TABLES设置它,表示启用严格模式。
注意 STRICT_TRANS_TABLES 不是几种策略的组合,单独指 INSERT、UPDATE出现少值或无效值该如何处理: 1.前面提到的把 '' 传给int,严格模式下非法,若启用非严格模式则变成0,产生一个warning 2.Out Of Range,变成插入最大边界值 3.A value is missing when a new row to be inserted does not contain a value for a non-NULL column that has no explicit DEFAULT clause in its definition
上面并没有囊括所有的 SQL Mode,选了几个代表性的,详细还是 看手册。
sql_mode一般来说很少去关注它,没有遇到实际问题之前不会去启停上面的条目。我们常设置的 sql_mode 是 ANSI、STRICT_TRANS_TABLES、TRADITIONAL,ansi和traditional是上面的几种组合。
ANSI:更改语法和行为,使其更符合标准SQL相当于REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE
TRADITIONAL:更像传统SQL数据库系统,该模式的简单描述是当在列中插入不正确的值时“给出错误而不是警告”。相当于 STRICT_TRANS_TABLES, STRICT_ALL_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, NO_ENGINE_SUBSTITUTION
ORACLE:相当于 PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS, NO_AUTO_CREATE_USER
无论何种mode,产生error之后就意味着单条sql执行失败,对于支持事务的表,则导致当前事务回滚;但如果没有放在事务中执行,或者不支持事务的存储引擎表,则可能导致数据不一致。MySQL认为,相比直接报错终止,数据不一致问题更严重。于是 STRICT_TRANS_TABLES 对非事务表依然尽可能的让写入继续,比如给个"最合理"的默认值或截断。而对于 STRICT_ALL_TABLES,如果是单条更新,则不影响,但如果更新的是多条,第一条成功,后面失败则会出现部分更新。
5.6.6 以后版本默认就是NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES,5.5默认为 '' 。
3. 设置 sql_mode
查看
查看当前连接会话的sql模式:
mysql> select @@session.sql_mode;
或者从环境变量里取
mysql> show variables like "sql_mode";
查看全局sql_mode设置:
mysql> select @@global.sql_mode;
只设置global,需要重新连接进来才会生效
设置
形式如
mysql> set sql_mode='';
mysql> set global sql_mode='NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES';
如果是自定义的模式组合,可以像下面这样
Adding only one mode to sql_mode without removing existing ones:
mysql> SET sql_mode=(SELECT CONCAT(@@sql_mode,',<mode_to_add>'));
Removing only a specific mode from sql_mode without removing others:
mysql> SET sql_mode=(SELECT REPLACE(@@sql_mode,'<mode_to_remove>',''));
配置文件里面设置sql-mode="" 。
参考
MySQL manual sql-mode
mysql的sql_mode合理设置
set-sql-mode-blank-after-upgrading-to-mysql-5-6
MySQL SQL_MODE详解
原文链接地址:http://seanlook.com/2016/04/22/mysql-sql-mode-troubleshooting/
PHP从零开始--字段修饰符&&数据操作&&SQL语言
文章目录一、 字段修饰符1.1主键1.2自动增长1.3非空1.4默认值1.5外键二、 对数据的操作2.1增加数据2.2删除数据2.3更新数据2.4查询数据2.4.1查询所有的数据2.4.2查询指定字段2.4.3去除重复字段2.4.4where表达式详解2.4.5分组查询2.4.6排序三、 SQL语言3.1DML3.2DDL3.3DCL一、 字段修饰符1.1主键主键使用primary key修饰 ,它是唯一,可以防止用户插入相同的数据如果字段加上主键修饰符,如果再加入重复的数据会报错。1.2自动增长auto_increment 是自动增长的修饰符,用户没插入一条数据,修饰的字段会自动增加这样创建的表插入数据默认是从1开始的1.3非空not null 如果字段用not null 修饰了,但是插入数据的时候这个字段没有给值会报错create table student (sid int primary key auto_increment,sname varchar(20) not null,sex char(2));1.4默认值default 数字或者default 字符串意思是用户如果某个字段设置了默认值,如果插入数据的时候这个字段没有给值就采用默认值create table student (sid int primary key auto_increment,sname varchar(20) not null,sex char(2) default ‘男’);1.5外键其中一个表中的字段用primary key修饰,它叫主键,主键所在的表叫主表,另外一张表也有一个字段和主表中的主键相关联,tid叫做student表的外键。用外键约束,如果删除一个表中的数据,会提示报错,这样就保证了数据的一致性和完整性。完整代码如下:创建教师表:create table teacher (tid int primary key auto_increment,tname varchar(20));创建学生外键表:create table student(
sid int primary key auto_increment,
sname varchar(20),
age int,
tid int,
foreign key(tid) references teacher(tid));二、 对数据的操作2.1增加数据insert into 表名 (字段1,字段2…) values (值1,值2…) ;或者同时插入多条数据2.2删除数据delete from 表名 where 条件表达式delete from yuan where name =‘jerry’;2.3更新数据update 表名 set 字段=新值,字段2=新值… where 条件必须加条件 否则整个表的数据都会更新update yuan set name=‘aaa’,sal=6000 where id=3;2.4查询数据2.4.1查询所有的数据select * from 表名select * from yuan;2.4.2查询指定字段select 字段1,字段2… from 表名select id,name,sal from yuan;2.4.3去除重复字段select distinct 字段名 from 表名;select distinct name from yuan;2.4.4where表达式详解算术表达式:+ - * / %比较运算符: > >= < <= <>表示不等 =表示等于逻辑运算符: and or not(1) 查询工资大于3000select * from 表名 where sal>3000;select * from yuan where sal>3000;(2) 查询工资不等于6000select * from yuan where sal<>6000;(3) 查询工资等于6000select * from yuan where sal=6000(4) 查询姓名是jim而且性别是女的信息select * from yuan where name=’jim’ and sex=’女’;(5) 查询不是女生的信息select * from yuan where not sex=’女’;(6) 查询工作在3000和5000之间的between 表示范围 相当于>=3000 and <=5000select * from yuan where sal between 3000 and 6000;(7) 查询地区是保定 南京 沧州in(值1,值2,值3) 表示是里面的任意一个值(8) like 模糊查询like后面可以跟字符串表示模糊查询,%代表任意字符,一个_代表一个字符比如查询姓名叫张x 张xxselect * from yuan where name like ‘张%’;比如查询叫x华 xx华 最后一个字是华select * from yuan where name like ‘%华’;比如查询中间带华的select * from yuan where name like ‘%华%’;2.4.5分组查询count(*) 统计数量max(字段名)最大值min(字段名)最小值sum(字段名)求和avg(字段名)求平均值数据表信息如下: 求男生和女生的人数select sex,count(*) from yuan group by sex; 求部门工资的最大值select b_id,max(sal) from yuan group by b_id; 求每个地区的平均工资是多少select area,avg(sal) from yuan group by area; 分组以后再加条件用having查询按地区分组然后平均工资小于等于6000的信息select area,avg(sal) from yuan group by area having avg(sal)<=6000;2.4.6排序(1)升序和降序按工资排序 取前三名desc是降序 asc是升序select * from yuan order by sal desc;select * from yuan order by sal desc limit 3;(2)limit详解limit后面可以跟两个参数,第一个参数是开始的索引号,默认是0开始,第二个参数取的个数(长度)select * from yuan order by sal desc limit 0,3;三、 SQL语言SQL(structured query language)是结构化查询语言的意思,mysql、oracle用的都是sql语言,只不过根据软件的不同儿语法稍有区别,就和我们的普通话和方言的意思是一样的。上面的增删改查 对数据库和表的操作等都是sql语句。SQL语言3.1DMLDML(data manipulation language)数据操纵语言:就是我们最经常用到的 SELECT、UPDATE、INSERT、DELETE。 主要用来对数据库的数据进行一些操作。SELECT 列名称 FROM 表名称
UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值
INSERT INTO table_name (列1, 列2,...) VALUES (值1, 值2,....)
DELETE FROM 表名称 WHERE 列名称 = 值3.2DDLDDL(data definition language)数据库定义语言:其实就是我们在创建表的时候用到的一些sql,比如说:CREATE、ALTER、DROP等。DDL主要是用在定义或改变表的结构,数据类型,表之间的链接和约束等初始化工作上CREATE TABLE 表名称
(
列名称1 数据类型,
列名称2 数据类型,
列名称3 数据类型,
....
)
ALTER TABLE table_name
ALTER COLUMN column_name datatype
DROP TABLE 表名称
DROP DATABASE 数据库名称3.3DCLDCL(Data Control Language)数据库控制语言:是用来设置或更改数据库用户或角色权限的语句,包括(grant,deny,revoke等)语句。这个比较少用到。在公司呢一般情况下我们用到的是DDL、DML这两种。
PostgreSQL修炼之道:从小工到专家
数据库技术丛书
PostgreSQL修炼之道:从小工到专家
唐成著
图书在版编目(CIP)数据
PostgreSQL修炼之道:从小工到专家/唐成著. —北京:机械工业出版社,2015.4
(数据库技术丛书)
ISBN 978-7-111-49872-8
I. P… II. 唐… III. 关系数据库系统 IV. TP311.132.3
中国版本图书馆CIP数据核字(2015)第063966号
PostgreSQL修炼之道:从小工到专家
出版发行:机械工业出版社(北京市西城区百万庄大街22号 邮政编码:100037)
责任编辑:杨绣国陈佳媛 责任校对:董纪丽
印 刷: 版 次:2015年4月第1版第1次印刷
开 本:186mm×240mm 1/16 印 张:33.5
书 号:ISBN 978-7-111-49872-8 定 价:79.00元
凡购本书,如有缺页、倒页、脱页,由本社发行部调换
客服热线:(010)88378991 88361066 投稿热线:(010)88379604
购书热线:(010)68326294 88379649 68995259 读者信箱:hzjsj@hzbook.com
版权所有·侵权必究
封底无防伪标均为盗版
本书法律顾问:北京大成律师事务所 韩光/邹晓东
Preface 前 言
为什么要写这本书
PostgreSQL数据库是目前功能最强大的开源数据库,它基本包含了其他所有商业或开源的数据库中能找到的功能,甚至还包含了一些商业数据库中没有的功能。它是最接近工业标准SQL92的查询语言,并且正在实现新的功能以兼容最新的SQL标准:SQL2003。PostgreSQL也获得数个奖项,曾三次被评为Linux Journal杂志编辑评选的“最佳数据库奖”(2000年、2003年和2004年),并获2004年度的Linux新媒体最佳数据库系统奖。
PostgreSQL目前在国外很流行,特别是近两年,使用PostgreSQL数据库的公司越来越多,如提供网络电话功能的skype和著名的图片分享网站Instagram。2012年,美国联邦机构全面转向PostgreSQL阵营;法国也正推动政府机构积极采用PostgreSQL数据库取代商业数据库;世界最大的CRM软件服务提供商Salesforce同样开始大量使用 PostgreSQL。在DB-Engine 发布的历年数据库排名中,PostgreSQL自从2013年3月上升到第四名后,一直稳定在第四名,排在很多知名的商业数据库如DB2、Sybase之前,也排在所有NoSQL数据库如Cassandra、Redis等之前。
虽然在国外使用PostgreSQL 数据库的人很多,但在国内,PostgreSQL中文的学习资料并不多,因此我就想到写一本关于PostgreSQL的书,让国内更多的人加入到学习PostgreSQL数据库的队伍中来。
读者对象
适合阅读本书的用户:
数据库入门者。学习本书和相关的数据库知识,可以让一个对数据库了解不是很深的数据库爱好者成为数据库专家。
非PostgreSQL数据库的DBA。可以让非PostgreSQL的DBA 快速掌握PostgreSQL数据库相关知识,成为一名合格的PostgreSQL DBA。
PostgreSQL DBA。本书的一些章节对熟悉PostgreSQL数据库的DBA也有很大指导作用,可以使读者的知识更充实。
开发人员。通过此书可以快速掌握PostgreSQL数据库方面的知识,提高开发人员的数据库水平。
如何阅读本书
本书分为四大部分,分别为准备篇、基础篇、提高篇和第三方开源软件及架构篇。准备篇是为没有数据库基础的读者准备的,如果你已经具备了一定的数据库基础,可以跳过其中的一些内容。基础篇介绍了PostgreSQL数据库中的一些基础内容,学完此篇可以完成基本的PostgreSQL数据库的日常操作。提高篇讲解了一些更深的内容,如PostgreSQL的一些技术内幕、特色功能、优化等方面的内容,仔细阅读此篇可使你早日成为PostgreSQL数据库高手。第三方开源软件及架构篇讲解了与PostgreSQL数据库配套使用的一些常用的开源软件及架构设计方面的内容,通过阅读此篇,可以开阔大家的眼界,提高数据库架构设计能力。
本书中有大量的例子,读者边阅读此书边按例子进行实际的操作,将获得最佳的学习效果。
勘误和支持
由于作者的水平有限,编写的时间也很仓促,书中难免会出现一些错误或者不准确的地方,不妥之处恳请读者批评指正。你可以将书中的错误,遇到的问题及宝贵意见发送邮件至我的邮箱chengdata@gmail.com,我很期待听到你们的真挚反馈。
致谢
首先要感谢国内PostgreSQL数据库的爱好者,他们已经整理了很多PostgreSQL的文章,翻译了PostgreSQL的官方手册,让我可以站在前人的肩膀上。大家可以在PostgreSQL在中国的维基主页http://www.pgsqldb.org/mwiki/index.php/上看到前人的成果。
感谢机械工业出版社华章公司的编辑杨绣国老师,感谢她一年多来始终支持我的写作,她的鼓励和帮助引导我能顺利完成全部书稿。
最后要感谢我的妻子,她一直支持和鼓励我,让我能坚持把这本书写完。
谨以此书,献给众多热爱PostgreSQL的朋友们。
唐成(osdba)
中国,杭州,2015年1月
Contents 目 录
前言
第一篇准备篇
第1章PostgreSQL简介2
1.1什么是PostgreSQL2
1.1.1PostgreSQL概述2
1.1.2PostgreSQL的发展历史2
1.1.3 PostgreSQL数据库的优势3
1.1.4 PostgreSQL应用现状和发展趋势4
1.2 PostgreSQL数据库与其他数据库的对比4
1.2.1PostgreSQL与MySQL数据库的对比4
1.2.2 PostgreSQL与Oracle数据库的对比6
1.3 小结6
第2章PostgreSQL安装与配置7
2.1 从发行版本安装7
2.1.1 在Debian或Ubuntu下的安装7
2.1.2在Redhat、CentOS或Fedora下的安装9
2.1.3 在Windows下的安装12
2.1.4 发行版安装总结16
2.2 从源码安装16
2.2.1 编译安装过程介绍16
2.2.2 下载源代码17
2.2.3 编译及安装18
2.2.4 安装后的配置20
2.2.5 创建数据库簇21
2.2.6 安装contrib目录下的工具21
2.2.7 启动和停止数据库21
2.2.8 编译安装时的常见问题及解决方法22
2.3 安装技巧介绍24
2.3.1 在Redhat、CentOS下使用二进制包安装较新版本的方法24
2.3.2 如何使用较大的数据块提高I/O性能25
2.4 PostgreSQL的简单配置25
2.4.1 修改监听的IP和端口25
2.4.2 与数据库log相关的参数25
2.4.3 内存参数的设置26
2.5 小结26
第3章SQL语言入门27
3.1 SQL语句语法简介27
3.1.1 语句的分类27
3.1.2 词法结构27
3.2 DDL语句28
3.2.1 建表语句28
3.2.2 删除表语句30
3.3 DML语句30
3.3.1 插入语句30
3.3.2 更新语句31
3.3.3 删除语句31
3.4 查询语句31
3.4.1 单表查询语句31
3.4.2 过滤条件的查询32
3.4.3 排序32
3.4.4 分组查询33
3.4.5 表join34
3.5 其他SQL语句36
3.5.1 INSERT INTO... SELECT语句36
3.5.2 UNION语句36
3.5.3 TRUNCATE TABLE语句37
3.6 小结37
第二篇基础篇
第4章psql工具的使用介绍40
4.1 psql介绍40
4.2 psql的简单使用40
4.3 psql的常用命令42
4.3.1 \d命令42
4.3.2 指定字符集编译的命令45
4.3.3 \pset命令46
4.3.4 \x命令46
4.3.5 执行存储在外部文件中的SQL命令47
4.3.6 显示信息的命令48
4.3.7 更多的命令49
4.4 psql的使用技巧和注意事项50
4.4.1 历史命令与补全的功能50
4.4.2 自动提交方面的技巧50
4.4.3 如何得到psql中命令实际执行的SQL51
4.5 小结53
第5章数据类型54
5.1 类型介绍54
5.1.1 类型的分类54
5.1.2 类型输入与转换55
5.2 布尔类型56
5.2.1 布尔类型解释56
5.2.2 布尔类型的操作符58
5.3 数值类型59
5.3.1 数值类型解释59
5.3.2 整数类型 59
5.3.3 精确的小数类型59
5.3.4 浮点数类型60
5.3.5 序列类型61
5.3.6 货币类型61
5.3.7 数学函数和操作符62
5.4 字符串类型64
5.4.1 类型解释64
5.4.2 字符串函数和操作符65
5.5 二进制数据类型67
5.5.1 二进制数据类型解释67
5.5.2 二进制数据类型转义表示67
5.5.3 二进制数据类型的函数68
5.6 位串类型69
5.6.1 位串类型解释69
5.6.2 位串类型的使用69
5.6.3 位串的操作符及函数70
5.7 日期/时间类型71
5.7.1 日期/时间类型详解71
5.7.2 日期输入72
5.7.3 时间输入73
5.7.4 特殊值75
5.7.5 函数和操作符列表75
5.7.6 时间函数77
5.7.7 extract和date_part函数80
5.8 枚举类型81
5.8.1 枚举类型的使用81
5.8.2 枚举类型的说明82
5.8.3 枚举类型的函数83
5.9 几何类型84
5.9.1 几何类型概况84
5.9.2 几何类型的输入84
5.9.3 几何类型的操作符89
5.9.4 几何类型的函数97
5.10 网络地址类型98
5.10.1 网络地址类型概况98
5.10.2 inet与cidr类型98
5.10.3 macaddr类型101
5.10.4 网络地址类型的操作符101
5.10.5 网络地址类型的函数102
5.11 复合类型103
5.11.1 复合类型的定义103
5.11.2 复合类型的输入104
5.11.3 访问复合类型105
5.11.4 修改复合类型105
5.11.5 复合类型的输入与输出106
5.12 XML类型107
5.12.1 XML类型的输入107
5.12.2 字符集的问题108
5.12.3 XML类型的函数109
5.13 JSON类型114
5.13.1 JSON类型简介115
5.13.2 JSON类型的输入与输出115
5.13.3 JSON类型的操作符116
5.13.4 JSON类型的函数118
5.13.5 JSON类型的索引121
5.14 Range类型125
5.14.1 Range类型简介125
5.14.2 创建Range类型126
5.14.3 Range类型的输入与输出127
5.14.4 Range类型的操作符130
5.14.5 Range类型的函数130
5.14.6 Range类型的索引和约束131
5.15 数组类型132
5.15.1 数组类型的声明132
5.15.2 如何输入数组值133
5.15.3 访问数组135
5.15.4 修改数组137
5.15.5 数组的操作符138
5.15.6 数组的函数139
5.16 伪类型142
5.17 其他类型143
5.17.1 UUID类型143
5.17.2 pg_lsn 类型143
第6章逻辑结构管理145
6.1 数据库逻辑结构介绍145
6.2 数据库基本操作145
6.2.1 创建数据库145
6.2.2 修改数据库146
6.2.3 删除数据库147
6.2.4 常见问题及解答147
6.3 模式148
6.3.1 模式的定义148
6.3.2 模式的使用148
6.3.3 公共模式150
6.3.4 模式的搜索路径150
6.3.5 模式的权限151
6.3.6 模式的移植性151
6.4 表152
6.4.1 创建表152
6.4.2 表的存储属性154
6.4.3 临时表156
6.4.4 默认值158
6.4.5 约束159
6.4.6 修改表163
6.4.7 表继承及分区表167
6.4.8 分区表168
6.5 触发器173
6.5.1 创建触发器173
6.5.2 语句级触发器与行级触发器175
6.5.3 BEFORE触发器与AFTER触发器177
6.5.4 删除触发器178
6.5.5 触发器的行为179
6.5.6 触发器函数中的特殊变量180
6.6 事件触发器180
6.6.1 创建事件触发器183
6.6.2 修改事件触发器186
6.7 表空间186
6.7.1 表空间的定义186
6.7.2 表空间的使用186
6.8 视图187
6.8.1 视图的定义187
6.8.2 创建视图188
6.8.3 可更新视图189
6.9 索引191
6.9.1 索引简介191
6.9.2 索引的分类192
6.9.3 创建索引192
6.9.4 并发创建索引193
6.9.5 修改索引196
6.9.6 删除索引196
6.10 用户及权限管理197
6.10.1 用户和角色197
6.10.2 创建用户和角色198
6.10.3 权限的管理199
6.10.4 函数和触发器的权限202
6.10.5 权限的总结202
6.10.6 权限的示例202
6.11 事务、并发、锁203
6.11.1 ACID203
6.11.2 DDL事务204
6.11.3 事务的使用204
6.11.4 SAVEPOINT205
6.11.5 事务隔离级别206
6.11.6 两阶段提交207
6.11.7 锁机制209
6.11.8 死锁及防范212
6.11.9 表级锁命令LOCK TABLE213
6.11.10 行级锁命令213
6.11.11 锁的查看214
第7章PostgreSQL的核心架构221
7.1 应用程序的访问接口221
7.1.1 访问接口总体图221
7.1.2 不同编辑语言的PostgreSQL驱动介绍222
7.2 进程及内存结构223
7.2.1 进程和内存架构图223
7.2.2 主进程Postmaster224
7.2.3 SysLogger(系统日志)进程224
7.2.4 BgWriter(后台写)进程225
7.2.5 WalWriter(预写式日志写)进程225
7.2.6 PgArch(归档)进程225
7.2.7 AutoVacuum(自动清理)进程225
7.2.8 PgStat(统计数据收集)进程226
7.2.9 共享内存226
7.2.10 本地内存226
7.3 目录结构227
7.3.1 安装目录的结构227
7.3.2 数据目录的结构227
7.3.3 表空间的目录228
第8章服务管理229
8.1 服务的启停和创建229
8.1.1 启停方法229
8.1.2 pg_ctl230
8.1.3 信号234
8.1.4 postgres及单用户模式234
8.2 服务配置介绍235
8.2.1 配置参数235
8.2.2 连接配置项237
8.2.3 内存配置项240
8.2.4 预写式日志的配置项241
8.2.5 错误报告和日志项243
8.3 访问控制配置文件246
8.3.1 pg_hba.conf 文件247
8.3.2 认证方法介绍248
8.3.3 认证方法实战249
8.4 备份和还原249
8.4.1 逻辑备份249
8.4.2 pg_dump命令250
8.4.3 pg_restore命令254
8.4.4 pg_dump和pg_restore使用举例257
8.4.5 物理备份258
8.4.6 使用LVM快照进行热备份259
8.5 常用的管理命令261
8.5.1 查看系统信息的常用命令261
8.5.2 系统维护常用命令267
第三篇提高篇
第9章PostgreSQL中执行计划270
9.1 执行计划的解释270
9.1.1 EXPLAIN命令270
9.1.2 EXPLAIN输出结果解释271
9.1.3 EXPLAIN使用示例272
9.1.4 全表扫描275
9.1.5 索引扫描275
9.1.6 位图扫描275
9.1.7 条件过滤276
9.1.8 Nestloop Join277
9.1.9 Hash Join277
9.1.10 Merge Join278
9.2 与执行计划相关的配置项279
9.2.1 ENABLE_*参数 279
9.2.2 COST基准值参数279
9.2.3 基因查询优化的参数280
9.2.4 其他执行计划配置项281
9.3 统计信息的收集282
9.3.1 统计信息收集器的配置项282
9.3.2 SQL执行的统计信息输出283
9.3.3 手工收集统计信息283
第10章PostgreSQL中的技术内幕285
10.1 表中的系统字段285
10.1.1 oid286
10.1.2 ctid288
10.1.3 xmin、xmax、cmin、cmax289
10.2 多版本并发控制290
10.2.1 多版本并发控制的原理290
10.2.2 PostgreSQL中的多版本并发控制291
10.2.3 PostgreSQL多版本的优劣分析293
10.3 物理存储结构293
10.3.1 PostgreSQL中的术语293
10.3.2 数据块结构293
10.3.3 Tuple结构294
10.3.4 数据块空闲空间管理296
10.3.5 可见性映射表文件298
10.4 技术解密298
10.4.1 Index-only scans298
10.4.2 Heap-Only Tuples300
第11章PostgreSQL的特色功能302
11.1 规则系统302
11.1.1 SELECT规则302
11.1.2 更新规则303
11.1.3 规则和权限306
11.1.4 规则和命令状态307
11.1.5 规则与触发器的比较308
11.2 模式匹配和正则表达式308
11.2.1 PostgreSQL中的模式匹配和正则表达式介绍308
11.2.2 传统SQL的LIKE 操作符309
11.2.3 SIMILAR TO 正则表达式310
11.2.4 POSIX 正则表达式312
11.2.5 模式匹配函数 substring313
11.3 listen与notify315
11.3.1 listen与notify的简单示例315
11.3.2listen与notify的相关命令316
11.3.3 listen与notify的使用详解317
11.4 索引的特色320
11.4.1 表达式上的索引320
11.4.2 部分索引320
11.4.3 GiST索引323
11.4.4 SP-GiST索引325
11.4.5 GIN索引326
11.5 序列的使用328
11.5.1 序列的创建328
11.5.2 序列的使用及相关的函数329
11.5.3 常见问题及解答331
11.6 咨询锁的使用333
11.6.1 咨询锁的定义333
11.6.2 咨询锁的函数及使用333
11.6.3 常见问题及解答337
11.7 SQL/MED338
11.7.1 SQL/MED的介绍338
11.7.2 外部数据包装器对象339
11.7.3 外部服务器对象340
11.7.4 用户映射对象341
11.7.5 外部表对象341
11.7.6 file_fdw使用实例342
11.7.7 postgres_fdw使用实例345
第12章数据库优化347
12.1 优化准则和方法347
12.1.1 优化准则347
12.1.2 优化方法348
12.2 硬件知识348
12.2.1 CPU及服务器体系结构348
12.2.2 内存349
12.2.3 硬盘350
12.3 文件系统及I/O调优352
12.3.1 文件系统的崩溃恢复352
12.3.2 Ext2文件系统353
12.3.3 Ext3文件系统353
12.3.4 Ext4文件系统354
12.3.5 XFS文件系统355
12.3.6 Barriers I/O355
12.3.7 I/O调优的方法356
12.4 性能监控359
12.4.1 数据库性能视图359
12.4.2 Linux监控工具362
12.5数据库配置优化364
12.5.1内存配置优化364
12.5.2 关于双缓存的优化366
12.5.3 vacuum中的优化367
12.5.4 预写式日志写优化369
第13章Standby数据库的搭建371
13.1 Standby数据库原理371
13.1.1PITR原理371
13.1.2WAL日志归档372
13.1.3流复制372
13.1.4Standby的运行原理373
13.1.5 创建Standby的步骤373
13.2 pg_basebackup命令行工具374
13.2.1 pg_basebackup介绍374
13.2.2 pg_basebackup的命令行参数375
13.2.3 pg_basebackup使用示例376
13.3 异步流复制Hot Standby的示例377
13.3.1 配置环境377
13.3.2 主数据库的配置378
13.3.3 在Standby上生成基础备份378
13.3.4 启动Standby379
13.4 同步流复制的Standby数据库380
13.4.1 同步流复制的架构380
13.4.2 同步复制的配置381
13.4.3 配置实例381
13.5 检查备库及流复制情况383
13.5.1 检查异步流复制的情况383
13.5.2 检查同步流复制的情况384
13.5.3 视图pg_stat_replication详解385
13.5.4 查看备库的状态385
13.6 Hot Standby的限制387
13.6.1 Hot Standby的查询限制387
13.6.2 Hot Standby的查询冲突处理389
13.7 恢复配置详解390
13.7.1 归档恢复配置的配置项390
13.7.2 Recovery Target配置391
13.7.3 Standby Server配置 391
13.8 流复制的注意事项392
13.8.1 wal_keep_segments参数的配置392
13.8.2 vacuum_defer_cleanup_age参数的配置392
第四篇第三方开源软件及架构篇
第14章PgBouncer394
14.1 PgBouncer 介绍394
14.2 PgBouncer中的概念395
14.3 PgBouncer的安装方法395
14.4 PgBouncer的简单使用395
14.4.1 简单配置方法395
14.4.2 启动PgBouncer396
14.4.3 停止PgBouncer397
14.4.4 查看连接池信息397
14.5 PgBouncer的配置文件详解399
14.5.1 “[databases]”部分的配置项399
14.5.2 “[pgbouncer]”部分的配置项399
14.5.3 用户密码文件403
第15章Slony-I的使用404
15.1Slony-I中的概念404
15.1.1 集群404
15.1.2 节点405
15.1.3 复制集合405
15.1.4 数据原始生产者、数据提供者和数据订阅者405
15.1.5 slon守护程序405
15.1.6 slonik配置程序405
15.2 Slony-I复制的限制405
15.3 在Windows下使用pgAdminIII安装配置Slony-I406
15.3.1 Windows下安装Slony-I406
15.3.2Windows配置 Slony-I同步实例407
15.4在Linux下安装配置Slony-I419
15.4.1编译安装Slony-I419
15.4.2配置Slony-I复制421
第16章Bucardo的使用426
16.1Bucardo中的概念426
16.1.1Bucardo介绍426
16.1.2Bucardo FAQ426
16.1.3 Bucardo 同步中定义的概念427
16.2Bucardo的安装方法427
16.2.1Bucardo的安装步骤427
16.2.2安装Test-Simple、ExtUtils-MakeMaker、version428
16.2.3安装DBI及DBD::Pg428
16.2.4安装DBIx-Safe429
16.2.5安装Bucardo源码包429
16.3Bucardo同步配置429
16.3.1示例环境429
16.3.2配置同步的简要过程430
16.3.3 bucardo_ctl install431
16.3.4bucardo_ctl add db433
16.3.5 bucardo_ctl add table433
16.3.6 bucardo_ctl add herd433
16.3.7 bucardo_ctl add sync433
16.3.8 bucardo_ctl start434
16.4Bucardo的日常维护434
16.4.1Bucardo的触发器日志清理434
16.4.2临时停止和启动同步的方法435
16.4.3新增表到同步的方法435
16.4.4移除某个表或序列的方法435
第17章PL/Proxy的使用436
17.1PL/Proxy中的概念436
17.1.1PL/Proxy的定义436
17.1.2PL/Proxy的特性说明438
17.2PL/Proxy安装及配置438
17.2.1编译安装438
17.2.2安装规划439
17.2.3配置过程439
17.3PL/Proxy的集群配置详解443
17.3.1Cluster configuration API方式444
17.3.2SQL/MED方式配置集群446
17.4PL/Proxy语言详解446
17.4.1CONNECT447
17.4.2CLUSTER447
17.4.3RUN ON447
17.4.4SPLIT448
17.4.5TARGET448
17.5PL/Proxy的一个高可用方案448
17.5.1方案介绍448
17.5.2方案架构449
17.5.3具体实施步骤449
第18章pgpool-II的使用458
18.1 pgpool-II中的概念458
18.1.1 pgpool-II的定义458
18.1.2 pgpool-II的架构459
18.1.3 pgpool-II的工作模式460
18.1.4 pgpool-II的程序模块461
18.2 pgpool-II安装方法462
18.2.1 源码安装462
18.2.2 安装 pgpool_regclass463
18.2.3 建立 insert_lock 表463
18.2.4 安装C语言函数463
18.3 pgpool-II配置快速入门463
18.3.1 pgpool-II的配置文件及启停方法464
18.3.2 复制和负载均衡的示例466
18.3.3 使用流复制的主备模式的示例467
18.3.4 show命令468
18.4 pgpool-II高可用配置方法471
18.4.1 pgpool-II高可用切换及恢复的原理471
18.4.2 pgpool-II的健康检查473
18.4.3 复制和负载均衡模式的高可用示例473
18.4.4 使用流复制的主备模式下的高可用示例488
18.5 pgpool-II的总结492
第19章Postgres-XC的使用493
19.1 Postgres-XC中的概念493
19.1.1 Postgres-XC的定义493
19.1.2 Postgres-XC的特点493
19.1.3 Postgres-XC的性能494
19.1.4 Postgres-XC的组件494
19.2 Postgres-XC的安装495
19.2.1 源码安装方法495
19.2.2 Postgres-XC目录及程序说明496
19.3 配置Postgres-XC集群497
19.3.1 集群规划497
19.3.2 初始化GTM498
19.3.3 初始化GTM的备库498
19.3.4 初始化GTM Proxy499
19.3.5 初始化Coordinators、数据节点499
19.3.6 启动集群500
19.3.7 停止集群501
19.3.8 配置集群节点信息502
19.4 Postgres-XC的使用503
19.4.1 建表详解503
19.4.2 使用限制509
19.4.3 重新分布数据510
19.4.4 增加Coordinator节点的方法512
19.4.5 移除Coordinator节点的方法513
19.4.6 增加Datanode节点的方法513
19.4.7 移除Datanode节点的方法514
第20章高可用性方案设计516
20.1 高可用架构基础516
20.1.1 各种高可用架构介绍516
20.1.2 服务的可靠性设计517
20.1.3 数据可靠性设计517
20.2 基于共享存储的高可用方案517
20.2.1 SAN存储的方案517
20.2.2 DRBD的方案518
20.3 WAL日志同步或流复制同步的方案519
20.3.1 持续复制归档的standby的方法519
20.3.2 异步流复制的方案519
20.3.3 基于同步流复制方案519
20.4 基于触发器的同步方案520
20.4.1 方案的特点520
20.4.2 基于触发器方案的同步软件介绍520
20.5 基于语句中间件的高可用方案520
20.5.1 方案的特点520
20.5.2 基于语句中间件的开源软件介绍521
第一篇
准 备 篇
第1章PostgreSQL简介
第2章PostgreSQL安装与配置
第3章SQL语言入门
第1章
PostgreSQL简介
本章将着重介绍PostgreSQL数据库的相关知识,让没有接触过PostgreSQL的读者对它有一个初步的了解。
1.1什么是PostgreSQL
1.1.1PostgreSQL概述
PostgreSQL数据库是目前功能最强大的开源数据库,支持丰富的数据类型(如JSON和JSONB类型、数组类型)和自定义类型。而且它提供了丰富的接口,可以很容易地扩展它的功能,如可以在GiST框架下实现自己的索引类型等,它还支持使用C语言写自定义函数、触发器,也支持使用流行的语言写自定义函数,比如其中的PL/Perl提供了使用Perl语言写自定义函数的功能,当然还有PL/Python、PL/Tcl,等等。
1.1.2PostgreSQL的发展历史
前身Ingres:PostgreSQL的前身是伯克利源于1977 年的 Ingres 项目。这个项目是由著名的数据库科学家Michael Stonebraker领导的。1982年,Michael Stonebraker离开伯克利大学,把Ingres商业化,使之成为 Relational Technologies 公司的一个产品。后来 Relational Tecchnologies被Computer Associates(CA)收购。Ingres 是一个非关系型的数据库。
伯克利的 Postgres 项目:20世纪80年代,数据库系统中的一个主要问题是数据关系维护。在1985年Michael Stonebraker回到伯克利后,为了解决Ingres中的数据关系维护问题,启动了一个后Ingres(post-Ingres)的项目,这就是 POSTGRES 的开端。 POSTGRES项目是由防务高级研究项目局(DARPA)、陆军研究办公室(ARO)、国家科学基金(NSF) 以及 ESL公司共同赞助的。从1986年开始,Michael Stonebraker 教授发表了一系列论文,探讨了新的数据库的结构设计和扩展设计。第一个“演示性”系统在 1987 年便可使用了,并且在 1988 年的数据管理国际会议(ACM-SIGMOD)上展出。1989年6月发布了版本 1给一些外部的用户使用。由于源代码维护的时间日益增加,占用了太多本应用于数据库研究的时间,为减少支持的负担,伯克利的POSTGRES 项目在版本 4.2 时正式终止。
Postgres95:在 1994 年,来自中国香港的两名伯克利的研究生Andrew Yu 和 Jolly Chen 向 POSTGRES 中增加了现在SQL 语言的解释器,将Postgres改名为 Postgres95,随后将 Postgres95 源代码发布到互联网上供大家使用。它成为一个开放源码的POSTGRES 代码的继承者。
PostgreSQL6.X:到了 1996 年,很明显地看出“Postgres95”这个名字已经经不起时间的考验。于是起了一个新名字 PostgreSQL,为Postgres与SQL的缩写,即增加了SQL功能的Postgres的意思。同时版本号也沿用伯克利 POSTGRES 项目的顺序,从6.0开始。
PostgreSQL7.1:PostgreSQL 7.1是继6.5版本之后又一个有巨大变化的版本,首先它引入了预写式日志的功能。这样,事务就拥有了完善的日志机制,可以提供更好的性能,还可以实现更优良的备份和灾难恢复的能力(比如联机热备份和宕机后的自动恢复)。其次是不再限制文本类型的数据段长度,这从很大程度上解决了PostgreSQL大对象的问题。
Postgres8.X:该版本可以在Windows下运行,它具有一些新的特性。比如具有事务保存点功能、改变字段的类型、表空间、即时恢复(即时恢复允许对服务器进行连续的备份。既可以恢复到失败那个点,也可以恢复到以前的任意事务)等功能。并且开始支持Perl 服务器端编程语言。
PostgreSQL9.X:进入9.X版本,标识着PostgreSQL进入了黄金发展阶段。2010年9月20日发布了PostgreSQL 9.0,大大增强了复制的功能(replication),比如增加了流复制功能(stream replicaction)和HOT standby功能。从9.0开始,可以很方便地搭建主从数据库。2011年9月12日发布了PostgreSQL9.1,在该版本中增加了同步复制功能(synchronous replication);2012年9月10发布了PostgreSQL9.2,增加了级连复制的功能。
1.1.3 PostgreSQL数据库的优势
PostgreSQL有以下优势:
PostgreSQL数据库是目前功能最强大的开源数据库,它是最接近工业标准SQL92的查询语言,并且正在实现新的功能以兼容最新的SQL标准:SQL2003。
稳定可靠:PostgreSQL是唯一能做到数据零丢失的开源数据库。有报道称国外的部分银行也在使用PostgreSQL数据库。
开源省钱: PostgreSQL数据库是开源的、免费的,而且是BSD协议,在使用和二次开发上基本没有限制。
支持广泛:PostgreSQL 数据库支持大量的主流开发语言,包括C、C++、Perl、Python、Java、Tcl,以及PHP等。
PostgreSQL社区活跃:PostgreSQL基本上每三个月推出一个补丁版本,这意味着已知的BUG很快会被修复,有应用场景的需求也会及时得到响应。
1.1.4 PostgreSQL应用现状和发展趋势
PostgreSQL目前在国外很流行,特别是近几年使用PostgreSQL数据库的公司越来越多。比如,日本电信(NTT) 大量使用PostgreSQL替代Oracle数据库,并且在 PostgreSQL之上二次开发了Postgres-XC,Postgres-XC是对使用者完全兼容PostgreSQL接口的share-nothing 架构的数据库集群。网络电话公司Skype 也大量使用PostgreSQL,并贡献了一些与PostgreSQL数据库配套的开源软件:
PL/Proxy:PostgreSQL中的数据水平拆分软件
pgQ:使用PostgreSQL的消息队列软件
Londiste:用C语言实现的在PostgreSQL数据库之间进行逻辑同步的软件
全球最大的CRM软件服务提供商Salesforce也开始使用PostgreSQL,并招募了PostgreSQL内核开发者Tom lane。
2012年,美国联邦机构全面转向PostgreSQL阵营;法国也正积极推动政府机构采用PostgreSQL数据库,从而取代商业数据库。
在国内,越来越多的公司开始使用PostgreSQL,如斯凯网络(股票代码:MOBI)的后台数据库基本使用的都是PostgreSQL数据库,去哪儿网(qunar.com)也大量使用了PostgreSQL数据库。
主流的云服务提供商如亚马逊、阿里云的RDS(关系型数据库服务)同样提供了PostgreSQL的支持。
更多的使用PostgreSQL数据库的情况可以见PostgreSQL官方网站(http://www.postgresql.org/about/users/)。
1.2 PostgreSQL数据库与其他数据库的对比
1.2.1PostgreSQL与MySQL数据库的对比
可能有人会问,既然已经有一个人气很高的开源数据库MySQL了,为什么还要使用PostgreSQL?这主要是因为在一些应用场景中,使用MySQL有以下几个缺点:
功能不够强大:MySQL的多表连接查询方式只支持“Nest Loop”,不支持“hash join”和“sort merge join”。不仅如此,还有很多SQL语法它也不支持,子查询性能比较低。由于它不支持sequence,有公司还为此专门开发了统一序号分发中心的软件。
性能优化工具和度量信息不足:MySQL在运行过程中如果出现问题,只产生很少的性能数据,很难让维护人员准确定位问题产生的原因。MySQL的复制是异步的,无法通过Master/Slave做到数据零丢失。一些第三方公司也有改造MySQL源代码实现同步复制,但这些方案要么是没有开源,要么已开源却又不是很稳定,所以,对于普通大众来说,如何实现同步复制成了一个令人头疼的问题。
在线操作功能较弱:如果在MySQL表中加列,基本上是新建一个表,而且建索引时也会锁定整张表,即在建索引的过程中,表不能做任何操作。一些大的互联网公司或者是修改MySQL源码来实现在线DDL的功能,或者是通过上层架构来解决这个问题,如先在slave数据库上把DDL做完,然后把应用从master库切换到slave,再把原先的master上把DDL做完。第一种方法,需要公司有很强的MySQL研发能力,第二种方法需要公司有较强的开发能力,能设计出较强的应用架构。这对于一些中小型公司来说不太容易实现。
相对这些MySQL的弱点,PostgreSQL有以下几个优点:
PostgreSQL功能强大:支持所有主流的多表连接查询的方式(如:“Nest loop”、“ hash join”“sort merge join”等);支持绝大多数的SQL语法(如:with子句)。PostgreSQL是笔者见过的对正则表达式支持最强、内置函数也是最丰富的数据库。字段类型还支持数组类型。除了可以使用PL/PGSQL写存储过程外,还可以使用各种主流开发语言的语法(如:Python语言的PL/Python、Perl语言的PL/Perl来写存储过程)。这些强大的功能可以大大地节约开发资源。很多开发人员在PostgreSQL上做开发时,会发现数据库已帮自己实现了很多功能,甚至有一些业务功能都可直接使用数据库的功能解决,不再需要写代码来实现了。
性能优化工具与度量信息丰富:PostgreSQL数据库中有大量的性能视图,可方便地定位问题(比如:可看到正在执行的SQL,可通过锁视图看到谁在等待、哪条记录被锁定等)。PostgreSQL中设计了专门的架构和进程用于收集性能数据,既有物理I/O方面的统计,也有表扫描及索引扫描方面的性能数据。
在线操作功能好:PostgreSQL增加空值的列时,本质上只是在系统表上把列定义上,无须对物理结构做更新,这就让PostgreSQL在加列时可以做到瞬间完成。PostgreSQL还支持在线建索引的功能,建索引的过程可以不锁更新操作。
从PostgreSQL9.1开始,支持同步复制功能(synchronous replication),通过master和slave之间的复制可以实现零数据丢失的高可用方案。
另外,由于MySQL对SQL语法支持的功能较弱,基本上不适合做数据仓库。虽然也有些厂商开发了基于MySQL的数据仓库存储引擎(如Infobright),但这个方案只是解决了部分数据仓库的问题,SQL功能弱的问题仍无法完全解决。另外,Infobright的社区版本功能上还有很多的限制,如不支持数据更新,不支持太多的并发执行(最多支持十几个)等。而PostgreSQL不仅支持复杂的SQL,还支持大量的分析函数,非常适合做数据仓库。
PostgreSQL数据库中还有一些支持移动互联网时代的新功能,如空间索引。PostGIS是最著名的一个开源GIS系统,它是PostgreSQL中的一个插件,通过它可以很方便地解决LBS中的一些位置计算问题。
综上所述,PostgreSQL数据库是一个功能强大,又带有移动互联网特征的开源数据库。如果你仅仅是想把数据库作为一个简单的存储功能使用(如一些大的互联网公司),一些较复杂的功能都想放在应用中来实现,那么选择MySQL或一些NoSQL产品都是合适的;如果你应用的数据访问很简单(如大多数的blog系统),那么后端使用MySQL也是很合适的。但如果你的应用不像blog系统那么简单,而你又不想消耗太多的开发资源,那么PostgreSQL是一个明智的选择。最有说服力的例子就是图片分享公司instagram,在使用python+PostgreSQL架构后,只是十几个人就支持起了整个公司的业务。在数据库中使用PostgreSQL的感觉,就像在开发语言中使用python,会让你的工作变得简洁和高效。
1.2.2 PostgreSQL与Oracle数据库的对比
从功能上说,PostgreSQL要比Oracle数据库稍弱,如不支持索引组织表等。毕竟Oracle数据库是目前功能最强大的商业数据库,但PostgreSQL算是功能最强大的开源数据库。
PostgreSQL与Oracle有很多相似之处:都是使用共享内存的进程结构,客户端与数据库服务器建立一个连接后,数据库服务器就启动一个进程为这个连接服务,这与MySQL的线程模型不一样。此外,PostgreSQL的WAL日志与Oracle的Redo日志都是记录物理块数据变化的,这与MySQL的binlog也不同。
PostgreSQL与Oracle的不同之处在于:PostgreSQL有更多的支持互联网特征的功能。如PostgreSQL数据类型支持网络地址类型、XML类型、JSON类型、UUID类型,以及数组类型,有强大的正则表达式函数,where条件中可以使用正则表达式匹配,可以使用Python、Perl等语言写存储过程等。
另外,PostgreSQL更小巧。Oracle安装包动则几个GB以上,PostgreSQL安装包只有几十MB大小。在任何一个环境都可以容易地安装PostgreSQL。
1.3 小结
本章主要给大家介绍了什么是PostgreSQL数据库,它有哪些强大的功能,以及目前的一些应用情况,以便大家对PostgreSQL有一个初步的认识。
第2章
PostgreSQL安装与配置
本章将着重介绍PostgreSQL数据库的安装和配置方法。安装方法分为两类:一种是从二进制安装包进行安装,另一种是从源码安装。各个Linux的发行版本中,都内置了PostgreSQL的二进制安装包,但内置的版本可能较旧。二进制包安装的方法一般都是通过不同发行版本的Linux下的包管理器进行的,如在Redhat下是yum,在Ubuntu下是apt-get。使用源码安装更灵活,用户可以有更多的选择,可以选择较新的版本、配置不同的编译选项,编译出用户需要的功能。
2.1 从发行版本安装
2.1.1 在Debian或Ubuntu下的安装
在Debian和Ubuntu下一般使用apt-get命令或aptitude命令来安装软件,命令如下:
sudo apt-get install postgresql
安装完毕后,PostgreSQL数据库就启动了,如果想进入数据库,需要切换到postgres用户下:
su - postgres
然后使用psql连接到数据库中,从操作系统下的“postgres”用户(注意这里指的不是数据库中的postgres用户)连接数据库是不需要密码的,如下:
root@osdba-laptop:~# sudo su - postgres
postgres@osdba-laptop:~$ psql
psql (9.1.9)
Type "help" for help.
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access
privileges
-----------+----------+----------+------------+------------+--------------------
postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres
+
| | | | |
postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres
+
| | | | |
postgres=CTc/postgres
(3 rows)
postgres=# \q
在上面的示例中,使用psql命令连接PostgreSQL数据库,psql是PostgreSQL中的客户端工具。“\l”是列出所有数据库的命令,“\q”是退出psql的命令,在后面的章节中还会详细介绍psql的使用方法。
在Debian或Ubuntu下,使用apt-get安装完成的PostgreSQL数据库的数据目录在/var/lib/postgresql/<dbversion>/main目录下:
postgres@osdba-laptop:~$ cd /var/lib/postgresql/9.1/main
postgres@osdba-laptop:~/9.1/main$ ls -l
total 56
drwx------ 5 postgres postgres 4096 Jun 29 11:55 base
drwx------ 2 postgres postgres 4096 Jun 29 11:55 global
drwx------ 2 postgres postgres 4096 Jun 29 11:55 pg_clog
drwx------ 4 postgres postgres 4096 Jun 29 11:55 pg_multixact
drwx------ 2 postgres postgres 4096 Jun 29 11:55 pg_notify
drwx------ 2 postgres postgres 4096 Jun 29 11:55 pg_serial
drwx------ 2 postgres postgres 4096 Jun 29 12:00 pg_stat_tmp
drwx------ 2 postgres postgres 4096 Jun 29 11:55 pg_subtrans
drwx------ 2 postgres postgres 4096 Jun 29 11:55 pg_tblspc
drwx------ 2 postgres postgres 4096 Jun 29 11:55 pg_twophase
-rw------- 1 postgres postgres 4 Jun 29 11:55 PG_VERSION
drwx------ 3 postgres postgres 4096 Jun 29 11:55 pg_xlog
-rw------- 1 postgres postgres 133 Jun 29 11:55 postmaster.opts
-rw------- 1 postgres postgres 100 Jun 29 11:55 postmaster.pid
lrwxrwxrwx 1 root root 36 Jun 29 11:55 server.crt ->
/etc/ssl/certs/ssl-cert-snakeoil.pem
lrwxrwxrwx 1 root root 38 Jun 29 11:55 server.key ->
/etc/ssl/private/ssl- cert-snakeoil.key
安装完成后,可以使用Linux下的服务管理命令service来启停数据库:
osdba@osdba-laptop:~$ sudo service postgresql status
9.1/main (port 5432): online
osdba@osdba-laptop:~$ sudo service postgresql stop
* Stopping PostgreSQL 9.1 database server
[ OK ]
osdba@osdba-laptop:~$ sudo service postgresql start
* Starting PostgreSQL 9.1 database server
[ OK ]
osdba@osdba-laptop:~$
2.1.2在Redhat、CentOS或Fedora下的安装
在Redhat、CentOS或Fedora下可使用yum工具来安装PostgreSQL,但这些系统的软件库中自带的PostgreSQL版本较低,其版本情况见表2-1。
表2-1Linux发行版本自带的PostgreSQL版本
Linux发行版本 自带的PostgreSQL版本
RHEL/CentOS/SL 5 8.1 (also supplies package postgresql84)
RHEL/CentOS/SL 6 8.4
Fedora 16、Fedora 17 9.1
Fedora 18 9.2
如果上面的PostgreSQL版本能满足你的需要,可按下面的步骤进行安装,否则就参照2.3.1节中的内容进行安装。
安装命令如下:
yum install postgresql-server.x86_64
具体安装过程如下:
[root@localhost ~]# yum install postgresql-server.x86_64
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.163.com
* extras: mirrors.163.com
* updates: mirrors.163.com
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package postgresql-server.x86_64 0:8.4.13-1.el6_3 will be installed
--> Processing Dependency: postgresql-libs(x86-64) = 8.4.13-1.el6_3 for package: postgresql-server-8.4.13-1.el6_3.x86_64
--> Processing Dependency: postgresql(x86-64) = 8.4.13-1.el6_3 for package: postgresql-server-8.4.13-1.el6_3.x86_64
--> Processing Dependency: libpq.so.5()(64bit) for package: postgresql-server-8.4.13-1.el6_3.x86_64
--> Running transaction check
---> Package postgresql.x86_64 0:8.4.13-1.el6_3 will be installed
---> Package postgresql-libs.x86_64 0:8.4.13-1.el6_3 will be installed
--> Finished Dependency Resolution
Dependencies Resolved
================================================================================
Package Arch
Version Repository Size
================================================================================
Installing:
postgresql-server x86_64
8.4.13-1.el6_3 base 3.4 M
Installing for dependencies:
postgresql x86_64
8.4.13-1.el6_3 base 2.8 M
postgresql-libs x86_64
8.4.13-1.el6_3 base 200 k
Transaction Summary
================================================================================
Install 3 Package(s)
Total size: 6.4 M
Installed size: 29 M
Is this ok [y/N]: Y
yum还会让你选择是否把一些依赖的包也安装上,当然要选择“Y”:
Downloading Packages:
warning: rpmts_HdrFromFdno: Header V3 RSA/SHA1 Signature, key ID c105b9de: NOKEY
Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
Importing GPG key 0xC105B9DE:
Userid : CentOS-6 Key (CentOS 6 Official Signing Key) <centos-6-key@centos.org>
Package: centos-release-6-4.el6.centos.10.x86_64
(@anaconda-CentOS-201303020151.x86_64/6.4)
From : /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
Is this ok [y/N]: Y
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
Installing : postgresql-libs-8.4.13-1.el6_3.x86_64
1/3
Installing : postgresql-8.4.13-1.el6_3.x86_64
2/3
Installing : postgresql-server-8.4.13-1.el6_3.x86_64
3/3
Verifying : postgresql-server-8.4.13-1.el6_3.x86_64
1/3
Verifying : postgresql-libs-8.4.13-1.el6_3.x86_64
2/3
Verifying : postgresql-8.4.13-1.el6_3.x86_64
3/3
Installed:
postgresql-server.x86_64 0:8.4.13-1.el6_3
Dependency Installed:
postgresql.x86_64 0:8.4.13-1.el6_3
postgresql-libs.x86_64 0:8.4.13-1.el6_3
Complete!
[root@localhost ~]#
这样就安装好了。
在RedHat下,安装好后,PostgreSQL服务并没有启动:
[root@localhost ~]# service postgresql status
postmaster is stopped
直接启动会报错:
[root@localhost ~]# service postgresql start
/var/lib/pgsql/data is missing. Use "service postgresql initdb" to initialize the cluster first.
[FAILED]
上面是在提示数据库还没有初使用化,请按提示把数据库初使用化:
[root@localhost ~]# service postgresql initdb
Initializing database: [ OK ]
再启动数据库:
[root@localhost ~]# service postgresql status
postmaster (pid 1345) is running...
切换到操作系统下的“postgres”用户,登录数据库:
[root@localhost ~]# su - postgres
-bash-4.1$ psql
psql (8.4.13)
Type "help" for help.
postgres=# \l
List of databases
Name | Owner | Encoding | Collation | Ctype | Access
privileges
-----------+----------+----------+-------------+-------------+------------------
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres
:
postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres
:
postgres=CTc/postgres
(3 rows)
postgres=#
这样就可以了。
也可以使用下面的命令把第三方贡献的软件包安装上:
yum install postgresql-contrib.x86_64
在RedHat或CentOS下,默认安装上的PostgreSQL的数据目录在/var/lib/pgsql/data目录下,如下:
-bash-4.1$ ls -l /var/lib/pgsql/data
total 80
drwx------. 5 postgres postgres 4096 Jun 30 11:07 base
drwx------. 2 postgres postgres 4096 Jun 30 11:08 global
drwx------. 2 postgres postgres 4096 Jun 30 11:07 pg_clog
-rw-------. 1 postgres postgres 3411 Jun 30 11:07 pg_hba.conf
-rw-------. 1 postgres postgres 1631 Jun 30 11:07 pg_ident.conf
图 2-1 PostgreSQL官方网站drwx------. 4 postgres postgres 4096 Jun 30 11:07 pg_multixact
drwx------. 2 postgres postgres 4096 Jun 30 11:13 pg_stat_tmp
drwx------. 2 postgres postgres 4096 Jun 30 11:07 pg_subtrans
drwx------. 2 postgres postgres 4096 Jun 30 11:07 pg_tblspc
drwx------. 2 postgres postgres 4096 Jun 30 11:07 pg_twophase
-rw-------. 1 postgres postgres 4 Jun 30 11:07 PG_VERSION
drwx------. 3 postgres postgres 4096 Jun 30 11:07 pg_xlog
-rw-------. 1 postgres postgres 16886 Jun 30 11:07 postgresql.conf
-rw-------. 1 postgres postgres 57 Jun 30 11:08 postmaster.opts
-rw-------. 1 postgres postgres 45 Jun 30 11:08 postmaster.pid
2.1.3 在Windows下的安装
在Windows安装时,先要到官网上下载PostgreSQL的Windows安装包,如图2-1所示。
图 2-1 PostgreSQL官方网站
点页面中的“download”,进入下载页面,如图2-2所示。
图2-2 PostgreSQL官方下载页面
然后选择下载安装包的类型为“Windows”,进入“Windows”安装包的下载界面,如图2-3所示。
图2-3 PostgreSQL Windows版本下载页面
这里需要根据你的Windows是32位的还是64位来选择下载合适的安装包,如图2-4所示。
图2-4 PostgreSQL Windows版本下的各种类型下载页面
因为Windows版本的安装包,是Enterprise DB公司制作的,所以下载时会显示EnterpriseDB公司的界面,如图2-5所示。
图2-5 PostgreSQL Windows版本下载转到EnterpriseDB公司页面
如果在可以下载时就选择运行,那么在下载后,就会直接运行安装程序,当然也可以在下载完后,再双击安装程序,如图2-6所示。
安装程序运行后,即会显示出安装向导,点“Next”即可,如图2-7所示。
进入选择安装目录界面,一般选择默认安装目录即可,可直接点“Next”,如图2-8所示。
进入选择数据目录的界面,根据实际需要,选择具体的目录,然后点“Next”,如图2-9所示。
进入数据库超级用户postgres的密码设置界面,以后可以使用这个超级用户增加更多的数据库用户,设置完后点“Next”,如图2-10所示。
然后进入选择数据库监听端口的界面,如果5432这个端口没有被别的应用程序占用,那么可使用这个默认端口,点“Next”,如图2-11所示。
选择语言,使用默认设置就可以了,点“Next”,如图2-12所示。
进入准备安装的界面,点“Next”,如图2-13所示。
开始安装,如图2-14所示。
安装完毕后,会问你是否需要使用“Stack Builder”安装一些附加的软件。Stack Builder是一个安装PostgreSQL附加软件的图形化工具。如果不需要,可以把选择框中的勾去掉,直接结束安装。
如果没有去掉,则会出现“Stack Builder”的界面,在该界面中会提示你为哪一个PostgreSQL安装附加软件(出现此提示的原因是可以安装多个不同版本的PostgreSQL),如图2-16所示。
这时会出现一个可以选择安装附加软件的界面,根据需要选择了附加软件后,点“Next”,如图2-17所示。
如果是第一次安装,不知道要安装哪些附加软件,可以点取消。以后需要时可以再次运行“Stack Builder”安装相应的附加软件。
2.1.4 发行版安装总结
Windows下的安装是比较简单的,只需要运行图形界面,基本上在安装的过程中点选“Next”项就可以完成安装。
Linux下各发行版本则使用相应版本的包管理器来进行安装即可。
前面曾提到,从发行版本安装PostgreSQL,所安装的一般不是最新版本,如果想安装最新版本的PostgreSQL,则要看下面介绍的方法或见2.3.1节的技巧。
2.2 从源码安装
2.2.1 编译安装过程介绍
这里先把大致的安装过程介绍一下。
第一步:下载源代码。
第二步:编译安装。过程与Linux下其他软件的编译安装过程相同,都是“三板斧”:
./configure
make
make install
第三步:编译安装完成后执行如下步骤。
1)使用initdb命令初使用化数据库簇。
2)启动数据库实例。
3)创建一个应用使用的数据库。
数据库簇是指数据库实例管理的系统文件和各个数据库文件的一个集合。
2.2.2 下载源代码
打开PostgreSQL的官方网站www.postgresql.org,如图2-18所示。
图2-18 PostgreSQL官方网站界面
点击网站菜单中的download,进入下载页面,如图2-19所示。
图2-19 PostgreSQL官方网站中的源代码下载界面
在下载页面中点左侧的“Source”,进入源代码下载页面,如图2-20所示。
图2-20 PostgreSQL官方源码下载中的选择版本界面
在源代码页面中选择合适的版本,比如v9.2.4,如图2-21所示。
图2-21 PostgreSQL官方源码下载中的选择v9.2.4版本界面
然后,在上面的页面中选择合适的压缩包下载就可以了,一般选择bz2的压缩包,因为这种格式体积较小。
2.2.3 编译及安装
默认情况下,安装会用到数据库中的压缩功能,而这个功能的实现需要第三方的压缩开发包zlib支持,在不同的Linux发行版本下,此包的名字会不太一样,但包的名字一般都含有“zlib”和“dev”两个字符串,“dev”是“develop”即开发包的意思。如在Ubuntu12.04下,可以使用下面的方法查找包的名称:
osdba@osdba-laptop:~$ aptitude search zlib |grep dev
p libghc-bzlib-dev - Haskell bindings to the bzip2 library
p libghc-bzlib-dev:i386 - Haskell bindings to the bzip2 library
v libghc-bzlib-dev-0.5.0.3-77459: -
v libghc-bzlib-dev-0.5.0.3-f7d98 -
p libghc-zlib-bindings-dev - low-level bindings to zlib
p libghc-zlib-bindings-dev:i386 - low-level bindings to zlib
v libghc-zlib-bindings-dev-0.1.0. -
v libghc-zlib-bindings-dev-0.1.0. -
p libghc-zlib-conduit-dev - streaming compression/decompression via co
p libghc-zlib-conduit-dev:i386 - streaming compression/decompression via co
v libghc-zlib-conduit-dev-0.4.0.1 -
v libghc-zlib-conduit-dev-0.4.0.1 -
p libghc-zlib-dev - Compression and decompression in the gzip
p libghc-zlib-dev:i386 - Compression and decompression in the gzip
v libghc-zlib-dev-0.5.3.3-78ddb:i -
v libghc-zlib-dev-0.5.3.3-7baa4 -
p libghc-zlib-enum-dev - enumerator interface for zlib compression
p libghc-zlib-enum-dev:i386 - enumerator interface for zlib compression
v libghc-zlib-enum-dev-0.2.2.1-16 -
v libghc-zlib-enum-dev-0.2.2.1-f8 -
p libghc6-bzlib-dev - transitional dummy package
p libghc6-zlib-dev - transitional dummy package
p lua-zlib-dev - zlib development files for the Lua languag
p lua-zlib-dev:i386 - zlib development files for the Lua languag
p zlib1g-dbg - compression library - development
p zlib1g-dbg:i386 - compression library - development
i A zlib1g-dev - compression library - development
p zlib1g-dev:i386 - compression library - development
从上面列出的包来看,只有“zlib1g-dev”的名称与我们需要的zlib开发包最接近,从而确定在Ubuntu12.10上(当然这还需要一些经验)应该安装这个包。
如果想要方便地在psql中使用上下键翻查历史命令,按照PostgreSQL官方手册的说明,还需要安装readline的开发包。与上面的方法类似,先查找包含“readline”和“dev”的包:
osdba@osdba-laptop:~$ aptitude search readline |grep dev
v lib32readline-dev -
p lib32readline-gplv2-dev - GNU readline and history libraries, develo
p lib32readline6-dev - GNU readline and history libraries, develo
v lib64readline-dev:i386 -
p lib64readline-gplv2-dev:i386 - GNU readline and history libraries, develo
p lib64readline6-dev:i386 - GNU readline and history libraries, develo
p libghc-readline-dev - Interface to the GNU readline library
p libghc-readline-dev:i386 - Interface to the GNU readline library
v libghc-readline-dev-1.0.1.0-52b -
v libghc-readline-dev-1.0.1.0-69f -
i libreadline-dev - GNU readline and history libraries, develo
p libreadline-dev:i386 - GNU readline and history libraries, develo
p libreadline-gplv2-dev - GNU readline and history libraries, develo
p libreadline-gplv2-dev:i386 - GNU readline and history libraries, develo
i A libreadline6-dev - GNU readline and history libraries, develo
p libreadline6-dev:i386 - GNU readline and history libraries, develo
从上面列出的包来看,只有“libreadline6-dev”的名称与我们需要的readline开发包最接近,所以应该安装这个包。
把前面下载的压缩包解压,如果该压缩包名称为postgresql-9.2.4.tar.bz2,解压命令则为:
tar xvf postgresql-9.2.4.tar.bz2
对于PostgreSQL8.X的版本,一般编译安装的第一板斧是使用configure命令,如下:
./configure --prefix=/usr/local/pgsql8.4.17 --enable-thread-safety --with-perl --with-python
对于PostgreSQL9.X的版本,一般编译安装的命令如下:
./configure --prefix=/usr/local/pgsql9.2.4 --with-perl --with-python
对比可以发现,在PostgreSQL8.X中,编译命令里有“--enable-thread-safety”选项,而在PostgreSQL9.X中没有这个选项。因为在日常使用中,一般要求客户端是线程安全的,PostgreSQL9.X考虑到这个问题,默认为线程安全的了,而PostgreSQL8.X没有,所以要加上这个选项。
再看看下面两个选项:
--with-perl: 加上这个选项,才能使用perl语法的PL/Perl过程语言写自定义函数,一般都需要。使用这个选项要求先安装perl开发包,该包在Ubuntu或Debian下的名称为:libperl-dev,可使用apt-get install libperl-dev安装。
--with-python:加上这个选项,才能使用python语法的PL/Python过程语言写自定义函数,一般都需要。使用这个选项要求先安装python-dev开发包,该包在Ubuntu或Debian下的名称为:python-dev,可使用apt-get install python-dev安装。
编译安装的第二板斧是运行make命令,这个命令没有什么好说的,直接运行就可以了:
make
按官方文档要求,使用make命令时,其版本要在gmake3.8以上,目前绝大多数的Linux发行版本都满足要求,所以在Linux下一般不需要检查make的版本,但如果是在其他非Linux的UNIX平台上,还是先检查一下make的版本比较好,命令如下:
osdba@osdba-laptop:~$ make --version
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
在其他的UNIX平台上,有可能存在非GNU的make,这时GNU的make的名称会是gmake。
编译安装的第三板斧是运行make install命令。如果是在一般用户下进行编译的,可能对/usr/local目录没有写的权限,而运行make install命令时是需要使用root权限的,所以在Debian或Ubuntu下可以使用sudo:
sudo make install
在前面我们看到--prefix设置的路径为“/usr/local/pgsql9.2.4”,如果不设置这个路径,默认的路径将是“/usr/local”,为什么要在此路径上加上PostgreSQL的版本号呢?这是为了升级方便。make install命令运行完之后,还要进入/usr/local目录下,为/usr/local/pgsql9.2.4建立一个/usr/local/pgsql的链接:
cd /usr/localL9.2.
sudo ln -sf /usr/local/pgsql9.2.4 /usr/local/pgsql
如果PostgreSQL9.2.5发布了,在编译PostgreSQL9.2.5后,只需把现有的数据库停掉,然后把链接/usr/local/pgsql指向先前的版本/usr/local/pgsql9.2.5即可完成升级。是不是觉得很方便呢?
2.2.4 安装后的配置
安装完后,需要设置PostgreSQL可执行文件的路径:
export PATH=/usr/local/pgsql/bin:$PATH
还要设置共享库的路径:
export LD_LIBRARY_PATH=/usr/local/pgsql/lib
如果想让以上配置对所有的用户生效,可以把以上内容加到/etc/profile文件中,/etc/profile中的内容看起来类似如下:
...
...
...
if [ -d /etc/profile.d ]; then
for i in /etc/profile.d/*.sh; do
if [ -r $i ]; then
. $i
fi
done
unset i
fi
export PATH=/usr/local/pgsql/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/pgsql/lib:$LD_LIBRARY_PATH
如果想让以上配置对当前用户生效,在Linux下可以把以上内容加到.bashrc文件中,在其他UNIX下可以加到.profile文件中。
有人问在Linux下为何不加到.profile文件或.bash_profile文件中,这是因为有时在图形界面下打开一个终端,.profile或.bash_profile不会生效。
2.2.5 创建数据库簇
先设定数据库中数据目录的环境变量:
export PGDATA=/home/osdba/pgdata
执行下面的命令创建数据库簇:
initdb
这样就完成了。
2.2.6 安装contrib目录下的工具
contrib下面有一些工具比较实用,一般都会安装上,其安装方法也与Linux下的编译过程相同,如下:
cd postgresql-9.2.3/contrib
make
sudo make install
2.2.7 启动和停止数据库
启动数据库的命令为:
pg_ctl start -D $PGDATA
其中,环境变量$PGDATA指向具体的PostgreSQL数据库的数据目录,看以下示例:
osdba@osdba-laptop:~$ pg_ctl start -D /home/osdba/pgdata
server starting
停止数据库的命令如下:
pg_ctl stop -D $PGDATA [-m SHUTDOWN-MODE]
其中-m是指定数据库的停止方法,有以下三种:
smart:等所有的连接中止后,关闭数据库。如果客户端连接不终止,则无法关闭数据库。
fast:快速关闭数据库,断开客户端的连接,让已有的事务回滚,然后正常关闭数据库。相当于Oracle数据库关闭时的immediate模式。
immediate:立即关闭数据库,相当于数据库进程立即停止,直接退出,下次启动数据库需要进行恢复。相当于Oracle数据库关闭时的abort模式。
PostgreSQL下的immediate关机模式是相当于Oracle中的Abort的关机模式,而Oracle下的immediate关机模式实际上对应的是PostgreSQL下的fast,Oracle DBA尤其要注意这一点。
其中,比较常用的关闭数据库的方法是“fast”方法。
2.2.8 编译安装时的常见问题及解决方法
问题一:./configure时报“error: zlib library not found”错误是怎么回事?报错信息如下:
osdba@ubuntu01:~/src/postgresql-9.2.3$ ./configure
--prefix=/usr/local/pgsql9.2.3 --with-perl --with-python
checking build system type... x86_64-unknown-linux-gnu
....
....
checking for inflate in -lz... no
configure: error: zlib library not found
If you have zlib already installed, see config.log for details on the failure. It is possible the compiler isn't looking in the proper directory.
Use --without-zlib to disable zlib support.
答:这是因为没有安装zlib开发包,安装后将不再报错。
问题二:已安装了“libreadline6”的包,但./configure时仍报“error: readline library not found”错误是怎么回事?报错信息如下:
osdba@ubuntu01:~/src/postgresql-9.2.3$ ./configure
--prefix=/usr/local/pgsql9.2.3 --with-perl --with-python
checking build system type... x86_64-unknown-linux-gnu
...
...
checking for library containing readline... no
configure: error: readline library not found
If you have readline already installed, see config.log for details on the failure. It is possible the compiler isn't looking in the proper directory.
Use --without-readline to disable readline support.
答:包安装错了,是需要安装开发包,即安装libreadline6-dev这个包,而不是libreadline6这个包。
问题三:在运行./configure命令时报以下警告,是否会导致编译出来的PostgreSQL的功能缺失?警告信息如下:
checking for bison... no
configure: WARNING:
*** Without Bison you will not be able to build PostgreSQL from Git nor
*** change any of the parser definition files. You can obtain Bison from
*** a GNU mirror site. (If you are using the official distribution of
*** PostgreSQL then you do not need to worry about this, because the Bison
*** output is pre-generated.)
checking for flex... no
configure: WARNING:
*** Without Flex you will not be able to build PostgreSQL from Git nor
*** change any of the scanner definition files. You can obtain Flex from
*** a GNU mirror site. (If you are using the official distribution of
*** PostgreSQL then you do not need to worry about this because the Flex
*** output is pre-generated.)
答:不会影响编译出来的PostgreSQL功能。这个警告的意思是没有bison和flex是无法使用git方式编译的。这里没有使用git,所以没有关系。bison是自动生成语法分析器的程序,flex则是自动生成词法分析器的程序,在PostgreSQL主要用于SQL的词法解析和语法解析。因为在源码包中已经生成了词法解析和语法解析的C源代码,所以没有bison和flex,也能正常编译。当然也可以把bison和flex这两个工具安装上,命令如下:
sudo aptitude install bison flex
问题四:在运行make时报“cannot find -lperl”的错误为什么?报错信息如下:
gcc -O2 -Wall -Wmissing-prototypes -Wpointer-arith
-Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard
-fpic -shared -o plperl.so plperl.o SPI.o Util.o -L../../../src/port
-Wl,--as-needed -Wl,-rpath,'/usr/lib/perl/5.14/CORE',--enable-new-dtags
-fstack-protector -L/usr/local/lib -L/usr/lib/perl/5.14/CORE -lperl -ldl -lm
-lpthread -lc -lcrypt
/usr/bin/ld: cannot find -lperl
collect2: error: ld returned 1 exit status
make[3]: *** [plperl.so] Error 1
make[3]: Leaving directory `/home/osdba/src/postgresql-9.2.3/src/pl/plperl'
make[2]: *** [all-plperl-recurse] Error 2
make[2]: Leaving directory `/home/osdba/src/postgresql-9.2.3/src/pl'
make[1]: *** [all-pl-recurse] Error 2
make[1]: Leaving directory `/home/osdba/src/postgresql-9.2.3/src'
make: *** [all-src-recurse] Error 2
答:这是在./configure时加了--with-perl,却没有安装perl开发包导致的。注意,若没有安装perl开发包,在运行./configure时并不报错,而是到运行make命令的时候才报错。在Debian或Ubuntu下,只要安装libperl-dev包即可:
sudo aptitude install libperl-dev
2.3 安装技巧介绍
2.3.1 在Redhat、CentOS下使用二进制包安装较新版本的方法
如果认为Redhat或CentOS上自带的PostgreSQL版本太低,想要使用新版本,可以使用下面的方法安装。
使用PostgreSQL官方的RPM包,将新版本信息加到版本库中:
rpm -i
http://yum.postgresql.org/9.2/redhat/rhel-6-x86_64/pgdg-redhat92-9.2-7.noarch.rpm
然后使用yum install 命令安装新版本:
yum install postgresql92-server.x86_64
再使用1.1.2节介绍的方法安装新版本的PostgreSQL:
[root@localhost ~]# service postgresql-9.2 status
is stopped
[root@localhost ~]# service postgresql-9.2 initdb
Initializing database: [ OK ]
[root@localhost ~]# service postgresql-9.2 start
Starting postgresql-9.2 service: [ OK ]
登录数据库:
[root@localhost ~]# su - postgres
-bash-4.1$ psql
psql (9.2.4)
Type "help" for help.
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access
privileges
-----------+----------+----------+-------------+-------------+------------------
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres
+
| | | | |
postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres
+
| | | | |
postgres=CTc/postgres
(3 rows)
postgres=# \q
使用下面命令把相关的第三方贡献包也安装上:
yum install postgresql92-contrib.x86_64
新版本的PostgreSQL的数据目录在/var/lib/pgsql/<version>/data目录下,“version”代表PostgreSQL的版本,如9.2版本就安装在/var/lib/pgsql/9.2/data目录下。
2.3.2 如何使用较大的数据块提高I/O性能
在数据仓库中使用PostgreSQL时,若希望使用较大的数据块提高I/O性能怎么办?要解决这类问题,只能采用从源码安装的方法,在执行./configure命令时指定较大的数据块,一般也需要指定较大的WAL日志块和WAL日志文件的大小。如想指定128KB的数据块、128KB的WAL日志块、64MB的WAL日志文件,则configure命令如下:
./configure --prefix=/usr/local/pgsql9.2.4 --with-perl --with-python
--with-blocksize=128 --with-wal-blocksize=128 --with-wal-segsize=64
使用此时编译出来的PostgreSQL程序创建的PostgreSQL数据库,不能使用其他块大小的PostgreSQL程序启动。
2.4 PostgreSQL的简单配置
本节将简单介绍PostgreSQL的配置方法,更具体的配置操作会在后面的章节中介绍。PostgreSQL数据库的配置主要是通过修改数据目录下的postgresql.conf文件来实现的。
2.4.1 修改监听的IP和端口
在数据目录下编辑postgresql.conf文件,找到如下内容:
#listen_addresses = 'localhost' # what IP address(es) to listen on;
#port = 5432 # (change requires restart)
其中,参数“listen_addresses”表示监听的IP地址,默认是在“localhost”处监听,也就是“127.0.0.1”的IP地址上监听,这会让远程的主机无法登录这台数据库,如果想从其他的机器上登录这台数据库,需要把监听地址改成实际网络的地址,一种简单的方法是,把这个地址改成“*”,表示在本地的所有地址上监听。
参数“port”表示监听的数据库端口,默认为“5432”,可以不更改。如果一台机器上安装了几个数据库实例(如安装了几个不同版本的PostgreSQL),可以设置为不同的端口。
修改了这两个参数后,需要重启数据库才能生效。
2.4.2 与数据库log相关的参数
来看看与log相关的几个参数:
日志的收集一般是要打开的,所以需要设置:
logging_collector = on
日志的目录一般使用默认值就可以了:
log_directory = 'pg_log'
日志的切换和是否选择覆盖则可以使用如下几种方案。
方案一:每天生成一个新的日志文件。
配置方法如下:
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_truncate_on_rotation = off
log_rotation_age = 1d
log_rotation_size = 0
方案二:每当日志写满一定的大小(如10MB空间),则切换一个日志。
配置方法如下:
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_truncate_on_rotation = off
log_rotation_age = 0
log_rotation_size = 10M
方案三:只保留7天的日志,进行循环覆盖。
配置方法如下:
log_filename = 'postgresql-%a.log' #
log_truncate_on_rotation = on
log_rotation_age = 1d
log_rotation_size = 0
2.4.3 内存参数的设置
PostgreSQL安装完毕后,可以修改以下两个主要内存参数。
shared_buffers:共享内存的大小,主要用于共享数据块。
work_mem:单个SQL执行时,排序、hash join所使用的内存,SQL运行完后,内存就释放了。
shared_buffers默认值为32MB,work_mem为1MB,如果你的机器上有足够的内存,可以把这个参数改得大一些,这样数据库就可以缓存更多的数据块,当读取数据时,就可以从共享内存中读,而不需要再从文件上去读取。
work_mem设置大一些,会让排序操作快一些。
2.5 小结
本章讲解了PostgreSQL在不同平台下的二进制安装方法,以及从源代码进行安装的方法。从前面的叙述中可以看出,在多数Linux发行版本中都自带了PostgreSQL的二进制安装包,可以直接使用Linux发行版本中的包管理器进行安装。不过这些自带的PostgreSQL版本都比较旧,如果想安装较新的PostgreSQL版本,可以从源代码进行编译安装。源代码编译安装也比较简单,要注意的是,需要先把一些依赖的开发包安装上。
第3章
SQL语言入门
SQL是结构化查询语言(STRUCTURED QUERY LANGUAGE)的简称,它是最重要的关系型数据库操作语言,并且它的影响已经超出了数据库领域。比如,在Hadoop中的Hive就是一个SQL接口。
本章将介绍一些通用的、最基础的SQL语法知识,以便于没有接触过数据库的读者能掌握最基础的数据库知识。这些使用语法不仅适用于PostgreSQL数据库,也适用于其他关系型数据库,如MySQL、Oracle。本章是为从没有接触过SQL的读者准备的,对于已有SQL基础的读者,可以略过此章。
3.1 SQL语句语法简介
3.1.1 语句的分类
SQL命令一般分为DQL、DML、DDL几类。
DQL:数据查询语句,基本就是SELECT查询命令,用于数据查询。
DML:Data Manipulation Language的简称,即数据操纵语言,主要用于插入、更新、删除数据,所以也分为INSERT、UPDATE、DELETE三种语句。
DDL:Data Definition Language的缩写,即数据定义语言,主要用于创建、删除,以及修改表、索引等数据库对象语言。
3.1.2 词法结构
每次执行的SQL可以由多条SQL命令组成。多条SQL命令之间由分号(“;”)分隔。
每个SQL命令由一系列的记号组成,这些记号可以由关键字、标识符、双引号包围的标识符、常量、单引号包围的文本常量和特殊的字符等组成。在 SQL 命令里可以有注释,这些注释在PostgreSQL中等效于空白。
举个例子,下面的命令从SQL的语法上来说是合法的:
SELECT * FROM OSDBA_TABLE01;
UPDATE OSDBA_TABLE SET COL1 = 614;
INSERT INTO OSDBA_TABLE VALUES (232, 'hello osdba');
该SQL由三条命令组成。在SQL中,多行命令可以在一行中,也可以在多行中。此外,单条命令也可以占用多行。
SQL命令并未严格地像计算机语言一样明确标识哪些是命令、哪些是操作数或参数。SQL的语法主要是让你比较直观地理解其意思。比如,查询一个表的数据,就是由“SELECT”+“要查询的各列”+“FROM 表”这样的语法组成的。后面的几节会详细叙述SQL的用法。
3.2 DDL语句
DDL语句是创建、修改和删除表的语句,想要掌握SQL语言,必须对它有一定的了解。
3.2.1 建表语句
表是关系型数据库中最基本的对象,数据库中的表与实际生活中的二维表格很相似,有很多列也有很多行,每一列有一个名称,不同的列有不同的数据类型,比如,列可能是数字、文本字符串,也可能是日期类型。建表语句的一个简单语法如下:
CREATE TABLE table_name (
col01_namme data_type,
col02_namme data_type,
col03_namme data_type,
col04_namme data_type,
};
其中“CREATE”、“TABLE”为关键字,是不变的,从字面上也很好理解,表示创建表。“table_name”表示表名,“col01_name”、 “col02_name”、 “col03_name”、 “col04_name”分别表示列名。“data_type”表示数据类型,不同的数据库系统有不同的数据类型名称,即使是相同意思的整数类型,在不同的数据库系统中也有不同的类型名称。变长的字符串在大多数数据库中都可使用 “varchar”类型,比如PostgreSQL、MySQL和Oracle数据库等。整形数据在PostgreSQL和MySQL都可以使用“int”类型。日期类型的名称一般为“date”。例如,要创建一张分数表score,包括“学生名称(student_name)”、“语文成绩(chinese_score)”、“数学成绩(math_score)”、“考试日期(test_date)”四列,则创建这个表的SQL如下:
CREATE TABLE score (
student_name varchar(40),
chinese_score int,
math_score int,
test_date date
);
如果按前面的安装步骤安装完了数据库,之后就可以使用psql工具连接到PostgreSQL数据库了,执行上面的建表语句,如下:
osdba=# CREATE TABLE score (
osdba(# student_name varchar(40),
osdba(# chinese_score int,
osdba(# math_score int,
osdba(# test_date date
osdba(# );
CREATE TABLE
osdba=#
在psql中,可使用\d显示数据库中有哪些表,如下:
osdba=# \d
List of relations
Schema | Name | Type | Owner
--------+-------+-------+-------
public | score | table | osdba
(1 row)
这样就看到了我们建的表。
使用“\d score”可以显示这张表的定义情况:
osdba=# \d score
Table "public.score"
Column | Type | Modifiers
---------------+-----------------------+-----------
student_name | character varying(40) |
chinese_score | integer |
math_score | integer |
test_date | date |
显示列的类型“character varying(40)”实际上与“varchar(40)”的意思是完全一样的,“int”与“integer”的意思也是一样的。
在建表的时候,可以指定表的主键,主键是表中行的唯一标识,这个唯一标识是不能重复的。在创建表的语句中,可以在列定义后面用“primary key”来指定这一列为主键,如下面的学生表:
CREATE TABLE student(no int primary key, student_name varchar(40), age int);
在该表中,学号(no)为主键,则在该列的定义后面加了“primary key”。在psql中演示如下:
osdba=# CREATE TABLE student(no int primary key, student_name varchar(40), age int);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "student_pkey" for table "student"
CREATE TABLE
细心的读者会注意到“NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "student_pkey" for table "student"”这句提醒,它表示系统为主键自动创建了一个隐含的索引“student_pkey”。
3.2.2 删除表语句
删除表的语法比较简单,如下:
DROP TABLE table_name;
其中“table_name”表示要删除的表名。假设要删除前面创建的表student,则可以使用下面的SQL:
DROP TABLE student;
3.3 DML语句
DML用于插入、更新和删除数据。主要包含INSERT语句、UPDATE语句和DELETE语句。
3.3.1 插入语句
可以使用下面的语句往前面创建的学生表(student)中插入数据:
INSERT INTO student VALUES(1, '张三', 14);
由此可以看出,INSERT语句的语法为:以“INSERT INTO”关键字为首,后面跟表名,然后再跟“VALUES”关键字,最后是由小括号包围起来的以逗号分隔的各列数据,数据的顺序与表定义时表列的顺序是一样的。当然也可以在表名后指定要插入数据列的顺序,如下所示:
INSERT INTO student(no, age, student_name) VALUES(2, 13, '李四');
在插入数据时,也可以指定某些列不插入数据,这时这些列的数据会被置为空,如下:
INSERT INTO student(no, student_name) VALUES(2, '王二');
如果在psql中执行了下面的语句,使用SELECT语句就可以查询出数据,查询的语句为:
SELECT * FROM student;
SELECT语句的具体用法会在后面的章节中介绍,现在只需要知道这么用就可以了。
我们查看到的数据如下:
osdba=# select * from student;
no | student_name | age
----+--------------+-----
1 | 张三 | 14
2 | 李四 | 13
3 | 王二 |
(3 rows)
从上面可以看出,在插入数据时,没有提供的列数据会被置为NULL。
3.3.2 更新语句
假设要把student表中所有学生的年龄(age)更新为“15”,则更新语句如下:
UPDATE student SET age = 15;
从上面的语句可以看出,更新语句以“UPDATE” 关键字开始,后面跟表名,然后是“SET”关键字,表示要设置的数据,再后面就是要设置的数据的表达式“age = 15”,设置数据的表达式也很简单,就是“列名=数据”的格式。
实际执行的效果如下:
osdba=# UPDATE student SET age = 15;
UPDATE 3
osdba=# select * from student;
no | student_name | age
----+--------------+-----
1 | 张三 | 15
2 | 李四 | 15
3 | 王二 | 15
(3 rows)
在更新数据时,还可以指定过滤表达式“WHERE”,从而指定更新哪条数据或哪些数据,比如,要更新学号(no)为3的学生年龄为14岁,则使用下面的语句:
UPDATE student SET age =14 WHERE no = 3;
在SET子句中,还可以同时更新多个列的值,如下所示:
UPDATE student SET age =13, student_name='王明充' WHERE no = 3;
3.3.3 删除语句
如果想删除学号(no)为3的记录,语句如下:
DELETE FROM student WHERE no = 3;
由此可见删除语句比较简单,以“DELETE FROM”开始,后面跟表名,然后加“WHERE”子句用于指定要删除的记录。
当然也可以没有“WHERE”子句,这表明要删除整个表的数据,删除表student中所有数据的语句如下:
DELETE FROM student;
3.4 查询语句
3.4.1 单表查询语句
查询student表中所有数据的语句为:
select no, student_name, age from student;
其中“SELECT”是关键字,表示要查询,后面跟多个列名,各列之间使用逗号分隔。其后的“FROM”是关键字,后面跟表的名称。各个列可以是表的列名,也可以是一个表达式,如下:
select age+5 from student;
表达式中可以包括表的列,也可以只是一个与表列无关的表达式,如下:
select no, 3+5 from student;
当表达式与表的列无关时,在PostgreSQL和MySQL中可以不使用“FROM 表名”,这样一来,就可以当作计算器使用了:
osdba=# select 55+88;
?column?
----------
143
(1 row)
osdba=# select 10*2,3*5+2;
?column? | ?column?
----------+----------
20 | 17
(1 row)
如果想查询表中所有列的数据,则可以使用“*”代表所有列,如下:
select * from student;
3.4.2 过滤条件的查询
SELECT语句后面可以通过指定WHERE子句来指定要查询哪条记录或哪些记录。比如,要查询学号为3的记录,其SQL语句为:
osdba=# SELECT * FROM student where no=3;
no | student_name | age
----+--------------+-----
3 | 王明充 | 13
(1 row)
在WHERE条件中也可以使用大于、小于的表达式。比如,想查询年龄大于等于15岁的学生,其语句如下:
osdba=# SELECT * FROM student where age >= 15;
no | student_name | age
----+--------------+-----
1 | 张三 | 15
2 | 李四 | 15
(2 rows)
3.4.3 排序
使用排序子句可以对查询出的数据进行排序,排序子句是在SELECT语句后面再加上“ORDER BY”子句。比如,希望查询出来的结果按年龄排序,则查询语句如下:
osdba=# SELECT * FROM student ORDER BY age;
no | student_name | age
----+--------------+-----
3 | 王明充 | 13
1 | 张三 | 15
2 | 李四 | 15
(3 rows)
排序子句“ORDER BY”应该在“WHERE”子句之前,如果顺序错了,会报错:
osdba=# SELECT * FROM student ORDER BY age WHERE age >= 15;
ERROR: syntax error at or near "WHERE"
LINE 1: SELECT * FROM student ORDER BY age WHERE age >= 15;
把“ORDER BY”子句放到“WHERE”子句后面就不报错了:
osdba=# SELECT * FROM student WHERE age >= 15 ORDER BY age;
no | student_name | age
----+--------------+-----
1 | 张三 | 15
2 | 李四 | 15
(2 rows)
还可以按多个列进行排序。比如,根据“age”和“student_name”两个列来排序:
osdba=# SELECT * FROM student ORDER BY age,student_name;
no | student_name | age
----+--------------+-----
3 | 王明充 | 13
2 | 李四 | 15
1 | 张三 | 15
(3 rows)
也可以在排序子句的列名后加“DESC”进行倒序排序:
osdba=# SELECT * FROM student ORDER BY age DESC;
no | student_name | age
----+--------------+-----
1 | 张三 | 15
2 | 李四 | 15
3 | 王明充 | 13
(3 rows)
osdba=# SELECT * FROM student ORDER BY age DESC,student_name;
no | student_name | age
----+--------------+-----
2 | 李四 | 15
1 | 张三 | 15
3 | 王明充 | 13
(3 rows)
3.4.4 分组查询
如果需要统计不同年龄的学生人数,可以使用分组查询,分组查询子句的关键字为“GROUP BY”,用法如下:
osdba=# SELECT age, count(*) FROM student GROUP BY age;
age | count
-----+-------
15 | 2
13 | 1
(2 rows)
从上面可以看出,使用“GROUP BY”语句时,需要使用聚合函数,常用的聚合函数为“count”、“sum”等。
3.4.5 表join
表join也称为多表关联查询。假设有一张班级表class,建表语句为:
CREATE TABLE class(no int primary key, class_name varchar(40));
表中的“no”表示班级编号,“class_name”表示班级名称。
插入一些测试数据:
osdba=# INSERT INTO class VALUES(1,'初二(1)班');
INSERT 0 1
osdba=# INSERT INTO class VALUES(2,'初二(2)班');
INSERT 0 1
osdba=# INSERT INTO class VALUES(3,'初二(3)班');
INSERT 0 1
osdba=# INSERT INTO class VALUES(4,'初二(4)班');
INSERT 0 1
osdba=# SELECT * FROM class;
no | class_name
----+------------
1 | 初二(1)班
2 | 初二(2)班
3 | 初二(3)班
4 | 初二(4)班
(4 rows)
还有另一张学生表student,建表语句为:
CREATE TABLE student(no int primary key, student_name varchar(40), age int, class_no int);
也插入一些数据:
osdba=# INSERT INTO student VALUES(1, '张三', 14, 1);
INSERT 0 1
osdba=# INSERT INTO student VALUES(2, '吴二', 15, 1);
INSERT 0 1
osdba=# INSERT INTO student VALUES(3, '李四', 13, 2);
INSERT 0 1
osdba=# INSERT INTO student VALUES(4, '吴三', 15, 2);
INSERT 0 1
osdba=# INSERT INTO student VALUES(5, '王二', 15, 3);
INSERT 0 1
osdba=# INSERT INTO student VALUES(6, '李三', 14, 3);
INSERT 0 1
osdba=# INSERT INTO student VALUES(7, '吴二', 15, 4);
INSERT 0 1
osdba=# INSERT INTO student VALUES(8, '张四', 14, 4);
INSERT 0 1
osdba=# SELECT * FROM student;
no | student_name | age | class_no
----+--------------+-----+----------
1 | 张三 | 14 | 1
2 | 吴二 | 15 | 1
3 | 李四 | 13 | 2
4 | 吴三 | 15 | 2
5 | 王二 | 15 | 3
6 | 李三 | 14 | 3
7 | 吴二 | 15 | 4
8 | 张四 | 14 | 4
若现在想查询出每个学生与班级的关系,那么此时就需要关联查询两张表:
SELECT student_name, class_name FROM student, class
WHERE student.class_no = class.no;
查询出来的结果如下:
osdba=# SELECT student_name, class_name FROM student, class
WHERE student.class_no = class.no;
student_name | class_name
--------------+------------
张三 | 初二(1)班
吴二 | 初二(1)班
李四 | 初二(2)班
吴三 | 初二(2)班
王二 | 初二(3)班
李三 | 初二(3)班
吴二 | 初二(4)班
张四 | 初二(4)班
(8 rows)
表关联查询就是在WHERE条件上加上需要关联的条件(两张表关联):
WHERE student.class_no = class.no;
由于在两张表中,有一些列的名称是重复的,如在表student中no表示学生号,而在表class中表示班级号,所以在关键条件中要明确使用“表名”加“列名”来唯一定位这个列。如果输入的表名比较长,不是很方便,这时可以给表起个别名,如下所示:
SELECT student_name, class_name FROM student a, class b
WHERE a.class_no = b.no;
上面的语句中,给表“student”起的别名为“a”,表“class”的别名为“b”,这时条件表达式中“b.no”就代表了表“class”中的“no”列。
在关联查询的WHERE子句中可以再加上其他的过滤条件,如下:
osdba=# SELECT student_name, class_name FROM student a, class b
WHERE a.class_no = b.no AND a.age > 14;
student_name | class_name
---------------+------------
吴二 | 初二(1)班
吴三 | 初二(2)班
王二 | 初二(3)班
吴二 | 初二(4)班
(4 rows)
3.5 其他SQL语句
3.5.1 INSERT INTO... SELECT语句
使用INSERT INTO... SELECT语句可以把数据从一张表插入到另一张表中,这个语句属于DML语句。
假设建了一张学生表的备份表:student_bak
CREATE TABLE student_bak(no int primary key, student_name varchar(40), age int, class_no int);
可以使用下面的语句把数据备份到下面这张备份表中:
INSERT INTO student_bak SELECT * FROM student;
实际演示如下:
osdba=# INSERT INTO student_bak SELECT * FROM student;
INSERT 0 8
osdba=# SELECT * FROM student_bak;
no | student_name | age | class_no
----+--------------+-----+----------
1 | 张三 | 14 | 1
2 | 吴二 | 15 | 1
3 | 李四 | 13 | 2
4 | 吴三 | 15 | 2
5 | 王二 | 15 | 3
6 | 李三 | 14 | 3
7 | 吴二 | 15 | 4
8 | 张四 | 14 | 4
(8 rows)
3.5.2 UNION语句
可以将从两张表查询出来的数据整合在一个结果集下,如:
SELECT * FROM student WHERE no = 1 UNION SELECT * FROM student_bak where no = 2;
这里的语法比较简单,把两个SQL用“UNION”关键字连接起来就可以了。
结果如下:
osdba=# SELECT * FROM student WHERE no = 1 UNION SELECT * FROM student_bak where no = 2;
no | student_name | age | class_no
----+--------------+-----+----------
1 | 张三 | 14 | 1
2 | 吴二 | 15 | 1
(2 rows)
注意,UNION可以把结果集中相同的两条记录合并成一条:
osdba=# SELECT * FROM student WHERE no = 1 UNION SELECT * FROM student_bak where no = 1;
no | student_name | age | class_no
----+--------------+-----+----------
1 | 张三 | 14 | 1
(1 row)
如果不想合并,请使用UNION ALL,如下:
osdba=# SELECT * FROM student WHERE no = 1 UNION ALL SELECT * FROM student_bak where no = 1;
no | student_name | age | class_no
----+--------------+-----+----------
1 | 张三 | 14 | 1
1 | 张三 | 14 | 1
(2 rows)
3.5.3 TRUNCATE TABLE语句
TRUNCATE TABLE语句的用途是清空表内容。不带WHERE条件子句的DELETE 语句也表示清空表的内容。从执行结果看,两者实现了相同的功能,但两者实现的原理是不一样的。
TRUNCATE TABLE是DDL语句,即数据定义语句,相当于用重新定义一个新表的方法把原先表的内容直接丢弃了,所以TRUNCATE TABLE执行起来很快,而DELETE 是DML语句,可以认为DELETE 是把数据一条一条地删除,若要删除很多行数据,就会比较慢。
如果想把表student_bak中的数据清理掉,则可以使用如下命令:
TRUNCATE TABLE student_bak;
3.6 小结
从前面的叙述可以看出,SQL语言是一种声明式编程语言,与命令式编程语言有较大的差异。声明式编程语言主要是描述用户需要做什么,需要得到什么结果的,不像命令式编辑需要描述怎么做,过程是什么。SQL语言能够智能地实现用户的需要,而不需要用户去关心具体的运行过程。完全用SQL写一个应用程序是不可能的,但非计算机专业人士也可以使用SQL,因为SQL是直观易懂的。
Android SQLite (三 ) 全面详解(一)
官网 SQLite是一款轻型的数据库,是关系型数据库(RDBMS)管理系统,它包含在一个相对小的C库中。目前在很多嵌入式产品中使用了它,它占用资源非常 的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix/Android/IOS等等主流的操作系统,同 时能够跟很多程序语言相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源的世界著名数据库管理系统来讲,它的处理速度 比他们都快。
Sqlite命令分类:
(DDL)数据定义语言:
CMD
Description
CREATE
创建一个新的表,一个表的视图,或者数据库中的其他对象。
ALTER
修改数据库中的某个已有的数据库对象,比如一个表。
DROP
删除整个表,或者表的视图,或者数据库中的其他对象。
(DML)数据操作语言:
CMD
Description
INSERT
创建一条记录。
UPDATE
修改记录。
DELETE
删除记录。
(DQL)数据查询语言:
CMD
Description
SELECT
从一个或多个表中检索某些记录。
Sqlite点命令
先看一张Windows下的截图:
这是在Windows的cmd下运行sqlite3命令(如何安装和配置烦请自行google | baidu),然后依据提示运行.help的打印(只截图一部分)。
可以发现sqlite的help列出来了所有sqlite支持的点命令,也可以发现,点命令不需要已”;”结尾。
我们对上面的.help命令进行翻译大致如下:
CMD
Description
.backup ?DB? FILE
备份DB数据库(默认是”main”)到FILE文件。
.bail ON/OFF
发生错误后停止。默认为OFF。
.databases
列出附加数据库的名称和文件。
.dump ?TABLE?
以SQL文本格式转储数据库。如果指定了TABLE表,则只转储匹配LIKE模式的TABLE表。
.echo ON/OFF
开启或关闭echo命令。
.exit
退出SQLite提示符。
.explain ON/OFF
开启或关闭适合于EXPLAIN的输出模式。如果没有带参数,则为EXPLAIN on,及开启EXPLAIN。
.header(s) ON/OFF
开启或关闭头部显示。
.help
显示消息。
.import FILE TABLE
导入来自FILE文件的数据到TABLE表中。
.indices ?TABLE?
显示所有索引的名称。如果指定了TABLE表,则只显示匹配LIKE模式的TABLE表的索引。
.load FILE ?ENTRY?
加载一个扩展库。
.log FILE/off
开启或关闭日志。FILE文件可以是stderr(标准错误)/stdout(标准输出)。
.mode MODE
设置输出模式,MODE可以是下列之一:csv 逗号分隔的值;column 左对齐的列;html HTML的<table>代码;insert TABLE表的SQL插入(insert)语句;line 每行一个值;list 由 .separator字符串分隔的值;tabs 由Tab分隔的值;tcl TCL列表元素。
.nullvalue STRING
在NULL值的地方输出STRING字符串。
.output FILENAME
发送输出到FILENAME文件。
.output stdout
发送输出到屏幕。
.print STRING...
逐字地输出STRING字符串。
.prompt MAIN CONTINUE
替换标准提示符。
.quit
退出SQLite提示符。
.read FILENAME
执行FILENAME文件中的SQL。
.schema ?TABLE?
显示CREATE语句。如果指定了TABLE表,则只显示匹配LIKE模式的TABLE表。
.separator STRING
改变输出模式和.import所使用的分隔符。
.show
显示各种设置的当前值。
.stats ON/OFF
开启或关闭统计。
.tables ?PATTERN?
列出匹配LIKE模式的表的名称。
.timeout MS
尝试打开锁定的表MS微秒。
.width NUM NUM
为”column”模式设置列宽度。
.timer ON/OFF
开启或关闭CPU定时器测量。
Sqlite数据库的sqlite_master表
主表中保存数据库表的关键信息,并把它命名为sqlite_master。如要查看表概要,可如下操作:
sqlite>.schema sqlite_master
Sqlite语法规则
SQLite是遵循一套独特的称为语法的规则和准则。
SQLite是不区分大小写的,但也有一些命令是大小写敏感的,比如GLOB和glob在SQLite的语句中有不同的含义。
SQLite 注释是附加的注释,可以在 SQLite 代码中添加注释以增加其可读性,他们可以出现在任何空白处,包括在表达式内和其他 SQL 语句的中间,但它们不能嵌套。
SQL注释以两个连续的”-“字符开始,并扩展至下一个换行符或直到输入结束,以先到者为准。也可以以”/*"开始,并扩展至下一个 “*/” 字符对或直到输入结束,以先到者为准。SQLite的注释可以跨越多行。
SQLite语句以任何关键字开始,以”;”结束。
Sqlite数据类型
SQLite数据类型是一个用来指定任何对象的数据类型的属性。SQLite 中的每一列,每个变量和表达式都有相关的数据类型。您可以在创建表的同时使用这些数据类型。SQLite使用一个更普遍的动态类型系统。在SQLite 中,值的数据类型与值本身是相关的,而不是与它的容器相关。
存储类
SQLite有5个原始的数据类型,被称为存储类。存储类这个词表明了一个值在磁盘上存储的格式,其实就是类型或数据类型的同义词。如下即是存储类:
存储类
Description
NULL
值是一个NULL值。
INTEGER
值是一个带符号的整数,根据值的大小存储在1、2、3、4、6 或8字节中。
REAL
值是一个浮点值,存储为8字节的IEEE浮点数字。
TEXT
值是一个文本字符串,使用数据库编码(UTF-8、UTF-16BE或UTF-16LE)存储。
BLOB
值是一个blob数据,完全根据它的输入存储。
SQLite通过值的表示法来判断其类型,下面就是SQLite的推理方法:
SQL语句中用单引号或双引号括起来的文字被指派为TEXT。
如果文字是未用引号括起来的数据,并且没有小数点和指数,被指派为INTEGER。
如果文字是未用引号括起来的数据,并且带有小数点或指数,被指派为REAL。
用NULL说明的值被指派为NULL存储类。
如果一个值的格式为X’ABCD’,其中ABCD为16进制数字,则该值被指派为BLOB。X前缀大小写皆可。
如下就是验证结果:
SQLite单独的一个字段可能包含不同存储类的值。
如下就是验证结果:
喜欢钻牛角尖的这时候指定开始BB了,temp这一列数据类型不同,咋样比较大小?咋样排序等等?
经过查阅资料发现,具有不同存储类的值可以存储在同一个字段中。可以被排序,因为这些值可以相互比较。有完善定义的规则来做这件事。不同存储类的值可以通过它们各自类的“类值”进行排序,定义如下:
NULL存储类具有最低的类值。一个具有NULL存储类的值比所有其它值都小(包括其它具有NULL存储类的值)。在NULL值之间,没有特别的可排序值。
INTEGER或REAL存储类值高于NULL,它们的类值相等。INTEGER值和REAL值通过其数值进行比较。
TEXT存储类的值比INTEGER和REAL高。数值永远比字符串的值低。当两个TEXT值进行比较时,其值大小由“排序法”决定。
BLOB存储类具有最高的类值。具有BLOB类的值大于其它所有类的值。BLOB值之间在比较时使用C函数memcmp()。
所以,当SQLite对一个字段进行排序时,首先按存储类排序,然后再进行类内的排序 (NULL类内部各值不必排序) 。
弱类型(manifest typing)
首先有如下SQL语句:
CREATE TABLE table_yanbo( x integer, y text, z real );
INSERT INTO table_yanbo VALUES ('1', '1', '1');
这里的x、y和z这3个字段中存储的是INTEGER, TEXT和REAL类型。
再看下面例子:
CREATE TABLE table_yanbo(x, y, z);
INSERT INTO table_yanbo VALUES ('1', '1', '1');
这里的x、y和z这3个字段中存储的是TEXT、TEXT和TEXT类型。
再看下面例子:
CREATE TABLE table_yanbo(x, y, z);
INSERT INTO table_yanbo VALUES (1, 1.0, x'10');
这里的x、y和z这3个字段中存储的是INTEGER、REAL和BLOB类型。
通过上面几种写法你会发现,可以为SQLite的字段定义类型,但这不是必须的,你可以尽管违反类型定义。这是因为在任何情况下,SQLite都可以接受一个值并推断它的类型。
总之,SQLite的弱类型可表示为:
字段可以有类型。
类型可以通过值来推断。
类型亲和性介绍这两个规定如何相互关联。所谓类型亲和性就是在强类型(strict typing)和动态类型(dynamic typing)之间的平衡艺术。
类型亲和性(Type Affinity)
在SQLite中,字段没有类型或域。当给一个字段声明了类型,该字段实际上仅仅具有了该类型的亲和性。声明类型和类型亲和性是两回事。类型亲和性 预定SQLite用什么存储类在字段中存储值。在存储一个给定的值时到底SQLite会在该字段中用什么存储类决定于值的存储类和字段亲和性的结合。
任何列可以存储任何类型的数据,但列的首选存储类是它的affinity。在SQLite3数据库中,每个表的列分配为以下类型的affinity之一:
Affinity
Description
TEXT
该列使用存储类NULL、TEXT或BLOB存储所有数据。
NUMERIC
该列可以包含使用所有五个存储类的值。
INTEGER
与带有NUMERIC affinity的列相同,在CAST表达式中带有异常。
REAL
与带有NUMERIC affinity的列相似,不同的是,它会强制把整数值转换为浮点表示。
NONE
带有affinity NONE的列,不会优先使用哪个存储类,也不会尝试把数据从一个存储类强制转换为另一个存储类。
下表列出了当创建SQLite3表时可使用的各种数据类型名称,同时也显示了相应的应用Affinity:
数据类型
Affinity
INT、NTEGER、TINYINT、SMALLINT、MEDIUMINT、BIGINT、UNSIGNED BIG INT、INT2、INT8
INTEGER
CHARACTER(20)、VARCHAR(255)、VARYING CHARACTER(255)、NCHAR(55)、NATIVE CHARACTER(70)、NVARCHAR(100)、TEXT、CLOB
TEXT
BLOB、no datatype specified
NONE
REAL、DOUBLE、DOUBLE PRECISION、FLOAT
REAL
NUMERIC、DECIMAL(10,5)、BOOLEAN、DATE、DATETIME
NUMERIC
Boolean数据类型
SQLite没有单独的Boolean存储类,布尔值被存储为整数 0(false)和 1(true)。
Date与Time数据类型
SQLite没有一个单独的用于存储日期和/或时间的存储类,但SQLite 能够把日期和时间存储为TEXT、REAL或 INTEGER值。您可以以任何上述格式来存储日期和时间,并且可以使用内置的日期和时间函数来自由转换不同格式。
存储类
日期格式
TEXT
格式为”YYYY-MM-DD HH:MM:SS.SSS”的日期。
REAL
从公元前4714年11月24日格林尼治时间的正午开始算起的天数。
INTEGER
从1970-01-01 00:00:00 UTC算起的秒数。
字段类型和亲和性
首先,每个字段都具有一种亲和性。共有五种亲和性:NUMERIC、INTEGER、REAL、TEXT和NONE。一个字段的亲和性由它预声明的类型决定。所以,当你为字段声明了类型,从根本上说是为字段指定了亲和性。SQLite按下面的规则为字段指派亲和性:
默认的,一个字段默认的亲和性是NUMERIC。如果一个字段不是INTEGER、TEXT、REAL或NONE的,那它自动地被指派为NUMERIC亲和性。
如果为字段声明的类型中包含了’INT’(无论大小写),该字段被指派为INTEGER亲和性。
如果为字段声明的类型中包含了’CHAR’、’CLOB’或’TEXT’(无论大小写),该字段被指派为TEXT亲和性。如’VARCHAR’包含了’CHAR’,所以被指派为TEXT亲和性。
如果为字段声明的类型中包含了’BLOB’(无论大小写),或者没有为该字段声明类型,该字段被指派为NONE亲和性。
注意:如果没有为字段声明类型,该字段的亲和性为NONE,在这种情况下,所有的值都将以它们本身的(或从它们的表示法中推断的)存储类存储。如果 你暂时还不确定要往一个字段里放什么内容,或准备将来修改,用NONE亲和性是一个好的选择。但SQLite默认的亲和性是NUMERIC。例如,如果为 一定字段声明了类型JUJYFRUIT,该字段的亲和性不是NONE,因为SQLite不认识这种类型,会给它指派默认的NUMERIC亲和性。所以,与 其用一个不认识的类型最终得到NUMERIC亲和性,还不如不为它指定类型,从而使它得到NONE亲和性。
亲和性和存储
亲和性对值如何存储到字段有影响,规则如下:
一个NUMERIC字段可能包括所有5种存储类。一个NUMERIC字段具有数字存储类的偏好(INTEGER和REAL)。当一个TEXT值被 插入到一个NUMERIC字段,将会试图将其转化为INTEGER存储类;如果转化失败,将会试图将其转化为REAL存储类;如果还是失败,将会用 TEXT存储类来存储。
一个INTEGER字段的处理很像NUMERIC字段。一个INTEGER字段会将REAL值按REAL存储类存储。也就是说,如果这个REAL 值没有小数部分,就会被转化为INTEGER存储类。INTEGER字段将会试着将TEXT值按REAL存储;如果转化失败,将会试图将其转化为 INTEGER存储类;如果还是失败,将会用TEXT存储类来存储。
一个TEXT字段将会把所有的INTEGER或REAL值转化为TEXT。
一个NONE字段不试图做任何类型转化。所有值按它们本身的存储类存储。
没有字段试图向NULL或BLOB值转化——如无论用什么亲和性。NULL和BLOB值永远都按本来的方式存储在所有字段。
这些规则初看起来比较复杂,但总的设计目标很简单,如果你需要,SQLite会尽量模仿其它的关系型数据库。也就是说,如果你将SQLite看成是 一个传统数据库,类型亲和性将会按你的期望来存储值。如果你声明了一个INTEGER字段,并向里面放一个整数,就会按整数来存储。如果你声明了一个具有 TEXT, CHAR或VARCHAR类型的字段并向里放一个整数,整数将会转化为TEXT。可是,如果你不遵守这些规定,SQLite也会找到办法来存储你的值。
如下例子展示了亲和性是如何工作的:
存储类和类型转换
关于存储类,需要关注的另一件事是存储类有时会影响到值如何进行比较。特别是SQLite有时在进行比较之前,会将值在数字存储类(INTEGER和REAL)和TEXT之间进行转换。为进行二进制的比较,遵循如下规则:
当一个字段值与一个表达式的结果进行比较,字段的亲和性会在比较之前应用于表达式的结果。
当两个字段值进行比较,如果一个字段拥有INTEGER或NUMERIC亲和性而另一个没有,NUMERIC亲和性会应用于非NUMERIC字段的TEXT值。
当两个表达式进行比较,SQLite不做任何转换。如果两个表达式有相似的存储类,则直接按它们的值进行比较;否则按类值进行比较。
总结
这里主要介绍了Sqlite的一些基本概念和数据类型的特性。关于Sqlite其他内容接下来文章继续介绍。
本文转自 一点点征服 博客园博客,原文链接:http://www.cnblogs.com/ldq2016/p/5237932.html,如需转载请自行联系原作者
MySQL 教程下
AUTO_INCREMENT 详解MySQL 中最简单使用序列的方法就是使用 AUTO_INCREMENT 来定义序列。CREATE TABLE insect
-> (
-> id INT UNSIGNED NOT NULL AUTO_INCREMENT,
-> PRIMARY KEY (id),
...设置序列的开始值序列的开始值默认为 1,但如果你需要指定一个开始值 100,那我们可以通过在创建表的时候指定:CREATE TABLE insect
(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
KEY (id)
) engine = innodb auto_increment = 100;则下一个插入的值为 100。你也可以在表创建成功后,通过以下语句来实现:ALTER TABLE t AUTO_INCREMENT = 100;视图MySQL 5 添加了对视图的支持。视图是虚拟的表。与包含数据的表不一样,视图只包含使用时动态检索数据的查询。下面是视图的一些常见应用。❑ 重用 SQL 语句。❑ 简化复杂的 SQL 操作。在编写查询后,可以方便地重用它而不必知道它的基本查询细节。❑ 使用表的组成部分而不是整个表。❑ 保护数据。可以给用户授予表的特定部分的访问权限而不是整个表的访问权限。❑ 更改数据格式和表示。视图可返回与底层表的表示和格式不同的数据。在视图创建之后,可以用与表基本相同的方式利用它们。可以对视图执行 SELECT 操作,过滤和排序数据,将视图联结到其他视图或表,甚至能添加和更新数据(添加和更新数据存在某些限制。关于这个内容稍后还要做进一步的介绍)。重要的是知道视图仅仅是用来查看存储在别处的数据的一种设施。视图本身不包含数据,因此它们返回的数据是从其他表中检索出来的。在添加或更改这些表中的数据时,视图将返回改变过的数据。在理解什么是视图(以及管理它们的规则及约束)后,我们来看一下视图的创建。❑ 视图用 CREATE VIEW 语句来创建。❑ 使用 SHOW CREATE VIEW viewname; 来查看创建视图的语句。❑ 用 DROP 删除视图,其语法为 DROP VIEW viewname;。❑ 更新视图时,可以先用 DROP 再用 CREATE,也可以直接用 CREATE OR REPLACE VIEW。如果要更新的视图不存在,则第 2 条更新语句会创建一个视图;如果要更新的视图存在,则第 2 条更新语句会替换原有视图。❑ 查看所有视图 show table status where comment = 'view';sql 小案例:-- 创建视图
CREATE VIEW `vendors_view` AS
select concat(vend_id, ' ', vend_name) AS vend_id_name
from vendors;
-- 视图的查询和普通表的查询无差别
select * from vendors_view;更新视图迄今为止的所有视图都是和 SELECT 语句使用的。然而,视图的数据能否更新?答案视情况而定。通常,视图是可更新的(即,可以对它们使用 INSERT、UPDATE 和 DELETE)。更新一个视图将更新其基表(可以回忆一下,视图本身没有数据)。如果你对视图增加或删除行,实际上是对其基表增加或删除行。但是,并非所有视图都是可更新的。基本上可以说,如果 MySQL 不能正确地确定被更新的基数据,则不允许更新(包括插入和删除)。这实际上意味着,如果视图定义中有以下操作,则不能进行视图的更新:❑ 分组(使用 GROUP BY 和 HAVING);❑ 联结;❑ 子查询;❑ 并;❑ 聚集函数(Min()、Count()、Sum()等);❑ DISTINCT;❑ 导出(计算)列。视图为虚拟的表。它们包含的不是数据而是根据需要检索数据的查询。视图提供了一种 MySQL 的 SELECT 语句层次的封装,可用来简化数据处理以及重新格式化基础数据或保护基础数据。存储过程MySQL 5 添加了对存储过程的支持。存储过程简单来说,就是为以后的使用而保存的一条或多条 MySQL 语句的集合。可将其视为批文件,虽然它们的作用不仅限于批处理。使用存储过程有 3 个主要的好处,即简单、安全、高性能。不过,在将 SQL 代码转换为存储过程前,也必须知道它的一些缺陷。❑ 一般来说,存储过程的编写比基本SQL语句复杂,编写存储过程需要更高的技能,更丰富的经验。❑ 你可能没有创建存储过程的安全访问权限。许多数据库管理员限制存储过程的创建权限,允许用户使用存储过程,但不允许他们创建存储过程。尽管有这些缺陷,存储过程还是非常有用的,并且应该尽可能地使用。它创建一个新的存储过程 productpricing。没有返回数据,因为这段代码并未调用存储过程,这里只是为以后使用而创建它。delimiter //
CREATE procedure productpricing()
begin
select avg(prod_price) as price_average from products;
end //
delimiter ;CALL productpricing(); 执行刚创建的存储过程并显示返回的结果。因为存储过程实际上是一种函数,所以存储过程名后需要有()符号(即使不传递参数也需要)。删除存储过程drop procedure productpricing;定义参数关键字 OUT 指出相应的参数用来从存储过程传出一个值(返回给调用者)。MySQL 支持 IN(传递给存储过程)、OUT(从存储过程传出,如这里所用)和INOUT(对存储过程传入和传出)类型的参数。存储过程的代码位于BEGIN和END 语句内,如前所见,它们是一系列 SELECT 语句,用来检索值,然后保存到相应的变量(通过指定 INTO 关键字)。用 DECLARE 语句可定义局部变量。DECLARE 要求指定变量名和数据类型,它也支持可选的默认值。COMMENT 关键字 存储过程在CREATE PROCEDURE语句中可包含了一个COMMENT值。它不是必需的,但如果给出,将在 SHOW PROCEDURE STATUS 的结果中显示。检查存储过程为显示用来创建一个存储过程的CREATE语句,使用SHOW CREATE PROCEDURE 存储过程名语句。为了获得包括何时、由谁创建等详细信息的存储过程列表,使用 SHOW PROCEDURE STATUS。游标MySQL 5 添加了对游标的支持。游标(cursor)是一个存储在 MySQL 服务器上的数据库查询,它不是一条SELECT语句,而是被该语句检索出来的结果集。在存储了游标之后,应用程序可以根据需要滚动或浏览其中的数据。游标主要用于交互式应用,其中用户需要滚动屏幕上的数据,并对数据进行浏览或做出更改。只能用于存储过程 不像多数 DBMS, MySQL 游标只能用于存储过程(和函数)。使用游标使用游标涉及几个明确的步骤。❑ 在能够使用游标前,必须声明(定义)它。这个过程实际上没有检索数据,它只是定义要使用的 SELECT 语句。❑ 一旦声明后,必须打开游标以供使用。这个过程用前面定义的 SELECT 语句把数据实际检索出来。❑ 对于填有数据的游标,根据需要取出(检索)各行。❑ 在结束游标使用时,必须关闭游标。在声明游标后,可根据需要频繁地打开和关闭游标。在游标打开后,可根据需要频繁地执行取操作。触发器若需要在某个表发生更改时自动处理。这确切地说就是触发器。触发器是 MySQL 响应以下任意语句而自动执行的一条 MySQL 语句(或位于 BEGIN 和 END 语句之间的一组语句):❑ DELETE;❑ INSERT;❑ UPDATE。其他 MySQL 语句不支持触发器。创建触发器在创建触发器时,需要给出 4 条信息:❑ 唯一的触发器名;❑ 触发器关联的表;❑ 触发器应该响应的活动(DELETE、INSERT 或 UPDATE);❑ 触发器何时执行(处理之前或之后)。CREATE TRIGGER newproduct
after insert
on products
for each row select 'product added' INTO @arg;CREATE TRIGGER 用来创建名为 newproduct 的新触发器。触发器可在一个操作发生之前或之后执行,这里给出了 AFTER INSERT,所以此触发器将在 INSERT 语句成功执行后执行。这个触发器还指定FOR EACH ROW,因此代码对每个插入行执行。触发器按每个表每个事件每次地定义,每个表每个事件每次只允许一个触发器。因此,每个表最多支持 6 个触发器(每条 INSERT、UPDATE 和 DELETE的之前和之后)。单一触发器不能与多个事件或多个表关联,所以,如果你需要一个对 INSERT 和 UPDATE 操作执行的触发器,则应该定义两个触发器。触发器失败 如果 BEFORE 触发器失败,则 MySQL 将不执行请求的操作。此外,如果 BEFORE 触发器或语句本身失败,MySQL 将不执行 AFTER 触发器(如果有的话)。为了删除一个触发器,可使用 DROP TRIGGER 语句。关于触发器的进一步介绍❑ 与其他 DBMS 相比,MySQL 5 中支持的触发器相当初级。未来的 MySQL 版本中有一些改进和增强触发器支持的计划。❑ 创建触发器可能需要特殊的安全访问权限,但是,触发器的执行是自动的。如果 INSERT、UPDATE 或 DELETE 语句能够执行,则相关的触发器也能执行。❑ 应该用触发器来保证数据的一致性(大小写、格式等)。在触发器中执行这种类型的处理的优点是它总是进行这种处理,而且是透明地进行,与客户机应用无关。❑ 触发器的一种非常有意义的使用是创建审计跟踪。使用触发器,把更改(如果需要,甚至还有之前和之后的状态)记录到另一个表非常容易。❑ 遗憾的是,MySQL 触发器中不支持 CALL 语句。这表示不能从触发器内调用存储过程。所需的存储过程代码需要复制到触发器内。什么是事务事务的四大特性 acid原子性 atomicity 不可分割一致性 consistency 数据库状态与其他业务保持一致隔离性 isolation: 并发操作中,不同事务互不干扰持续性 durability: 一旦事务提交成功, 事务中所有的数据操作都必须被持久化到数据库中。事务处理(transaction processing)可以用来维护数据库的完整性,它保证成批的 MySQL 操作要么完全执行,要么完全不执行。MySQL 事务事务的隔离级别事务的并发问题:脏读 最可怕: 读取到另一个未提交的数据不可重复读: 对同一记录的两次读取不一致, 因为另一事务对该记录做了修改幻读(虚读): 对同一记录的两次查询不一致, 因为另一事务插入了一条记录四大隔离级别:读未提交数据:读已提交数据: 防止了脏读, 没有处理不可重复读 和 幻读 (oracle 采用)可重复读: 防止了脏读和不可重复读, 不处理不了幻读 (mysql 采用)串行化: 性能最差MYSQL 事务处理使用 start transaction / commit / rollback 关键字。BEGIN 开始一个事务ROLLBACK 事务回滚COMMIT 事务确认。在事务处理块中,提交不会隐含地进行。为进行明确的提交,使用 COMMIT 语句。start transaction;
delete from orderitems;
select * from orderitems;
rollback;
select * from orderitems;使用保留点为了支持回退部分事务处理,必须能在事务处理块中合适的位置放置占位符。这样,如果需要回退,可以回退到某个占位符。创建保留点:savepoint delete1;回滚到指定保留点:rollback to delete1;保留点越多越好 可以在 MySQL 代码中设置任意多的保留点,越多越好。为什么呢?因为保留点越多,你就越能按自己的意愿灵活地进行回退。释放保留点 保留点在事务处理完成(执行一条 ROLLBACK 或 COMMIT)后自动释放。自 MySQL 5 以来,也可以用 RELEASE SAVEPOINT 明确地释放保留点。更改默认的提交行为默认的 MySQL 行为是自动提交所有更改。换句话说,任何时候你执行一条 MySQL 语句,该语句实际上都是针对表执行的,而且所做的更改立即生效。为指示MySQL不自动提交更改,需要使用以下语句:SET AUTOCOMMIT=0 禁止自动提交SET AUTOCOMMIT=1 开启自动提交标志为连接专用 autocommit 标志是针对每个连接而不是服务器的。jdbc 事务connection 的方法setAutoCommit(boolean) 设置是否为自动提交事务, 默认为 true 表示自动提交, 也就是每条执行的 sql 语句都是一个单独的事务, 如果设置 false, 就相当于开启了事务; conn.setAutoCommit(false); 表示开启事务try {
conn.setautocommit(false)
..
conn.commit
} catch() {
conn.rollback
}MySQL 临时表MySQL 临时表在我们需要保存一些临时数据时是非常有用的。临时表只在当前连接可见,当关闭连接时,MySQL 会自动删除表并释放所有空间。临时表在 MySQL 3.23 版本中添加。如果你使用了其他 MySQL 客户端程序连接 MySQL 数据库服务器来创建临时表,那么只有在关闭客户端程序时才会销毁临时表,当然你也可以手动销毁。CREATE TEMPORARY TABLE SalesSummary (
product_name VARCHAR(50) NOT NULL
, total_sales DECIMAL(12,2) NOT NULL DEFAULT 0.00
, avg_unit_price DECIMAL(7,2) NOT NULL DEFAULT 0.00
, total_units_sold INT UNSIGNED NOT NULL DEFAULT 0
);当你使用 SHOW TABLES 命令显示数据表列表时,你将无法看到临时表。默认情况下,当你断开与数据库的连接后,临时表就会自动被销毁。当然你也可以在当前 MySQL 会话使用 DROP TABLE 命令来手动删除临时表。MySQL 复制表使用 SHOW CREATE TABLE 命令获取创建数据表(CREATE TABLE) 语句,该语句包含了原数据表的结构,索引等。并执行 SQL 语句,通过以上命令 将完全的复制数据表结构。SHOW CREATE TABLE runoob_tbl \G2 仅创建并复制表结构,不包含数据,不包含完整性约束CREATE TABLE 新表 SELECT * FROM 旧表 WHERE 1=2仅创建并复制表结构,包含数据,不包含完整性约束CREATE TABLE 新表 [AS] SELECT * FROM 旧表3 完整复制表的方法【推荐】:CREATE TABLE 新表 LIKE 旧表如果你想复制表的内容,你就可以使用 INSERT INTO ... SELECT 语句来实现。完整复制结构 + 插入数据【推荐】:CREATE TABLE targetTable LIKE sourceTable;
INSERT INTO targetTable SELECT * FROM sourceTable;获取服务器元数据以下命令语句可以在 MySQL 的命令提示符使用,也可以在脚本中 使用,如 PHP 脚本。命令 描述SELECT VERSION( ) 服务器版本信息SELECT DATABASE( ) 当前数据库名 (或者返回空)SELECT USER( ) 当前用户名SHOW STATUS 服务器状态SHOW VARIABLES 服务器配置变量数据库维护❑ ANALYZE TABLE,用来检查表键是否正确。ANALYZE TABLE返回如下所示的状态信息。❑ CHECK TABLE 用来针对许多问题对表进行检查。在 MyISAM 表上还对索引进行检查。CHECK TABLE支持一系列的用于 MyISAM 表的方式。CHANGED 检查自最后一次检查以来改动过的表。EXTENDED 执行最彻底的检查,FAST 只检查未正常关闭的表,MEDIUM 检查所有被删除的链接并进行键检验,QUICK 只进行快速扫描。查看日志文件MySQL维护管理员依赖的一系列日志文件。主要的日志文件有以下几种。❑ 错误日志。它包含启动和关闭问题以及任意关键错误的细节。此日志通常名为 hostname.err,位于 data 目录中。此日志名可用 --log-error 命令行选项更改。❑ 查询日志。它记录所有 MySQL 活动,在诊断问题时非常有用。此日志文件可能会很快地变得非常大,因此不应该长期使用它。此日志通常名为hostname.log,位于 data 目录中。此名字可以用--log命令行选项更改。❑ 二进制日志。它记录更新过数据(或者可能更新过数据)的所有语句。此日志通常名为 hostname-bin,位于 data 目录内。此名字可以用 --log-bin 命令行选项更改。注意,这个日志文件是 MySQL 5 中添加的,以前的 MySQL 版本中使用的是更新日志。❑ 缓慢查询日志。顾名思义,此日志记录执行缓慢的任何查询。这个日志在确定数据库何处需要优化很有用。此日志通常名为 hostname-slow.log,位于data目录中。此名字可以用 --log-slow-queries 命令行选项更改。在使用日志时,可用 FLUSH LOGS 语句来刷新和重新开始所有日志文件。MySQL 事件(定时任务)-- 开启事件调度器
SET GLOBAL event_scheduler = ON;
-- 关闭事件调度器
SET GLOBAL event_scheduler = OFF;
-- 查看事件调度器状态
SHOW VARIABLES LIKE 'event_scheduler';注意:如果想要始终开启事件,那么在使用 SET GLOBAL 开启事件后,还需要在 my.ini(Windows系统)/my.cnf(Linux系统)中添加 event_scheduler=on。因为如果没有添加,MySQL 重启事件后又会回到原来的状态。MySQL 导出和导入数据以下实例中我们将数据表 runoob_tbl 数据导出到 /tmp/runoob.txt 文件中:SELECT * FROM runoob_tbl
INTO OUTFILE '/tmp/runoob.txt';你可以通过命令选项来设置数据输出的指定格式,以下实例为导出 CSV 格式:SELECT * FROM runoob_tbl INTO OUTFILE '/tmp/runoob.txt'
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\n';导出表作为原始数据mysqldump 是 mysql 用于转存储数据库的实用程序。它主要产生一个 SQL 脚本,其中包含从头重新创建数据库所必需的命令 CREATE TABLE INSERT 等。--tab 选项来指定导出文件指定的目录mysqldump -u root -p --no-create-info \
--tab=/tmp RUNOOB runoob_tbl
password ******导出 SQL 格式的数据导出单张表数据mysqldump -u 用户名 -p密码 数据库名 表名 > 生成脚本的路径如果你需要导出整个数据库的数据,可以使用以下命令:mysqldump -u 用户名 -p密码 数据库名 > 生成脚本的路径如果需要备份所有数据库,可以使用以下命令:$ mysqldump -u root -p --all-databases > database_dump.txt
password ******导出 SQL 格式的数据到指定文件,如下所示:$ mysqldump -u root -p RUNOOB runoob_tbl > dump.txt
password ******MySQL 导入数据1、mysql 命令导入如果你需要将备份的数据库导入到 MySQL 服务器中,可以使用以下命令,使用以下命令你需要确认数据库已经创建:在未登录情况下mysql -u 用户名 -p密码 数据库名 < 生成脚本的路径2、SOURCE 命令导入SOURCE 命令导入数据库需要先登录到数库终端:SOURCE c:/mydb.sql生成的脚本文件不包含 CREATE DATABASE 语句, 需要手动创建即可。3、使用 LOAD DATA 导入数据MySQL 中提供了LOAD DATA INFILE 语句来插入数据。 以下实例中将从当前目录中读取文件 dump.txt ,将该文件中的数据插入到当前数据库的 mytbl 表中。4、使用 mysqlimport 导入数据mysqlimport 客户端提供了 LOAD DATA INFILEQL 语句的一个命令行接口。mysqlimport 的大多数选项直接对应 LOAD DATA INFILE 子句。数据库性能❑ MySQL是一个多用户多线程的 DBMS,换言之,它经常同时执行多个任务。如果这些任务中的某一个执行缓慢,则所有请求都会执行缓慢。如果你遇到显著的性能不良,可使用 SHOW PROCESSLIST 显示所有活动进程(以及它们的线程ID和执行时间)。你还可以用 KILL 命令终结某个特定的进程(使用这个命令需要作为管理员登录)。❑ 总是有不止一种方法编写同一条 SELECT 语句。应该试验联结、并、子查询等,找出最佳的方法。❑ 使用 EXPLAIN 语句让 MySQL 解释它将如何执行一条 SELECT 语句。❑ 一般来说,存储过程执行得比一条一条地执行其中的各条 MySQL 语句快。❑ 应该总是使用正确的数据类型。❑ 决不要检索比需求还要多的数据。换言之,不要用 SELECT *(除非你真正需要每个列)。❑ 有的操作(包括 INSERT)支持一个可选的 DELAYED 关键字,如果使用它,将把控制立即返回给调用程序,并且一旦有可能就实际执行该操作。❑ 在导入数据时,应该关闭自动提交。你可能还想删除索引(包括FULLTEXT索引),然后在导入完成后再重建它们。❑ 必须索引数据库表以改善数据检索的性能。确定索引什么不是一件微不足道的任务,需要分析使用的 SELECT 语句以找出重复的WHERE和ORDER BY子句。如果一个简单的 WHERE 子句返回结果所花的时间太长,则可以断定其中使用的列(或几个列)就是需要索引的对象。❑ 你的SELECT语句中有一系列复杂的 OR 条件吗?通过使用多条 SELECT 语句和连接它们的 UNION 语句,你能看到极大的性能改进。❑ 索引改善数据检索的性能,但损害数据插入、删除和更新的性能。如果你有一些表,它们收集数据且不经常被搜索,则在有必要之前不要索引它们。(索引可根据需要添加和删除。)❑ LIKE 很慢。一般来说,最好是使用 FULLTEXT 而不是 LIKE。❑ 数据库是不断变化的实体。一组优化良好的表一会儿后可能就面目全非了。由于表的使用和内容的更改,理想的优化和配置也会改变。❑ 最重要的规则就是,每条规则在某些条件下都会被打破。浏览文档 位于http://dev.mysql.com/doc/ 的 MySQL 文档有许多提示和技巧(甚至有用户提供的评论和反馈)。一定要查看这些非常有价值的资料。相关专题MySQL 简介 - 简书 https://www.jianshu.com/p/b72814256932MySQL 教程上 - 简书 https://www.jianshu.com/p/8af392d711f4参考MySQL 简介 | 菜鸟教程https://www.runoob.com/mysql/mysql-tutorial.htmlMySQL事件(定时任务)_pan_junbiao的博客-CSDN博客_mysql 定时任务 https://blog.csdn.net/pan_junbiao/article/details/86489237
冬季实战营第三期:MySQL数据库进阶实战
一、MySQL数据库快速部署实践1.MySQL安装与配置(1)执行如下命令,更新YUM源。rpm -Uvh http://dev.mysql.com/get/mysql57-community-release-el7-9.noarch.rpm(2)执行如下命令,安装MySQL。yum -y install mysql-community-server(3)执行如下命令,查看MySQL版本号。mysql -V返回结果如下,表示您已成功安装MySQL。(4)执行如下命令,启动MySQL服务。systemctl start mysqld(5)执行如下命令,设置MySQL服务开机自启动。systemctl enable mysqld(6)配置MySQL的root用户密码。 a.执行如下命令,查看/var/log/mysqld.log文件,获取root用户的初始密码。grep 'temporary password' /var/log/mysqld.log返回结果如下所示,您可以查看到root用户的初始密码。 b.执行以下命令,使用root用户登录数据库。mysql -uroot -p返回结果如下所示,输入root用户的初始密码。 c.执行以下命令,修改MySQL的root用户的初始密码。set global validate_password_policy=0; #修改密码安全策略为低(只校验密码长度,至少8位)。ALTER USER 'root'@'localhost' IDENTIFIED BY '12345678'; d.执行以下命令,授予root用户远程管理权限。GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '12345678'; e.输入exit退出数据库。(7)执行以下命令,使用root用户登录数据库。mysql -uroot -p12345678(8)执行如下命令,创建test数据库。create database test;(9)执行如下命令,查看当前数据库列表。此时,可以看到三个数据库:information_schema ,mysql,performance_schema,sys,test 。show databases;注意:进入 mysql 之后,每条命令结尾都要有分号。(10)执行命令 use mysql;,连接 mysql 数据库。然后执行命令 show tables; ,查看 mysql 数据库中的数据表。使用命令 exit ,退出 MySQL 界面。use mysql;show tables; exit(11)返回 Linux 界面,执行如下命令,将名为 test 的数据库备份到当前目录的 test.sql。界面显示 Enter password,输入 MySQL 数据库的登录密码 12345678 。根据备份的数据库大小,等待时间长短不同。完成后,使用命令 ll 查看备份文件,界面查看到备份文件 test.sql ,完成备份。mysqldump -uroot -p test >test.sql(12)返回 Linux 界面,执行如下命令,将 test.sql 导入数据库。界面显示 Enter password ,输入 MySQL 数据库的登录密码 12345678 。说明:其中参数 -D 是指定数据库为test。mysql -uroot -p -Dtest(13)还有一种导入方法:输入命令:mysql -uroot -p12345678 ,进入 MySQL 数据库。输入 use test; ,连接数据库 test ,输入 source /root/test.sql; ,将 test.sql 导入数据库 test ,全部出现 Query OK ,则表示数据库导入成功。mysql -uroot -p12345678use test;source /root/test.sql;2.常用SQL本小节将主要介绍基本的 SQL 语句,数据的增删查改等。\1. 若当前不是在 Mysql 数据库的命令界面,请执行命令:mysql -uroot -p12345678 ,登录到 Mysql 数据库命令行界面。否则,请忽略此操作。然后,在Mysql中,执行命令 use test; ,连接 test 数据库。界面提示 Database changed ,表示现在使用的数据库为 test 数据库。use test;\2. 执行命令 create table test1 (id int,name char(20)); ,创建一张表,表名为 test1 。test1 表有两列:id 和 name。其中,id 的数据类型为 int,name 的数据类型为 char,且字符长度为 20。说明:mysql 命令执行完成,页面会提示 Query OK 。create table test1 (id int,name char(20));语法:CREATE TABLE 表名称 (列名称1 数据类型,列名称2 数据类型,列名称3 数据类型,....);\3. 执行命令 insert into test1 values(1,"zhangsan"); ,插入一条数据:此条数据的第一列 id 的值为1,第二列 name 的值为zhangsan。insert into test1 values(1,"zhangsan");语法:INSERT INTO 表名称 VALUES (值1, 值2,....);\4. 执行命令 select * from test1; ,查看 test1 表中的全部数据信息。此时,用户可以查看到新插入的一行数据: id 的值为 1 , name 的值为 zhangsan 。select * from test1;语法1:SELECT * FROM 表名称; //查询表中的所有列的数据信息 语法2:SELECT 列名称 FROM 表名称; //查询表中的指定列的数据信息\5. 执行命令 update test1 set name = "lisi" where id =1; ,更新 test1 表中的数据,也就是,将所有 id 为 1 的 name 值均修改为 lisi 。update test1 set name = "lisi" where id =1;select * from test1;语法:UPDATE 表名称 SET 列名 = 值 WHERE 表名称 = 值;\6. 执行命令 delete from test1 where id =1; ,删除 test1 表中,所有 id 值为 1 的数据。delete from test1 where id =1;select * from test1;语法:DELETE FROM 表名称 WHERE 列名称 = 值;\7. 执行命令 drop table test1; 删除名为 test1 的数据表。drop table test1;show tables;语法:DROP TABLE 表名称\8. 执行命令 drop database test; ,删除名为 test 的数据库。drop database test;show databases;语法:DROP DATABASE 数据库名称二、在云端创建MySQL数据库1.现有数据库查看本小节主要内容:登录本地部署的MySQL数据库实验环境,并查看本地MySQL源数据库中的信息。\1. 点击右侧 ,切换至Web Terminal,远程登录到 云产品资源 中的 MySQL源数据库 ECS实例。\2. 运行如下命令,登录到ECS实例的MySQL数据库:mysql -u root -p123456\3. 通过如下操作,查看源数据库bakery、其中的表customer和product,以及表中的数据。1)执行如下命令,查看数据库信息。show databases;2)执行如下命令,切换数据库为bakery:use bakery;3)执行如下命令,查看表中数据:show columns from customer;show columns from product; select * from customer;select * from product;2.上云迁移\1. 首先,通过如下操作步骤,登录到阿里云RDS管理控制台:1)点击右侧 图标,切换到远程桌面操作界面。2)双击打开虚拟桌面 FireFox ESR浏览器,在RAM用户登录框中点击 下一步,复制 云产品资源 列表中 子用户密码 粘贴(lx shell粘贴快捷键ctrl+shift+v,其他地方粘贴是ctrl+v)到浏览器 RAM用户登录界面,即可登录当前子账号。3)顶部导航栏处点击【产品与服务】,在主页面的【数据库】条目下找到【云数据库RDS版】,点击进入阿里云RDS管理控制台。\2. 点击左侧的【实例列表】,在实例列表页面,选择云产品资源提供的 地域,然后点击目标实例右侧的【管理】进入RDS实例的管理控制台。\3. 通过如下步骤,进入数据库账号创建页面:1)在RDS实例的管理页面,点击左侧栏的【账号管理】,进入数据库账号管理页面。2)在【用户账号】页面,点击左侧的【创建账号】。\2. 填写如下信息,完成数据库账号创建:1)数据库账号:请根据 输入框 下端的 命名规则 ,输入 数据库账号名称,例如:lab_user 。2)账号类型:选择【普通账号】。3)密码 :请根据 输入框 下端的 密码规则 ,输入 密码,例如:Passw0rd 。4)确认密码:再次输入创建的密码。5)完成如上信息后,点击【确定】。6)返回 账号管理 的 用户账号 ,查看到新建账号 lab_user 的 状态 为 已激活 。\3. 通过如下操作步骤,进入数据库创建页面:1)点击左侧栏的【数据库管理】,进入数据库管理页面。2)在右侧的【数据库管理】页面,点击左上角的【创建数据库】,进入创建页面。\4. 在弹出的创建页面中,添加如下信息:1)数据库(DB)名称:请根据 输入框 下端的 命名规则 ,输入 数据库名称,例如:lab_db 。2)支持字符集:默认设为 utf8 。3)授权帐号:选择新建数据库账号,例如lab_user。4)完成如上配置信息后,点击底部的【创建】,完成数据库的创建。5)在【数据库管理】页面中,等待1分钟左右,可以查看到数据库 lab_db 的 数据库状态 为 运行中 ,且 绑定账号 为 新建数据库账号 lab_user 。\5. 进入数据传输服务DTS。1)复制下方地址,在FireFox浏览器打开新页签,粘贴并访问数据传输控制台。https://dts.console.aliyun.com/2)在左侧控制台,单击数据迁移。3)在数据迁移页面,迁移任务列表选择华东1(杭州),单击配置迁移任务。\6. 配置迁移任务,按照如下步骤,输入 源库信息 的配置信息:实例类型:选择 有公网IP的自建数据库 。实例地区: 选择 云产品资源 中分配的 地域 ,例如:华东1 。数据库类型:选择 MySQL 。主机名或IP地址:输入 云产品资源 中分配的 MySQL源数据库 ECS实例的 弹性IP。端口:使用默认端口号 3306数据库账号:输入ECS上自建MySQL的 数据库账号 ,root;数据库密码:自建MySQL的访问密码,123456完成如上配置后,点击右侧的 【测试连接】 ,测试自建MySQL数据库的连通性,若显示 测试通过 ,证明连接成功。否则,请检查如上配置信息是否正确。\7. 按照如下步骤,完成 目标库信息 的配置信息:1)实例类型:选择 RDS实例2)实例地区:选择 实验资源 中分配的 地域 ,例如:华东1 3)RDS实例ID :选择 实验资源 中提供的 目标数据库 的 实例ID 4)数据库账号:输入RDS实例中新建的 数据库账号 lab_user ;数据库密码:新建数据库的密码 Passw0rd 。5)完成如上配置后,点击右侧的 测试链接 ,测试RDS账号的连通性,若显示 测试通过 ,证明连接成功。否则,请检查如上配置信息是否正确。6)完成如上的配置后,点击右下角的【 授权白名单并进入下一步 】。\8. 通过如下步骤,配置迁移任务的 迁移类型及列表:1)点击左侧 迁移对象 中的本地MySQL数据库中的bakery 2)点击 >3)数据库 bakery 移动到 已选择对象 的列表中。4)完成如上配置后,点击右下角的【 预检查并启动】 。\9. 等待30秒钟左右,完成预检查,检查结果为 预检查通过100% ,点击 【下一步】 。说明:若预检查未通过,请根据错误提示和如上的操作步骤,核对迁移任务的配置是否正确。\10. 此时,页面迁移任务的状态为 迁移中 ,等待3-4分钟,状态变为 已完成 。3.数据库迁移结果确认\1. 顶部导航栏处点击【产品与服务】,在主页面的【数据库】条目下找到【云数据库RDS版】,点击进入阿里云RDS管理控制台。\2. 在 实例列表 界面中,点击右上角的【登录数据库】,进入数据库管理登录界面。\3. 在弹出的页面中,输入如下的信息:网络地址:端口:请输入 云产品资源 中,RDS 目标数据库 提供的 链接地址 以及端口号 3306。 例如:提供的RDS 链接地址为 rm-uf6l90d950j1o7890.mysql.rds.aliyuncs.com,则输入信息为:rm-uf6l90d950j1o7890.mysql.rds.aliyuncs.com:3306用户名:输入新建数据库账号 lab_user密码:输入新建数据库密码 Passw0rd 完成后,点击【登录】。(忽略RAM授权)\4. 如下图,进入数据库管理页面,证明数据库迁移成功。三、基础学习之MySQL数据库基础1.数据库启动与连接本小节主要介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL。 \1. 通过如下操作步骤,登录阿里云管理控制台,并进入云数据库RDS实例的管理页面。1) 双击打开桌面 FireFox ESR浏览器,在RAM用户登录框中点击 下一步,复制 云产品资源 列表中 子用户密码 粘贴(lx shell粘贴快捷键ctrl+shift+v,其他地方粘贴是ctrl+v)到浏览器 RAM用户登录界面,即可登录当前子账号。2)在阿里云管理控制台,点击顶部【产品与服务】 ,然后点击 【数据库】条目下的 【云数据库RDS版】 ,进入RDS数据库的管理页面。3)在【实例列表】页面中,首先,选择 云产品资源 中提供的 地域,然后单击已创建的RDS实例ID,进入实例的管理页面。\2. 在实例详情页,单击左侧导航栏的【账号管理】,然后单击【创建账号】。\3. 参考说明配置账号信息,然后单击【确定】。数据库账号:输入数据库账号名称,例如:test_user 。账号类型:此处选择普通账号。密码:设置账号密码,例如:Password1213。确认密码:再次输入密码。\4. 在实例详情页,单击左侧导航栏的【数据库管理】,然后单击【创建数据库】。\5. 参考说明配置数据库信息,然后单击【创建】。数据库(DB)名称:输入数据库名称,例如:user_db 。支持字符集:默认设为utf8。授权账号:选择步骤三新建的数据库账号。账号类型:默认设置为读写。备注说明:非必填。用于备注该数据库的相关信息,便于后续数据库管理,最多支持256个字符。\6. 在数据库管理页面,单击页面右上方的【登录数据库】。\7. 在输入框中,输入刚才创建的用户名和密码,单击【登录】。登录成功,进入数据管理服务系统DMS。2.数据库表操作本小节主要介绍对数据库表的基本操作,其中包括新增、删除、更新和重命名等。\1. 在DMS控制台,左上角选择创建好的数据库user_db,然后单击【SQL操作】 > 【SQL窗口】。\2. 使用CREATE TABLE语句创建一个数据表。将以下语句复制到SQL窗口,然后单击【执行】。CREATE TABLE `USER` ( `user_id` int(128) NOT NULL AUTO_INCREMENT, `name` varchar(64) NOT NULL, `age` int(11) DEFAULT NULL, PRIMARY KEY (`user_id`)) ENGINE=InnoDBDEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci;语句解析:CREATE TABLE USER:新表的名字,表名称在关键字CREATE TABLE后给出。name varchar(64) NOT NULL,:列名name,类型varchar,长度限制64,此列不能为空。PRIMARY KEY (user_id):设置USER表主键为user_id。user_id int(128) NOT NULL AUTO_INCREMENT,:AUTO_INCREMENT通常用于主键,表示主键自增,数值会自动+1。执行成功后,单击【刷新】查看创建的数据表。\3. 使用ALTER TABLE语句更新数据表。将以下语句复制到SQL窗口,然后单击执行。# 在年龄age列后面,为USER表新增一列性别sex,0代表女,1代表男。ALTER TABLE user ADD COLUMN sex tinyint(1) NOT NULL COMMENT '性别,女:0,男:1' AFTER `age`;\4. 使用RENAME TABLE语句对数据表重命名。将以下语句复制到SQL窗口,然后单击执行。# 修改表名user为student。RENAME TABLE USER TO student;语句格式:RENAME TABLE table_name_a TO table_name_b;\5. 使用DROP TABLE语句删除数据表。将以下语句复制到SQL窗口,然后单击执行。说明:此操作不能撤销,请谨慎操作。# 删除学生表。DROP TABLE student;语句格式:DROP TABLE table_name;3.数据操作本小节主要为大家介绍MySQL中常用的数据查询、删除、更新、插入等基本操作。\1. 在DMS控制台,单击【SQL操作】 > 【SQL窗口】。\2. 使用CREATE TABLE语句创建一个数据表。将以下语句复制到SQL窗口,然后单击【执行】。CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID', `name` varchar(32) DEFAULT NULL COMMENT '姓名', `age` int(11) DEFAULT NULL COMMENT '年龄', `address` varchar(32) DEFAULT NULL COMMENT '住址', `sex` tinyint(1) DEFAULT NULL COMMENT '性别,女:0,男:1', PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8执行成功后,单击【刷新】查看创建的数据表。\3. 插入数据插入语句说明:table_name(col_name,...)中的字段名列表必须和values(expr,...)字段值列表一致。如果数据是字符型,必须使用单引号或者双引号。被AUTO_INCREMENT标记的自动递增的主键,在插入数据时,可以不设置值。将以下SQL语句复制到SQL窗口,然后单击【执行】。INSERT INTO USER (name, age, address, sex)VALUES ('端木巧香', 21, '江西', 0), ('令狐静珊', 22, '湖北', 0), ('钟离梦华', 23, '湖南', 0), ('西门怜云', 24, '河南', 1), ('拓跋晨潍', 25, '河北', 1), ('公羊曼安', 26, '山东', 1), ('呼延飞鹏', 27, '山西', 1) ;\4. 查询数据查询语句格式:SELECT col_name,... FROM table_name WHERE where_condition GROUP BY col_name,...HAVING where_condition ORDER BY col_name,... LIMIT offset,row_count将以下SQL语句复制到SQL窗口,然后单击【执行】。SELECT id,name,age,address,sex FROM user;\5. 更新数据更新语句格式:UPDATE table_name SET col_name=expr,... WHERE where_condition将以下SQL语句复制到SQL窗口,然后单击【执行】。UPDATE `user` SET `age` = 28,`address` = '四川' WHERE `name` = '公羊曼安' ;\6. 删除数据删除语句格式:DELETE FROM table_name WHERE where_condition将以下SQL语句复制到SQL窗口,然后单击【执行】。DELETE FROM `user` WHERE `name` = '公羊曼安' ;4.函数操作本小节主要为大家介绍MySQL中常用的内置函数。\1. 在DMS控制台,单击【SQL操作】 > 【SQL窗口】。\2. 使用CREATE TABLE语句创建一个数据表。将以下语句复制到SQL窗口,然后单击【执行】。CREATE TABLE student_score(sid INT PRIMARY KEY NOT NULL, sname VARCHAR(30), sage INT, ssex VARCHAR(8), score INT(11));insert into `student_score`(`sid`, `sname`, `sage`, `ssex`,`score`)values (1001, '小花', 17,'0', 75), (1002, '小红', 18,'0', 80), (1003, '王五', 18,'1', 90), (1004, '李四', 17,'1', 68), (1005, '张三', 19,'1', 73), (1006, '小黑', 19,'1', 100), (1007, '小马', 20,'0', 77), (1008, '王舞', 17,'1', 82), (1009, '小白', 19,'0', 88), (1010, '温瞳', 18,'0', 53);\3. AVG()函数将以下语句复制到SQL窗口,然后单击【执行】。SELECT avg(score) FROM student_score;执行结果如下:\4. COUNT()函数将以下语句复制到SQL窗口,然后单击【执行】。SELECT COUNT(*) FROM student_score;执行结果如下:\5. MAX()函数将以下语句复制到SQL窗口,然后单击【执行】。SELECT MAX(score) FROM student_score;执行结果如下:\6. MIN()函数将以下语句复制到SQL窗口,然后单击【执行】。SELECT MIN(score) FROM student_score;执行结果如下:\7. SUM()函数将以下语句复制到SQL窗口,然后单击【执行】。SELECT SUM(score) FROM student_score;执行结果如下:5.组合查询本小节主要介绍如何使用GROUP BY、HAVING和ORDER BY等进行分组查询。\1. 在DMS控制台,单击【SQL操作】 > 【SQL窗口】。\2. 使用CREATE TABLE语句创建数据表。将以下语句复制到SQL窗口,然后单击【执行】。CREATE TABLE `student` ( `sid` int(11) NOT NULL, `sname` varchar(30) DEFAULT NULL, `sage` int(11) DEFAULT NULL, `ssex` varchar(8) DEFAULT NULL, PRIMARY KEY (`sid`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;insert into `student`(`sid`,`sname`,`sage`,`ssex`) values(1005,'小花',19,'0'),(1004,'小红',18,'0'),(1003,'王五',18,'1'),(1002,'李四',17,'1'),(1001,'张三',18,'1');CREATE TABLE `sc` ( `sid` int(11) NOT NULL, `cid` int(11) NOT NULL, `score` int(11) DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8;insert into `sc`(`sid`,`cid`,`score`) values(1001,101,75),(1001,102,85),(1002,101,65),(1002,102,95),(1003,101,65),(1003,102,95),(1004,101,80),(1004,102,80),(1005,101,75),(1005,102,85);CREATE TABLE `course` ( `cid` int(11) NOT NULL, `cname` varchar(30) DEFAULT NULL, `tid` int(11) DEFAULT NULL, PRIMARY KEY (`cid`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;insert into `course`(`cid`,`cname`,`tid`) values(102,'语文',2),(101,'数学',1);CREATE TABLE `teacher` ( `tid` int(11) NOT NULL, `tname` varchar(30) DEFAULT NULL, PRIMARY KEY (`tid`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;insert into `teacher`(`tid`,`tname`) values(2,'刘老师'),(1,'王老师');执行成功后,单击【刷新】查看创建的数据表。\3. 查询所有同学的学号和成绩。 将以下SQL语句复制到SQL窗口,然后单击【执行】。# 使用WHERE s. sid = sc.sid 来消除笛卡尔积。SELECT s.sid ,s.sname ,c.score FROM student AS s ,sc AS c WHERE s.sid = c.sid ;执行结果如下:\4. 查询语文成绩在80以上同学。 将以下SQL语句复制到SQL窗口,然后单击【执行】。SELECT a.score, b.cname, s.sname FROM sc as a, course AS b, student AS s WHERE a.cid= b.cid AND s.sid= a.sid AND a.cid= 102 AND a.score> 80执行结果如下:\5. 查询语文成绩比数学成绩高的同学。 将以下SQL语句复制到SQL窗口,然后单击【执行】。SELECT a.sid, a.score, s.sname FROM(SELECT sid, score FROM sc WHERE cid= "102") a, (SELECT sid, score FROM sc WHERE cid= "101") b, student as s WHERE a.score > b.score AND a.sid= b.sid AND s.sid= a.sid执行结果如下:四、最佳应用实践之使用RDS MySQL和ECS搭建个人博客1.创建数据库账号和密码见上面详解2.部署环境在ECS服务器上,执行以下命令,安装Apache服务及其扩展包。yum -y install httpd httpd-manual mod_ssl mod_perl mod_auth_mysql返回类似如下图结果则表示安装成功:\3. 执行以下命令,启动Apache服务。systemctl start httpd.service\4. 打开浏览器输入ECS服务器的公网IP,如果显示如下图的测试页面表示Apache服务安装成功。\5. WordPress是使用PHP语言开发的博客平台。参考以下操作安装PHP。 a. 执行以下命令,安装PHP。yum -y install php php-mysql gd php-gd gd-devel php-xml php-common php-mbstring php-ldap php-pear php-xmlrpc php-imap b. 执行以下命令,创建PHP测试页面。echo "" > /var/www/html/phpinfo.php c. 执行以下命令,重启Apache服务。systemctl restart httpd d. 打开浏览器,访问http:///phpinfo.php,显示如下页面表示PHP安装成功。3.安装和配置WordPress完成上述环境搭建后,参考本节安装WordPress以及连接到RDS数据库。\1. 执行以下命令,安装WordPress。yum -y install wordpress显示如下信息表示安装成功。\2. 修改WordPress配置文件。 a. 执行以下命令,修改wp-config.php指向路径为绝对路径。# 进入/usr/share/wordpress目录。cd /usr/share/wordpress# 修改路径。ln -snf /etc/wordpress/wp-config.php wp-config.php# 查看修改后的目录结构。ll b. 执行以下命令,移动WordPress到Apache根目录。# 在Apache的根目录/var/www/html下,创建一个wp-blog文件夹。mkdir /var/www/html/wp-blogmv * /var/www/html/wp-blog/ c. 执行以下命令,修改wp-config.php配置文件。database_name_here为之前步骤中创建的数据库名称,本示例为wordpress。username_here为之前步骤中创建的数据库用户名,本示例为test_user。password_here为之前步骤中创建的数据库登录密码,本示例为Password1213。数据库地址为RDS的连接地址(在RDS管理控制台 实例详情 页查看或者开通资源后再左侧资源栏列表中查看RDS连接地址)。sed -i 's/database_name_here/wordpress/' /var/www/html/wp-blog/wp-config.phpsed -i 's/username_here/test_user/' /var/www/html/wp-blog/wp-config.phpsed -i 's/password_here/Password1213/' /var/www/html/wp-blog/wp-config.phpsed -i 's/localhost/数据库地址/' /var/www/html/wp-blog/wp-config.php d. 执行以下命令,查看配置文件信息是否修改成功。cat -n /var/www/html/wp-blog/wp-config.php修改内容如下图所示:\3. 执行以下命令,重启Apache服务。systemctl restart httpd\4. 初始化WordPress。 a. 打开浏览器并访问http:///wp-blog/wp-admin/install.php。 您可以在左侧实验资源栏查看ECS的公网IP。 b. 设置您的站点名称、管理员用户名和密码,然后单击Install WordPress完成WordPress初始化。 c. 单击Log In,输入用户名和密码,然后再次单击Log In打开WordPress站点。登录后,您就可以根据需要创建内容进行发布了。至此您已完成WordPress的搭建。
MySQL 超级入门教程
MySQL简介
1、什么是数据库 ?
数据库(Database)是按照数据结构来组织、存储和管理数据的仓库,它产生于距今六十多年前,随着信息技术和市场的发展,特别是二十世纪九十年代以后,数据管理不再仅仅是存储和管理数据,而转变成用户所需要的各种数据管理的方式。数据库有很多种类型,从最简单的存储有各种数据的表格到能够进行海量数据存储的大型数据库系统都在各个方面得到了广泛的应用。
主流的数据库有:sqlserver,mysql,Oracle、SQLite、Access、MS SQL Server等,本文主要讲述的是mysql
2、数据库管理是干什么用的?
· a. 将数据保存到文件或内存
· b. 接收特定的命令,然后对文件进行相应的操作
PS:如果有了以上管理系统,无须自己再去创建文件和文件夹,而是直接传递 命令 给上述软件,让其来进行文件操作,他们统称为数据库管理系统(DBMS,Database Management System)
MySQL安装
MySQL是一种开放源代码的关系型数据库管理系统(RDBMS),MySQL数据库系统使用最常用的数据库管理语言–结构化查询语言(SQL)进行数据库管理。在 WEB 应用方面MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一。
使用mysql必须具备一下条件
· a. 安装MySQL服务端
· b. 安装MySQL客户端
· c. 【客户端】连接【服务端】
· d. 【客户端】发送命令给【服务端MySQL】服务的接受命令并执行相应操作(增删改查等)
1、下载地址:http://dev.mysql.com/downloads/mysql/
2、安装
· windows安装请参考:http://www.cnblogs.com/lonelywolfmoutain/p/4547115.html
· linux下安装:http://www.cnblogs.com/chenjunbiao/archive/2011/01/24/1940256.html
注:以上两个链接有完整的安装方式,撸主也是参考他的安装的,安装完以后mysql.server start启动mysql服务
MySQL操作
一、连接数据库
mysql -u user -p 例:mysql -u root -p
常见错误如下:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2), it means that the MySQL server daemon (Unix) or service (Windows) is not running.
退出连接:
QUIT 或者 Ctrl+D
二、查看数据库,创建数据库,使用数据库查看数据库:
show databases;
默认数据库:
mysql - 用户权限相关数据test - 用于用户测试数据information_schema - MySQL本身架构相关数据
创建数据库:
create database db1 DEFAULT CHARSET utf8 COLLATE utf8_general_ci; # utf8编码
create database db1 DEFAULT CHARACTER SET gbk COLLATE gbk_chinese_ci; # gbk编码
使用数据库:
use db1;
显示当前使用的数据库中所有表:
SHOW TABLES;
三、用户管理
创建用户
create user '用户名'@'IP地址' identified by '密码';
删除用户
drop user '用户名'@'IP地址';
修改用户
rename user '用户名'@'IP地址'; to '新用户名'@'IP地址';
修改密码
set password for '用户名'@'IP地址' = Password('新密码');
注:用户权限相关数据保存在mysql数据库的user表中,所以也可以直接对其进行操作(不建议)
四、权限管理
mysql对于权限这块有以下限制:
all privileges:除grant外的所有权限select:仅查权限select,insert:查和插入权限...usage:无访问权限alter:使用alter tablealter routine:使用alter procedure和drop procedurecreate:使用create tablecreate routine:使用create procedurecreate temporary tables:使用create temporary tablescreate user:使用create user、drop user、rename user和revoke all privilegescreate view:使用create viewdelete:使用deletedrop:使用drop tableexecute:使用call和存储过程file:使用select into outfile 和 load data infilegrant option:使用grant 和 revokeindex:使用indexinsert:使用insertlock tables:使用lock tableprocess:使用show full processlistselect:使用selectshow databases:使用show databasesshow view:使用show viewupdate:使用updatereload:使用flushshutdown:使用mysqladmin shutdown(关闭MySQL)super:使用change master、kill、logs、purge、master和set global。还允许mysqladmin调试登陆replication client:服务器位置的访问replication slave:由复制从属使用
对于数据库及内部其他权限如下:
数据库名.* 数据库中的所有数据库名.表 指定数据库中的某张表数据库名.存储过程 指定数据库中的存储过程. 所有数据库
对于用户和IP的权限如下:
用户名@IP地址 用户只能在改IP下才能访问用户名@192.168.1.% 用户只能在改IP段下才能访问(通配符%表示任意)用户名@% 用户可以再任意IP下访问(默认IP地址为%)
1、查看权限:
show grants for '用户'@'IP地址'
2、授权
grant 权限 on 数据库.表 to '用户'@'IP地址'
3、取消授权
revoke 权限 on 数据库.表 from '用户名'@'IP地址'
授权实例如下:
grant all privileges on db1.tb1 TO '用户名'@'IP'
grant select on db1.* TO '用户名'@'IP'
grant select,insert on . TO '用户名'@'IP'
revoke select on db1.tb1 from '用户名'@'IP'
MySQL表操作
一、查看表
show tables; # 查看数据库全部表
select * from 表名; # 查看表所有内容
二、创建表
create table 表名(列名 类型 是否可以为空,列名 类型 是否可以为空)ENGINE=InnoDB DEFAULT CHARSET=utf8
来一个实例好详解
CREATE TABLE tab1 (nid int(11) NOT NULL auto_increment,name varchar(255) DEFAULT zhangyanlin,email varchar(255),PRIMARY KEY (nid) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
注:
· 默认值,创建列时可以指定默认值,当插入数据时如果未主动设置,则自动添加默认值
· 自增,如果为某列设置自增列,插入数据时无需设置此列,默认将自增(表中只能有一个自增列)注意:1、对于自增列,必须是索引(含主键)2、对于自增可以设置步长和起始值
· 主键,一种特殊的唯一索引,不允许有空值,如果主键使用单个列,则它的值必须唯一,如果是多列,则其组合必须唯一。
三、删除表
drop table 表名
四、清空表内容
delete from 表名truncate table 表名
五、修改表
添加列:
alter table 表名 add 列名 类型
删除列:
alter table 表名 drop column 列名
修改列:
alter table 表名 modify column 列名 类型; -- 类型alter table 表名 change 原列名 新列名 类型; -- 列名,类型
添加主键:
alter table 表名 add primary key(列名);
删除主键:
alter table 表名 drop primary key;alter table 表名 modify 列名 int, drop primary key;
添加外键:
alter table 从表 add constraint 外键名称(形如:FK_从表_主表) foreign key 从表(外键字段) references 主表(主键字段);
删除外键:
alter table 表名 drop foreign key 外键名称
修改默认值:
ALTER TABLE testalter_tbl ALTER i SET DEFAULT 1000;
删除默认值:
ALTER TABLE testalter_tbl ALTER i DROP DEFAULT;
对于上述这些操作是不是看起来很麻烦,很浪费时间,别慌!有专门的软件能提供这些功能,操作起来非常简单,这个软件名字叫Navicat Premium ,大家自行在网上下载,练练手,但是下面的即将讲到表内容操作还是建议自己写命令来进行
六、基本数据类型
MySQL的数据类型大致分为:数值、时间和字符串
bit[(M)]二进制位(101001),m表示二进制位的长度(1-64),默认m=1
tinyint[(m)] [unsigned] [zerofill]
小整数,数据类型用于保存一些范围的整数数值范围:有符号:-128 ~ 127.无符号:0 ~ 255
特别的: MySQL中无布尔值,使用tinyint(1)构造。
int(m)[zerofill]
整数,数据类型用于保存一些范围的整数数值范围:有符号:-2147483648 ~ 2147483647无符号:0 ~ 4294967295
特别的:整数类型中的m仅用于显示,对存储范围无限制。例如: int(5),当插入数据2时,select 时数据显示为:00002.gif"hljs-operator">bigint(m)[zerofill]
大整数,数据类型用于保存一些范围的整数数值范围:有符号:-9223372036854775808 ~ 9223372036854775807无符号:0 ~ 18446744073709551615
decimal[(m[,d])] [unsigned] [zerofill]
准确的小数值,m是数字总个数(负号不算),d是小数点后个数。 m最大值为65,d最大值为30。
特别的:对于精确数值计算时需要用此类型decaimal能够存储精确值的原因在于其内部按照字符串存储。
FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]
单精度浮点数(非准确小数值),m是数字总个数,d是小数点后个数。无符号:-3.402823466E+38 to -1.175494351E-38,01.175494351E-38 to 3.402823466E+38有符号:01.175494351E-38 to 3.402823466E+38
数值越大,越不准确
DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]
双精度浮点数(非准确小数值),m是数字总个数,d是小数点后个数。
无符号:-1.7976931348623157E+308 to -2.2250738585072014E-30802.2250738585072014E-308 to 1.7976931348623157E+308有符号:02.2250738585072014E-308 to 1.7976931348623157E+308 数值越大,越不准确
char (m)
char数据类型用于表示固定长度的字符串,可以包含最多达255个字符。其中m代表字符串的长度。PS: 即使数据小于m长度,也会占用m长度
varchar(m)
varchars数据类型用于变长的字符串,可以包含最多达255个字符。其中m代表该数据类型所允许保存的字符串的最大长度,只要长度小于该最大值的字符串都可以被保存在该数据类型中。
注:虽然varchar使用起来较为灵活,但是从整个系统的性能角度来说,char数据类型的处理速度更快,有时甚至可以超出varchar处理速度的50%。因此,用户在设计数据库时应当综合考虑各方面的因素,以求达到最佳的平衡
text
text数据类型用于保存变长的大字符串,可以组多到65535 (2**16 − 1)个字符。
mediumtext
A TEXT column with a maximum length of 16,777,215 (2**24 − 1) characters.
longtext
A TEXT column with a maximum length of 4,294,967,295 or 4GB (2**32 − 1) characters.
enum
枚举类型,An ENUM column can have a maximum of 65,535 distinct elements. (The practical limit is less than 3000.)示例:CREATE TABLE shirts (name VARCHAR(40),size ENUM('x-small', 'small', 'medium', 'large', 'x-large'));INSERT INTO shirts (name, size) VALUES ('dress shirt','large'), ('t-shirt','medium'),('polo shirt','small');
set
集合类型A SET column can have a maximum of 64 distinct members.示例:CREATE TABLE myset (col SET('a', 'b', 'c', 'd'));INSERT INTO myset (col) VALUES ('a,d'), ('d,a'), ('a,d,a'), ('a,d,d'), ('d,a,d');
DATE
YYYY-MM-DD(1000-01-01/9999-12-31)
TIME
HH:MM:SS('-838:59:59'/'838:59:59')
YEAR
YYYY(1901/2155)
DATETIME
YYYY-MM-DD HH:MM:SS(1000-01-01 00:00:00/9999-12-31 23:59:59 Y)
TIMESTAMP
YYYYMMDD HHMMSS(1970-01-01 00:00:00/2037 年某时)
MySQL表内容操作
表内容操作无非就是增删改查,当然用的最多的还是查,而且查这一块东西最多,用起来最难,当然对于大神来说那就是so easy了,对于我这种小白还是非常难以灵活运用的,下面咱来一一操作一下
一、增
insert into 表 (列名,列名...) values (值,值,...)insert into 表 (列名,列名...) values (值,值,...),(值,值,值...)insert into 表 (列名,列名...) select (列名,列名...) from 表例:insert into tab1(name,email) values('zhangyanlin','zhangyanlin8851@163.com')
二、删
delete from 表 # 删除表里全部数据delete from 表 where id=1 and name='zhangyanlin' # 删除ID =1 和name='zhangyanlin' 那一行数据
三、改
update 表 set name = 'zhangyanlin' where id>1
四、查
select * from 表select * from 表 where id > 1select nid,name,gender as gg from 表 where id > 1
查这块的条件太多太多我给列举出来至于组合还得看大家的理解程度哈
a、条件判断where
select * from 表 where id > 1 and name != 'aylin' and num = 12;select * from 表 where id between 5 and 16;select * from 表 where id in (11,22,33)select * from 表 where id not in (11,22,33)select * from 表 where id in (select nid from 表)
b、通配符like
select * from 表 where name like 'zhang%' # zhang开头的所有(多个字符串)select * from 表 where name like 'zhang_' # zhang开头的所有(一个字符)
c、限制limit
select * from 表 limit 5; - 前5行select * from 表 limit 4,5; - 从第4行开始的5行select * from 表 limit 5 offset 4 - 从第4行开始的5行
d、排序asc,desc
select * from 表 order by 列 asc - 根据 “列” 从小到大排列select * from 表 order by 列 desc - 根据 “列” 从大到小排列select * from 表 order by 列1 desc,列2 asc - 根据 “列1” 从大到小排列,如果相同则按列2从小到大排序
e、分组group by
select num from 表 group by numselect num,nid from 表 group by num,nidselect num,nid from 表 where nid > 10 group by num,nid order nid descselect num,nid,count(*),sum(score),max(score),min(score) from 表 group by num,nidselect num from 表 group by num having max(id) > 10
特别的:group by 必须在where之后,order by之前
好了,以上我们就完成了MySQL的入门。经过练习之后,一些简单的增删改查任务已经不成问题,这时候就应该要考虑进阶了。
限于本文的主题和篇幅,在这里我们就不多说了,如果有需要的同学可以前往 MySQL 的官方文档:https://dev.mysql.com/doc/ 进行查看,英文不太好的同学也可以去菜鸟教程:http://www.runoob.com/mysql/mysql-tutorial.html。
MySQL 资源大全
除了一份入门的教程,小编还给大家准备了一份礼物,那就是 MySQL 资源大全。
工欲善其事必先利其器,有了这些工具,我们和大神的差距就会缩小许多,而且很多工具也会为我们的日常提升提供很大帮助——有了工具包,妈妈再也不用担心你的学习!
分析工具
性能,结构和数据分析工具
· Anemometer – 一个 SQL 慢查询监控器。
· innodb-ruby – 一个对 InooDB 格式文件的解析器,用于 Ruby 语言。
· innotop – 一个具备多种特性和可扩展性的 MySQL 版 ‘top’ 工具。
· pstop – 一个针对 MySQL 的类 top 程序,用于收集,汇总以及展示来自 performance_schema 的信息。
· mysql-statsd – 一个收集 MySQL 信息的 Python 守护进程,并通过 StatsD 发送到 Graphite。
备份
备份/存储/恢复 工具
· MyDumper – 逻辑的,并行的 MySQL 备份/转储工具。
· MySQLDumper – 基于 web 的开源备份工具-对于共享虚拟主机非常有用。
· mysqldump-secure – 将加密,压缩,日志,黑名单和 Nagios 监控一体化的 mysqldump 安全脚本。
· Percona Xtrabackup – 针对 MySQL 的一个开源热备份实用程序——在服务器的备份期间不会锁定你的数据库。
性能测试
给你的服务器进行压测的工具
· iibench-mysql -基于 Java 的 MySQL/Percona/MariaDB 索引进行插入性能测试工具。
· Sysbench – 一个模块化,跨平台以及多线程的性能测试工具。
聊天应用
集成进聊天室的脚本
· Hubot MySQL ChatOps
配置
MySQL 配置实例及指导
· mysql-compatibility-config – 使 MySQL 配置起来更像新的(或先前)的 MySQL 版本。
连接器
多种编程语言的 MySQL 连接器
· Connector/Python – 一个对于 Python 平台和开发的标准化数据库驱动程序。
· go-sql-driver – 一个 Go 语言的轻量级、极速的 MySQL 驱动程序。
· libAttachSQL – libAttachSQL 是 MySQL 服务器的一个轻量级,非阻塞的 C 语言 API。
· MariaDB Java Client – 针对 Java 应用且经过 LGPL 许可的 MariaDB 客户端库。
· MySQL-Python – 一个 Python 语言的 MySQL 数据库连接器。
· PHP mysqlnd – 针对 MySQL 的 MySQL 本地驱动,弃用过时的 libmysql 基础驱动。
开发
支持 MySQL 相关开发的工具
· Flywaydb – 数据库迁移;任意情况下轻松可靠地演变你的数据库版本。
· Liquibase – 对你的数据库进行源代码控制。
· Propagator – 集中模式和数据部署在一个多维拓扑上。
GUI
前端和应用的 GUI
· Adminer – 一个 PHP 编写的数据库管理工具。
· HeidiSQL – Windows 下的 MySQL 图形化管理工具。
· MySQL Workbench – 提供给数据库管理员和开发人员进行数据库设计和建模的集成工具环境;SQL 开发;数据库管理。
· phpMyAdmin – 一个 PHP 写成的开源软件,意图对 web 上的 MySQL 进行管理。
· SequelPro – 一个 mac 下运行 MySQL 的数据库管理应用程序。
· mycli – 一个带自动补全和语法高亮的终端版 MySQL 客户端
HA
高可用解决方案
· Galera Cluster – 一个基于同步复制的多主机集群方案。
· MHA – 针对 MySQL 的优秀高可用管理器及工具
· MySQL Fabric – 一个用于管理 MySQL 服务器场(Server Farms)的可扩展框架。
· Percona Replication Manager – 针对 MySQL 的异步复制管理代理。支持以文件和 GTID 为基础的复制,使用 booth 实现的地理分布式集群。
代理
MySQL 代理
· MaxScale – 开源,以数据库为中心的代理。
· Mixer – Go 实现的一个 MySQL 代理,目的为 MySQL 分片提供一个简单的解决方案。
· MySQL Proxy – 一个处于你的客户端和 MySQL 服务端之间的简单程序,它可以检测、分析或者改变它们的通信。
· ProxySQL – 高性能的 MySQL 代理。
复制
复制相关的软件
· orchestrator – 对 MySQL 复制拓扑管理并可视化的工具。
· Tungsten Replicator – MySQL 的一个高性能、开源、数据复制引擎。
模式
附加模式
· common_schema – MySQL DBA 的框架, 提供一个具有函数库、视图库和查询脚本的解释器。
· sys – 一个视图、函数和过程的集合,以帮助 MySQL 管理人员更加深入理解 MySQL 数据库的使用。
服务器
MySQL server flavors
· MariaDB – MySQL server 的一个由社区开发的分支。
· MySQL Server & MySQL Cluster – Oracle 官方的 MySQL server 和 MySQL 集群分布。
· Percona Server – 一个加强版的 MySQL 替代品
· WebScaleSQL – WebScaleSQL,5.6 版本,基于 MySQL 5.6 社区版本。
分片
分片解决方案/框架
· vitess – 对于大规模的 web 服务,vitess 提供服务和工具以便于 MySQL 数据库的缩放。
· jetpants – 一个自动化套件,用于管理大规模分片集群,由 Tumblr 开发。
工具包
工具包,通用脚本
· go-mysql – 一个纯 go 的库,用于处理 MySQL 的网络协议和复制。
· MySQL Utilities – 一个命令行实用程序的集合,Python 语言编写,用于维护和管理单一或多层的 MySQL。
· Percona Toolkit – 一个先进的命令行工具集,用于执行对于 MySQL 服务器和系统过于困难或复杂的任务。
· openark kit – 一组实用的工具,解决日常的维护工作,包括一些复杂的或需徒手操作的,用 Python 语言编写。
· UnDROP – 一个用来恢复删除或损坏的 InnoDB 表中数据的工具。
本文部分内容来源于伯乐在线
负载均衡集群解决方案(三)haproxy
一、haproxy简介
HAProxy is a free, very fast and reliable solution offering high availability, load balancing, and proxying for TCP and HTTP-based applications. It is particularly suited for web sites crawling under very high loads while needing persistence or Layer7 processing. Supporting tens of thousands of connections is clearly realistic with todays hardware. Its mode of operation makes its integration into existing architectures very easy and riskless, while still offering the possibility not to expose fragile web servers to the Net。
摘自:http://haproxy.1wt.eu
二、haproxy集群工作流程
三、haproxy安装
# tar -xzvf haproxy-1.3.20.tar.gz
# make TARGET=linux26 PREFIX=/usr/local/haproxy install注:TARGET后面根据本机操作系统内核版本来填写
创建配置文件目录,日志目录,并根据需求编写配置文件
# mkdir /usr/local/haproxy/{conf,logs}
# vim /usr/local/haproxy/conf/haproxy.cfg
配置haproxy的日志环境
# vim /etc/syslog.conf
添加:
local0.* /usr/local/logs/haproxy.log
local3.* /usr/local/logs/haproxy_err.log
#vim /etc/sysconfig/syslog
修改:
SYSLOGD_OPTIONS="-r -m 0"
service syslog restart注: -r enables logging from remote machines
四、haproxy配置详解
HAProxy配置中分五大部分:
global:全局配置参数,进程级的,用来控制Haproxy启动前的一些进程及系统设置
defaults:配置一些默认的参数,可以被frontend,backend,listen段继承使用
frontend:用来匹配接收客户所请求的域名,uri等,并针对不同的匹配,做不同的请求处理
backend:定义后端服务器集群,以及对后端服务器的一些权重、队列、连接数等选项的设置,我将其理解为Nginx中的upstream块
listen:我将其理解为frontend和backend的组合体
配置一例:
global # 全局参数的设置
log 127.0.0.1 local0 info
# log语法:log [max_level_1]
# 全局的日志配置,使用log关键字,指定使用127.0.0.1上的syslog服务中的local0日志设备,记录日志等级为info的日志
user haproxy
group haproxy
# 设置运行haproxy的用户和组,也可使用uid,gid关键字替代之
daemon
# 以守护进程的方式运行
nbproc 16
# 设置haproxy启动时的进程数,根据官方文档的解释,我将其理解为:该值的设置应该和服务器的CPU核心数一致,即常见的2颗8核心CPU的服务器,即共有16核心,则可以将其值设置为:<=16 ,创建多个进程数,可以减少每个进程的任务队列,但是过多的进程数也可能会导致进程的崩溃。这里我设置为16
maxconn 4096
# 定义每个haproxy进程的最大连接数 ,由于每个连接包括一个客户端和一个服务器端,所以单个进程的TCP会话最大数目将是该值的两倍。
#ulimit -n 65536
# 设置最大打开的文件描述符数,在1.4的官方文档中提示,该值会自动计算,所以不建议进行设置
pidfile /var/run/haproxy.pid
# 定义haproxy的piddefaults # 默认部分的定义
mode http
# mode语法:mode {http|tcp|health} 。http是七层模式,tcp是四层模式,health是健康检测,返回OK
log 127.0.0.1 local3 err
# 使用127.0.0.1上的syslog服务的local3设备记录错误信息
retries 3
# 定义连接后端服务器的失败重连次数,连接失败次数超过此值后将会将对应后端服务器标记为不可用
option httplog
# 启用日志记录HTTP请求,默认haproxy日志记录是不记录HTTP请求的,只记录“时间[Jan 5 13:23:46] 日志服务器[127.0.0.1] 实例名已经pid[haproxy[25218]] 信息[Proxy http_80_in stopped.]”,日志格式很简单。
option redispatch
# 当使用了cookie时,haproxy将会将其请求的后端服务器的serverID插入到cookie中,以保证会话的SESSION持久性;而此时,如果后端的服务器宕掉了,但是客户端的cookie是不会刷新的,如果设置此参数,将会将客户的请求强制定向到另外一个后端server上,以保证服务的正常。
option abortonclose
# 当服务器负载很高的时候,自动结束掉当前队列处理比较久的链接
option dontlognull
# 启用该项,日志中将不会记录空连接。所谓空连接就是在上游的负载均衡器或者监控系统为了探测该服务是否存活可用时,需要定期的连接或者获取某一固定的组件或页面,或者探测扫描端口是否在监听或开放等动作被称为空连接;官方文档中标注,如果该服务上游没有其他的负载均衡器的话,建议不要使用该参数,因为互联网上的恶意扫描或其他动作就不会被记录下来
option httpclose
# 这个参数我是这样理解的:使用该参数,每处理完一个request时,haproxy都会去检查http头中的Connection的值,如果该值不是close,haproxy将会将其删除,如果该值为空将会添加为:Connection: close。使每个客户端和服务器端在完成一次传输后都会主动关闭TCP连接。与该参数类似的另外一个参数是“option forceclose”,该参数的作用是强制关闭对外的服务通道,因为有的服务器端收到Connection: close时,也不会自动关闭TCP连接,如果客户端也不关闭,连接就会一直处于打开,直到超时。
contimeout 5000
# 设置成功连接到一台服务器的最长等待时间,默认单位是毫秒,新版本的haproxy使用timeout connect替代,该参数向后兼容
clitimeout 3000
# 设置连接客户端发送数据时的成功连接最长等待时间,默认单位是毫秒,新版本haproxy使用timeout client替代。该参数向后兼容
srvtimeout 3000
# 设置服务器端回应客户度数据发送的最长等待时间,默认单位是毫秒,新版本haproxy使用timeout server替代。该参数向后兼容listen status # 定义一个名为status的部分
bind 0.0.0.0:1080
# 定义监听的套接字
mode http
# 定义为HTTP模式
log global
# 继承global中log的定义
stats refresh 30s
# stats是haproxy的一个统计页面的套接字,该参数设置统计页面的刷新间隔为30s
stats uri /admin?stats
# 设置统计页面的uri为/admin?stats
stats realm Private lands
# 设置统计页面认证时的提示内容
stats auth admin:password
# 设置统计页面认证的用户和密码,如果要设置多个,另起一行写入即可
stats hide-version
# 隐藏统计页面上的haproxy版本信息frontend http_80_in # 定义一个名为http_80_in的前端部分
bind 0.0.0.0:80
# http_80_in定义前端部分监听的套接字
mode http
# 定义为HTTP模式
log global
# 继承global中log的定义
option forwardfor
# 启用X-Forwarded-For,在requests头部插入客户端IP发送给后端的server,使后端server获取到客户端的真实IP
acl static_down nbsrv(static_server) lt 1
# 定义一个名叫static_down的acl,当backend static_sever中存活机器数小于1时会被匹配到
acl php_web url_reg /*.php$
#acl php_web path_end .php
# 定义一个名叫php_web的acl,当请求的url末尾是以.php结尾的,将会被匹配到,上面两种写法任选其一
acl static_web url_reg /*.(css|jpg|png|jpeg|js|gif)$
#acl static_web path_end .gif .png .jpg .css .js .jpeg
# 定义一个名叫static_web的acl,当请求的url末尾是以.css、.jpg、.png、.jpeg、.js、.gif结尾的,将会被匹配到,上面两种写法任选其一
use_backend php_server if static_down
# 如果满足策略static_down时,就将请求交予backend php_server
use_backend php_server if php_web
# 如果满足策略php_web时,就将请求交予backend php_server
use_backend static_server if static_web
# 如果满足策略static_web时,就将请求交予backend static_serverbackend php_server #定义一个名为php_server的后端部分
mode http
# 设置为http模式
balance source
# 设置haproxy的调度算法为源地址hash
cookie SERVERID
# 允许向cookie插入SERVERID,每台服务器的SERVERID可在下面使用cookie关键字定义
option httpchk GET /test/index.php
# 开启对后端服务器的健康检测,通过GET /test/index.php来判断后端服务器的健康情况
server php_server_1 10.12.25.68:80 cookie 1 check inter 2000 rise 3 fall 3 weight 2
server php_server_2 10.12.25.72:80 cookie 2 check inter 2000 rise 3 fall 3 weight 1
server php_server_bak 10.12.25.79:80 cookie 3 check inter 1500 rise 3 fall 3 backup
# server语法:server [:port] [param*]
# 使用server关键字来设置后端服务器;为后端服务器所设置的内部名称[php_server_1],该名称将会呈现在日志或警报中、后端服务器的IP地址,支持端口映射[10.12.25.68:80]、指定该服务器的SERVERID为1[cookie 1]、接受健康监测[check]、监测的间隔时长,单位毫秒[inter 2000]、监测正常多少次后被认为后端服务器是可用的[rise 3]、监测失败多少次后被认为后端服务器是不可用的[fall 3]、分发的权重[weight 2]、最为备份用的后端服务器,当正常的服务器全部都宕机后,才会启用备份服务器[backup]backend static_server
mode http
option httpchk GET /test/index.html
server static_server_1 10.12.25.83:80 cookie 3 check inter 2000 rise 3 fall 3
五、健康监测
1、通过监听端口进行健康检测
这种检测方式,haproxy只会去检查后端server的端口,并不能保证服务的真正可用。
listen http_proxy 0.0.0.0:80
mode http
cookie SERVERID
balance roundrobin
option httpchk
server web1 192.168.1.1:80 cookie server01 check
server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2
2、通过URI获取进行健康检测
这种检测方式,是用过去GET后端server的的web页面,基本上可以代表后端服务的可用性。
listen http_proxy 0.0.0.0:80
mode http
cookie SERVERID
balance roundrobin
option httpchk GET /index.html
server web1 192.168.1.1:80 cookie server01 check
server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2
3、通过request获取的头部信息进行匹配进行健康检测
这种检测方式,则是基于高级,精细的一些监测需求。通过对后端服务访问的头部信息进行匹配检测。
listen http_proxy 0.0.0.0:80
mode http
cookie SERVERID
balance roundrobin
option httpchk HEAD /index.jsp HTTP/1.1\r\nHost:\ www.xxx.com
server web1 192.168.1.1:80 cookie server01 check
server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2
六、haproxy实现持久连接
1 调度算法source
haroxy 将用户IP经过hash计算后 指定到固定的真实服务器上(类似于nginx 的IP hash 指令)
配置指令 balance source
2 cookie 识别
haproxy 将WEB服务端发送给客户端的cookie中插入(或添加加前缀)haproxy定义的后端的服务器COOKIE ID。
配置指令例举 cookie SESSION_COOKIE insert indirect nocache
3 session 识别
haproxy 将后端服务器产生的session和后端服务器标识存在haproxy中的一张表里。客户端请求时先查询这张表。然后根据session分配后端server。
配置指令:appsession <cookie> len <length> timeout <holdtime>
七、统计页面效果图
本文转自 向阳草米奇 51CTO博客,原文链接:http://blog.51cto.com/grass51/1109825,如需转载请自行联系原作者
浅谈Notepad++选中行操作+快捷键+使用技巧【超详解】
Notepad++选中行操作 快捷键 使用技巧
用Notepad++写代码,要是有一些重复的代码想copy一下,还真不容易,又得动用鼠标,巨烦人。。。。
有木有简单的方法呢,确实还是有的不过也不算太好用。
主要是应用键盘上的 Home 键 和 End 键。鼠标光标停留在一行的某处,按 Home 键光标会跳到行首,按End键光标会跳到行尾。 鼠标光标停留在行尾,按 Shift + Home 选中一行。 鼠标光标停留在行首,按 Shift + End 选中一行。 鼠标光标停留在类中某处,按 Shift + PageUp 选中类的光标前面所有内容。 鼠标光标停留在类中某处,按 Shift + PageDown 选中类的光标后面所有内容。 选中所有内容,Ctrl + A 。
要选中一行可以先按Home键,然后再按Shift + End 选中一行。
Notepad++ 快捷键 大全
Ctrl+C 复制
Ctrl+X 剪切
Ctrl+V 粘贴
Ctrl+Z 撤消
Ctrl+Y 恢复
Ctrl+A 全选
Ctrl+F 键查找对话框启动
Ctrl+H 查找/替换对话框
Ctrl+D 复制并粘贴当行
Ctrl+L 删除当前行
Ctrl+T 当行向上移动一行
F3 查找下一个
Shift+F3 查找上一个
Ctrl+Shift+F 组合在文件中查找
Ctrl+F3 查找(volatil)下一页
Ctrl+Shift+F3 查找(volatil)上一页
Ctrl+Shift+I 组合增量搜索
Ctrl+S 保存文件
Ctrl+Alt+S 另存为
Ctrl+Shift+S 保存所有文件
Ctrl+O 打开文件
Ctrl+N 新建立文件
Ctrl+F2 切换书签
F2 转到下一个书签
Shift+F2 转到上一个书签
CTRL+G 定位换行,偏移量
Ctrl+W 关闭当前文档
Alt+Shift+Arrow 键移箭头键或
ALT+鼠标左键 单击列选择
F5 启动运行对话框
Ctrl+空格 输入法切换
Alt+空格 程序单击右键
Tab 插入缩进
Shift+Tab 删除缩进
Alt-Shift-Arrow 或
Ctrl +鼠标滚轮钮 放大缩小
Ctrl +Keypad/恢复原来的大小
F11 全屏模式
Ctrl+Tab 下一个文档
Ctrl+Shift+Tab 上一个文档
Ctrl+Shift+Up 当前线向上移
Ctrl-Shift-Down 当前线向下移
Ctrl+Alt+F 折叠当前层次
Ctrl+Alt+Shift+F展开当前层次
Alt+0 折叠全部
Alt+Shift+0 展开全部
Alt+(1~8) 折叠级别(1~8)
Alt+Shift+(1~8) 展开级别(1~8)
Ctrl+BackSpace 删除开始词
Ctrl+Delete 删除结束词
Ctrl+Shift+BackSpace 删除至行
Ctrl+Shift+Delete 删除至行尾
CTRL+U 转换为小写
Ctrl+Shift+U 转换为大写
Ctrl+B 转至匹配的括号
Ctrl+Shift+R 的开始录制/停止录制宏
Ctrl+Shift+P 播放录制的宏
CTRL+Q 注释/取消注释
Ctrl+Shift+Q 值流评论
Ctrl+Shift+T 当前行复制到剪贴板
Ctrl+P 打印
Alt+F4 退出
Ctrl+I 分割线
Ctrl+J 连接行
Ctrl+Alt+R 从右边阅读
Ctrl+Alt+L 从左边阅读
Ctrl+H 打开Find / Replace 对话框
Ctrl+D 复制当前行
Ctrl+L 删除当前行
Ctrl+T 上下行交换
F3 找下一个
Shift+F3 找上一个
Ctrl+Shift-F 在文件中找
Ctrl+F2 触发书签
F2 到前一个书签
Shift+F2 到下一个书签
F5 打开run对话框
Ctrl+Space 打开CallTip列表框
Tab (selection of several lines) 加入Space
Shift+Tab (selection of several lines) 移除Space
F11 全屏
Alt+0 折叠全部
Alt+Shift+0 展开全部
Ctrl+U 变为小写
Ctrl+Shift+U 变为大写
Ctrl+Q 块注释/消除注释
F1 关于帮助
主要添加或调整的光标操作按键:
向前(Ctrl+F),向后(Ctrl+B),上一行(Ctrl+P),下一行(Ctrl+N)
行最前(Ctrl+A), 行最后(Ctrl+E)
方法
菜单<设置>-<管理快捷键>
在”Main menu”及“Scintilla commands”中修改。
修改旧的快捷键,避免冲突:
新建 -> Ctrl+Alt+N
定位匹配括号 ->Ctrl+Alt+B
查找 -> Ctrl+Alt+F
选择所有 -> Ctrl+Alt+A
Alt+H 隐藏行
Ctrl+Tab 实现在多个打开的窗口间切换
Ctrl+Shift+Q区块注释
Ctrl+K行注释(取消Ctrl+Shift+K)
文件
新建文件 Ctrl+N
打开文件 Ctrl+O
保存文件 Ctrl+S
另存为 Ctrl+Alt+S
全部保存 Ctrl+Shift+S
关闭当前文件 Ctrl+W
打印文件 Ctrl+P
退出 Alt+F4
编辑
撤销 Ctrl+Z
恢复 Ctrl+Y
剪切 Ctrl+X
复制 Ctrl+C
删除 Del
全选 Ctrl+A
列编辑 Alt+C
缩进 Tab
删除缩进 Shift+Tab
转为大写 Ctrl+Shift+U
转为小写 Ctrl+U
复制当前行 Ctrl+D
删除当前行 Ctrl+L
分割行 Ctrl+I
合并行 Ctrl+J
上移当前行 Ctrl+Shift+Up
下移当前行 Ctrl+Shift+Down
添加/删除单行注释 Ctrl+Q
设置行注释 Ctrl+K
取消行注释 Ctrl+Shift+K
区块注释 Ctrl+Shift+Q
函数自动完成 Ctrl+Space
搜索
查找 Ctrl+F
在文件中搜索 Ctrl+Shift+F
查找下一个 F3
查找上一个 Shift+F3
选定并找下一个 Ctrl+F3
行定位 Ctrl+G
定位匹配括号 Ctrl+B
设置/取消书签 Ctrl+F2
下一书签 F2
上一书签 Shift+F2
视图
全屏 F11
便签模式 F12
折叠所有层次 Alt+0
展开所有层次 Alt+Shift+0
折叠当前层次 Ctrl+Alt+F
展开当前层次 Ctrl+Alt+Shift+F
隐藏行 Alt+H
从视图激活 F8
文本比较工具
打开的文件比较 Alt+D
关闭文件比较 Ctrl+Alt+D
跟上次保存的文件比较 Alt+S
跟SVN的文件比较 Alt+B
上一个差异地方 Ctrl+Page UP
下一个差异地方 Ctrl+Page Down
第一个差异地方 Ctrl+Shift+Page Up
最后一个差异地方 Ctrl+Shift+Page Down
Function List是Notepad++诸多很酷的功能之一。但最新的版本需要额外的步骤来正确设置Function List。笔者就将介绍如何安装Function List,以及如何设置Function List。
首先,Function List插件并没有在Notepad++自带的插件清单里,也没有在Plugin Manager的Available List里 = =|||。所以要安装Function List,还得去Plugin_Central下载,笔者下载的最新版本是2.1.0.1。
将下载的压缩包解压后就有诸多的文件了,首先复制FunctionList.dll到<notepad++ install
dir>/plugins目录,再把FunctionListRules.xml,Gmod
Lua.bmp和C++.flb复制到<notepad++ install
dir>/plugins/config,到这里安装部分就完成了。
接下来就需要打开Notepad++对Function List进行设置了。Plugins->Function
List->Language Parsing Rules。然后,在语言列表中选择C/C++,勾选上“Bitmap
List”checkbox。浏览到plugins/config目录,并选择C++.flb,于是乎就万事大吉了。
notepad++挂接Python和gcc
Python挂接:Run -> Run… 填写python可执行文件的路径以及notepad++预定义的源文件地址: D:\Python26\pythonw.exe “$(FULL_CURRENT_PATH)”然后建议点下面的save附加快捷键gcc挂接Run -> Run… 填写***,我的是 D:\mingw\bin\gcc.exe “$(FULL_CURRENT_PATH)” -o “$(NAME_PART).exe”因为编译要生成文件,通过Plug-Ins -> NppExec -> Follow $(CURRENT_DIRECTORY)可以使生成的exe在源文件目录里。
最近在用Notepad++,发现的确是很不错的工具,具体特色,看了下面介绍就知道了。
【notepad++简介】
Notepad++是旨在替代Windows默认的notepad而生,比notepad的功能强大很多很多。
(1)Notepad++的版本:ANSI和Unicode
Notepad++有两个版本,一个是ANSI版本,一个是UNICODE版本。
对于大多数人把Notepad++作为notepad的增强版,而需要的普通应用的话,ANSI版本和UNICODE版本,其实没啥差别。
(2)Notepad++支持丰富的插件
notepad++支持插件,添加对应不同的插件,以支持不同的功能。里面除了一些常见的插件之外,还有一些好玩的插件,比如将文字读出来的speech插件。
(3)Notepad++特点概述
Notepad++属于轻量级的文本编辑类软件,比其他一些专业的文本编辑类工具,比如UltraEdit等要启动更快,占用资源更少,但是从功能使用等方面来说,不亚于那些专业工具,而windows默认的notepad虽然更“轻量”,但是功能就太少。所以一般用notepad++,或者另一个工具notepad2来代替notapad,同样也代替太复杂和庞大的UltraEdit。
【notepad,notepad2,notepad++,ultraEdit比较】
根据个人对一些文本类编辑工具的使用感觉来看,notepad2比notepad++相对启动更快,占用资源更少,但是相对来说,功能比较少,所以,很多常用的方便的功能,还是没法使用。而ultraEdit虽然功能多,但是太消耗资源,用起来太麻烦了,关键还是收费的,而notepad++是免费的。总的概括如下:
notepad:windows自带的,占用资源最少,启动最快,但是功能太弱,以至于满足需求。是免费的。
notepad2:占用资源稍多,启动也很快,但是功能上,没有notepad++多,更没有ultraEdit多。是免费的。
notepad++:占用资源有点多,启动要停顿一下,但是功能很强大,尤其是支持插件模式,使得扩展性非常好,支持很多的其他高级功能,而且使用起来也很方便。是免费的。
ultraEdit:功能强大,但是安装文件很大,占用资源多,启动慢,而且是收费的。
因此,根据启动速度,占用资源,功能支持,等方面来综合衡量,对于notepad,notepad2,notepad++,ultraEdit来说,无疑notepad++是最好的选择了。
【notepad++插件添加方法】
方法1:可以手动去notepad++插件的官方网站下载:
http://sourceforge.net/projects/npp-plugins/files/
方法2.让notepad的插件管理器自动下载和安装
点击:Plugins -> Plugin Manager -> Show Plugin Manager-> Avaliable一栏显示当前可用的插件列表,选中你要的插件,然后点击下面的Install即可自动下载和安装对应插件,很是方便
下面说说个人的使用体会和使用心得:
【查看当前notepad++的版本】
查看自己当前Notepad++是什么版本的话,点击工具栏上的 ?-> About Notepad++,弹出对话框会显示“Notepad++ v5.8.6 (ANSI)”字样,其中(ANSI)即代表当前是ANSI版本。
个人觉得一些好用,值得一提的特性是:
1.支持语法高亮和颜色自定义
关键是支持的语言狂多,除了常见的c/c++,java,php,而且还支持python和xml。
而且对于xml,还支持点击关键字可以展开或收缩,很是方便。后来得知,这个特性叫做代码折叠,囧。。。
还支持makefile,这样对于查看makefile文件的的话,就很方便了。
而且甚至连一般人不常用的Tex/LaTex的语法高亮,都支持了,很强大。
对于语法高亮时显示的颜色,也可以自定义,点击:
Settings -> Style Configurator
就可以根据自己需要配置不同的颜色了。
【自定义除默认后缀之外的其他后缀文件为某类型文件以实现语法高亮】
而且对于不同类型的文件的后缀,除了默认的文件后缀之外,设置自定义的文件后缀,比如我遇到的,对于普通的makefile,其默认的后缀是是.mak,而我此处自己的.mk也是makefile文件,所以可以通过这样来设置:
Settings -> Style Configurator -> 在Language中下拉找到Makefile,选择makefile,左下角会出现:
Default ext. 和user ext.,默认的扩展名(default extension)即后缀名.对应的是.mak,在user ext.所对应的框中填写.mk,
然后点击右边的 Save&Close,就可以实现notepad++自动识别.mk文件为makefile文件,然后引用对应的语法高亮了。
当然,如果不设置的话,单独打开.mk类型文件,notepad++虽然不会自动识别,没有语法高亮,但是也可以自己手动选择的:
language -> M -> Makefile,即可实现同样的功能,只是要麻烦自己每次都要手动设置而已。
2.添加hex editor插件以支持16进制编辑
notepad++支持添加HEX-Editor插件以支持16进制的查看与编辑,很是方便。
【Hex Editor插件的添加方法】
先通过上面的【查看当前notepad++的版本】的方法得知你自己的notepad++是ANSI还是UNICODE方法,
然后根据上面的 【notepad++插件添加方法】 去Notepad++插件的官网,找到并下载对应版本的Hex Editor,把插件文件HexEditor.dll,放到NotePad++路径下的 npp.5.8.6.bin\ansi\plugins文件夹里面即可。
当前也可以通过上面介绍的插件管理器,直接通过软件帮你自动下载并安装。
然后重启notepad++,就可以在Plugins中看到对应的Hex-Editor插件了。
值得一提的是,当前的最新版本(5.8.7)还支持了添加插件后,对应地在工具栏上也添加一个快捷图标,对于HexEditor来说,就是一个大写的H的图标,点击该图标,即可实现16进制查看,再次点击,又恢复到正常模式,很是方便。
3. 支持列模式编辑
按住Alt之后,就处于列模式了,然后比如你选取一列,然后点击右键,选中删除,就可以删除那些列了,松掉ALT就离开了ALT恢复普通模式了。非常好用,越来越觉得notepad++牛X了,啥功能都支持啊。。。
列操作模式中的在整个列中,整个都插入一些内容的话,可以这样操作:
Edit -> Column Editor (Alt C)
然后在Text to insert或Number to insert对应的的框中写入要插入的内容,notepad++就会自动帮你插入整列的对应的内容了
4.选中某单词即关键字后,notepad++会自动高亮对应选中的关键字,对于文件查看来说,很是方便。
5.打开多个文件的时候,上面会显示对应的Tab,默认的话,双击Tab是不能像其他一些工具一样关闭该文件的,但是可以设置的:
Settings-> Preference ->General -> Tab Bar中,选中:
Double Click to close document, 然后双击对应文件的tab就可以关闭文件了。
类似地,还有个选项:show close button on each tab,选中后,每个tab上会出现关闭按钮,也很方便使用。
6。显示文件行号:Settings-> Preference ->General -> Editing-> 选中Display Line Number,即可显示行号
7.是否打印行号:Settings-> Preference ->General ->
Printing-> 是否选中Printing Line
Number,默认是不选的,如果需要,可以选中,这样打印时候就可以也打印行号了,还是很方便用户根据自己需要而去设置的。
8.编辑文件后,是否备份:类似Ultra
Editor,编辑一个文件后,默认会生成.bak文件的,对于notepad++来说,也是支持此功能的,不过默认是关闭的。需要的话,可以去这里设置:Settings->
Preference ->General -> Backup/Auto-completion ->
默认是None,其他还有Simple和verbose backup,可以根据自己需要而设置。
9.自动完成功能:Settings-> Preference ->General -> Backup/Auto-completion,自动完成:Auto-Completion,可以根据自己需要而设置,默认是关闭的。
10.选中某文字,然后调用google搜索:
run -> google search
除了google搜索此项功能,于此相关类似的还有,选中文字后,调用其他程序或功能,比如直接调用wiki查询该单词/文字:
run -> wikipedia search
或者直接从notepad++中打开当前文件所在文件夹:
run -> open containing folder
从notepad++中打开windows的cmd,并且已经处于当前文件夹:
run -> open current dir cmd
直接把该文件作为附件,然后打开Windows的Outlook发送邮件
run -> send via Outlook
等等,都是非常实用好用的功能。
11.暂时隐藏某些行
如果在查看文件的时候,暂时觉得需要将某些行隐藏掉,在需要的时候再正常显示,就可以先选中那些行,然后:
View -> Hide Lines
即可。然后左边标签那列就会显示对应的标示,点击即可取消隐藏。
12.支持鼠标滚轮控制缩放
notepad++不仅支持快捷键Ctrl + Num+/Num- 去控制缩放,而且还支持Ctrl+鼠标滚轮去控制当前显示内容的缩放,很是方便。
13.全屏显示
有时候显示文档的话,希望显示更多的内容,希望用到全屏显示,通过view -> Toogle Full Screen Mode F11或者Post it F12,都可以实现全屏显示,也很是方便。
14.集成了轻量级的资源管理器
通过安装插件(默认好像是已经安装了)LightExplorer后:
Plugins -> Light Explorer -> Light Explorer,就可以在左侧打开一个轻量级的资源管理器,方法打开想要打开的文件,很是方便啊。
15.导出成其他类型文件 -> 实现彩色代码的粘贴
在添加了对应的NppExport插件后,就可以导出成不同的格式,比如HTML和RTF:
plugins -> NppExport -> Export to RTF或Export to HTML
其中HTML就是普通的HTML,RTF就可以理解为简洁版本的word,所以html和rtf,两者都是支持彩色代码/字符的,因此,这个功能就可以实现我们所需要的,将已经高亮显示,彩色显示,着色后的代码,导出到word或者其他文档中了。这样的功能,是很实用的。至少我个人觉得很好用,比如将一些C代码打开后,导出成html,然后打开html复制内容后粘贴到word里面,就是彩色的代码了。当然,你也可以导出成rtf,然后本身就是和word兼容的,windows下,也就是默认用word打开的了,就省去了从html拷贝粘贴过来的步骤了。
甚至,NppExport还提供了更方便的功能:
plugins -> NppExport -> Copy HTML to clipboard 或Copy RTF to clipboard
即,直接选择内容后,拷贝该内容到剪贴板,然后你就可以在其他word文件中直接粘贴了,即如此简单地就实现了彩色代码的支持,多么爽啊。
16.代码折叠
包括对C/C++等代码,可以以单个函数为整体进行代码的折叠和展开,其他的类型的,比如XML,根据关键字所包含的内容为整体进行折叠和展开等等。
17.资源管理器中,右键点击文件,可以直接用notepad++打开该文件
这个功能类似于UltraEdit,在资源管理器中添加了右键支持,右键点击某文件后,会出现“Edit With Notepad++”,就可以直接用notepad++打开该文件了,个人觉得这个功能还是很实用的。
18.Ctrl+Tab实现在多个打开的窗口间切换
19. 支持设置是否显示列边界(右边线)
设置->首选项->编辑->列边界,可以设置是否显示列边界,而且也支持自定义“边界宽度”的大小,默认是100。
(注:一般Linux下面常用的是80.)
而且对于列边界显示模式,还支持两种:
一种是从上到下的竖边线:
另一种是把超过列边界的内容加上一定的底色:
20.可以给代码批量添加或取消注释
选中一段代码,然后:编辑 -> 注释/取消注释 -> 添加/删除单行注释,即可批量地队选中的每一行,添加或者删除注释。
此功能,对于常写代码的人来说,还是很实用的。
notepad++的更多的其他功能,感兴趣的自己去探索。
总之,个人觉得,Notepad++,是个非常好用的,轻量级的,但是功能足够丰富的,文字/代码编辑工具,在此,非常地感谢那些开发者,谢谢其为我们带来这个好用的工具。
1
2
3
1. 可以消除文件中的空行
选中所有文本,
TextFX--->Edit--->Delete Blank lines
1
2
3
4
5
2. 整理xml文本格式
这个功能超好,经常遇到几百KB左右的xml文本就是一行,可以使用
它很快将一行文本整理成规范的xml文件。
选中所有文本
TextFX--->HTML Tidy--->Tidy: Reindent XML
1
2
3
3. 直接在你的文本行前自动添加行号:
选中所有文本
TextFX--->Tools--->Insert Line Numbers
4. 可以用来查看16进制格式
5. 有ftp插件,还不错
6. 好像还有一个Explorer插件,没怎么用过
7. 它的函数列表也蛮不错, 常用,至少看java源程序的时候要用到
8. 可以定制外部命令,我有时候用它来编译java源程序 按F6,就有一个定制窗口。
这是我的javac命令: jc5.bat $(FULL_CURRENT_PATH)
下边是我的运行java的命令
rj5.bat $(NAME_PART)
我只要在外边PATH路径上的某个目录里把jc5.bat和rj5.bat设置好就可以使用了。
比如,我在这里把d:/shell添加到PATH环境变量里,里边可以放很多自己喜欢的批处理脚本。
jc5.bat内容大致如下:
jc5.bat
echo off
setlocal
set JAGUAR_JDK15=d:sharedjdk1.5.0_01
set JAVA_HOME=%JAGUAR_JDK15%
set PATH=%JAVA_HOME%bin;%JAVA_HOME%jrebin;%PATH%
set OLD_CLASSPATH=%CLASSPATH%
set CLASSPATH=.;%JAVA_HOME%libdt.jar;
set CLASSPATH=%CLASSPATH%;%JAVA_HOME%libtools.jar;
set CLASSPATH=%CLASSPATH%;%JAVA_HOME%jrelibrt.jar
set CLASSPATH=%CLASSPATH%;%OLD_CLASSPATH%
“%JAVA_HOME%