天天看点

mysql cookbook

转自:http://blogold.chinaunix.net/u/10047/showart_2511711.html

mysql cookbook 2nd cn pdf: http://ishare.iask.sina.com.cn/f/13652605.html?w=][MySQL.Cookbook%28%B5%DA2%B0%E6%29].%28%C3%C0%29%B5%CF%B2%BC%CD%DF.%D6%D0%CE%C4%B0%E6.%C9%A8%C3%E8%B0%E6.pdf.7z

mysql version: >V5.0

mysql V5.1 zh handbook: http://dev.mysql.com/doc/refman/5.1/zh/index.html

examples data: http://www.kitebird.com/mysql-cookbook/downloads-2ed.php

1。使用MYSQL客户端程序

   1.1 建立MYSQL用户帐号:

    GRANT priv_type ON db_name.* TO 'username'@'ip or hostname' IDENTIFIED BY 'password'

   1.2 建库和表

     create database dbname;

     create table tablename (volum1 type,volum2 type,...)

   1.3 启动和停止mysql

   1.4 使用可选项文件来指定连接参数,即输入mysql命令即可登录mysql服务器。

       $vi ~usrname/.my.cnf

         [client]

          host    = ip or hostname

          user    = mysqlusername

          password= xxx(若想自己输入,则不写=xxx,即password后留空)

          database=dbname(指定默认登录的库)

         [mysql]

          skip-auto-rehash(关闭TAB键的自动补齐功能,反命令为去掉该句,或者mysql>rehash  或者 mysql>/#)

      $mysql --print-defaults 查看mysql程序从选项文件中读取了哪些选项

      $my_print_defaults client mysql 查看从[client] [mysql]选项中读取了什么

    1.5 保护选项文件:既设置.my.cnf文件的权限

    1.6 混合使用命令行和选项文件参数:如上,为了安全,密码需要手工输入。

        注意:如果命令行和选项文件都有某个参数,命令行的优先级高。

    1.7 找不到mysql时该如何做:即把mysql命令的路径加入环境变量PATH里。

    1.8 发起SQL语句:mysql语句的结尾可以是“;” or  "/g"

    1.9 取消一条部分输入的语句:/c

    1.10 重复和编辑SQL语句:使用mysql内建的输入行编辑能力,既gnu readline. 快捷键类似emacs. linux默认行编辑器也是它。不同VI。

         快捷键:up,down,left,right 方向键

                 ctrl+a 到行首(等于home)  ctrl+e 到行尾(等于end)

                 ctrl+l 清屏

                 backspace  向前删   delete 向后删(=ctrl+d)

    1.11 自动完成数据库和表名的录入:tab键自动补齐

         缺点:若库中有大量表时mysql启动会慢,因为预读的原因。

    1.12 让mysql从文件中读取语句:重定向$ mysql dbname < xxx.sql

                                  或者登录mysql后用命令mysql>source /xxx/yyy/sss.sql

    1.13 让mysql从其他程序读取语句:用管道(pipe) 如导出接着导入另一库:$mysqldump cookbook |mysql -h hostname cookbook

    1.14 一命令行输入所有sql:mysql能从其参数列表中读取语句,使用-e(--execute).多条语句用分号隔开。

         $mysql -e "show tables;select * from mail;"

    1.15 使用拷贝粘贴作为mysql输入源:GUI环境里用。

    1.16 预防查询输出超出屏幕范围:指定分页查看程序参数:在.my.cnf中设置[mysql]参数pager=/usr/bin/less

                                                         或者mysql>/P

                                    反命令是去掉pager参数或者mysql>/n

    1.17 发送查询输出到文件或程序:冲定向mysql的输出或者用管道

    1.18 选择表格或制表符定界的查询输出格式:$mysql -t cookbook <inputfile

    1.19 指定任意的输出列分隔符:使用shell替换功能

                                 $mysql cookbook <inputfile|sed -e "s/TAB/:/g" >outfile

    1.20 生成html或者xml:  $mysql --html -e "select * from mail;"

                           $mysql --xml -e "select * from mail;"

    1.21 在查询输出中禁止列出头部:$mysql --skip-column-name -e "select * from mail;"

                                   等效于:mysql -ss -e "select * from mail;" 即两次指定silent选项。

    1.22 使长输出行更具有可读性:show full columns from limbs /G 即垂直输出

                                 等效于 mysql -E -e "show full columns from limbs;"

    1.23 控制mysql的繁墉级别:echo "show now()"|mysql

                              echo "show now()"|mysql -v

                              echo "show now()"|mysql -vv

                              echo "show now()"|mysql -vvv

                            反命令为:-s

    1.24 记录交互式的mysql会话:mysql --tee=tmp.out cookbook

                                命令行里开启:/T tmp.out

                                命令行里关闭:/t

    1.25 以之前执行的语句创建mysql脚本:读取之前的tee文件。或者查看mysql的历史文件.mysql_history

    1.26 在sql语句中使用用户自定义的变量:在sql语句中给变量赋值语法:@var_name:=value

    1.27 为查询输出行计数:mysql --skip-colum-names -e "select * from mail;"|cat -n

                           等效:mysql>set @n=0;

                                 mysql>select @n :[email protected]+1 as rownum,t from mail;

    1.28 将mysql用作计数器:mysql> select (17+23)/sqrt(64);

    1.29 在shell脚本中使用mysql: 只要为命令提供合适的参数即可。

    备注:windows OS 下的命令行环境:cygwin(cygnus工具)

2。编写基于MYSQL的程序

   2.0 引言即MYSQL客户端API架构

   2.1 连接、选择数据库及断开连接

    不同API不同方法

   2.2 差错

   2.3 编写库文件

    封装语句以提高效率。

   2.4 发起语句并检索结果

   2.5 处理语句中的特殊字符和NULL值

    使用API的占位机制。

   2.6 处理标识符中的特殊字符

   2.7 识别结果集中的null值

   2.8 获取连接参数的技术

   2.9 结论和建议

3。从表中查询数据

   3.0 引言

       这里只是部分SELECT语句的分析,完整的请看《MySQL 5.1参考手册 》http://dev.mysql.com/doc/refman/5.1/zh/index.html

   3.1 指定查询列/从指定列中查询

       select * from tablename;

       select volumn1,volumn2,... from tablename;

   3.2 指定查询行

       select * from tablename where ...

   3.3 格式化显示查询结果

       若不指定列名,则用默认列名作为输出列名。

       若用表达式,则表达式为输出列名。

       若用AS 新名,则新名输出列名。

   3.4 使用列别名来简化程序

       上面用到了表达式来查询,如果引用该表达式结果时写表达式名就比较繁琐,可以用AS 新名来定义个别名。

   3.5 合并多列来构建复合值

        比如查询出username和hostname,现要输出邮件地址形式[email protected]

        用concat(username,'@',hostname) as mailadd

   3.6 where表达式中的列别名

        mysql是无法执行的。会报错。解决方法就是在where中用原名或原表达式。

   3.7 调试比较表达式

        即在sql语句中把原值和查询结果一起输出,既可调试。

   3.8 使查询结果唯一化

        关键字:distinct

        mysql内部帮助里如何查看所有函数?

   3.9 如何处理null值: 比较操作null

        is null  

        is not null

   3.10 在用户程序中使用null作为比较参数

        根据不同的语言有不同的方法

   3.11 结果集排序

         order by 字段 (默认升序,加desc后降序)

   3.12 使用视图来简化查询

        视图不同临时表(临时表是存在的表,可以执行表的各种操作,不过是临时工而已),不存在表,只是封包了一堆语句而已。

        create view view_name as select t as t-time,srcuser as user,srchost as host from mail;

        select user,host from view_name;

   3.13 多表查询:使用join(联合),或者子查询。

        select volumn1,volumn2,... from tablename1 inner join talbename2 on 条件1=条件2

        from字句指定了要查询的表。

        on字句指定了两个表的行的绑定规则。

   3.14 从查询结果集头或尾取出部分行

        limit N: 获得查询结果的头N行

   3.15 在结果集中间选取部分行

        limit n,m:获得从n开始(不含n)的m-n行。

   3.16 选择合适的limit参数

        即当有多个相同值时limit会显示不全,应该配合order by desc排序,distinct唯一来组合操作。

   3.17 当HTML需要“错误”的排列顺序时做什么。

         limint的灵活使用。

   3.18 从表达式中计算limit值

        limit只能接收1到2个数字(可以直接是数字,也可以是变量)参数,不能接受表达式。

4。表管理

   4.1 克隆表

        克隆表结构: create table new_table_name like old_table_name

        克隆部分或全部数据:insert into new_table_name select * from old_table_name where ...

   4.2 将查询结果保存到表中

        一步完成:create table new_table_name select * from old_table_name;

        根据实际需求,调整SELECT语句,即可实现按要求的保存。

   4.3 使用临时表(temporary,即临时,和mysql服务器的连接关闭后该类表即被自动删除)

        普通的临时表:create temporary table new_table_name (列定义);

        克隆表结构:create temporary table new_table_name like old_table_name;

        根据查询结果建表:create temporary table new_table_name select ...;

        注意:临时表名不可和普通表同名;

              若有连接池的API程序用临时表,建前最好先写删除语句:drop temporary table if exists new_table_name

   4.4 检查或修改某个表的存储引擎

         检测:select engine from information_schema.tables where table_name like 'table_name';

               show table status like 'table_name';

               show create table table_name;

         修改:alter table table_name engine=引擎名(myisam  innodb  bdb...)

   4.5 生成唯一的表名的方法:

         使用temporary表;

         使用随机数;

         使用PID;

         使用连接ID;

5。与字符串共舞

   5.0 引言

       字符串分两类:二进制 binary  varbinary blob: 存储原始数据

                 非二进制 char  varchar text:存储字符数据

   5.1 字符串属性

       属性之一就是二进制和非二进制

   5.2 选择字符串的数据类型

       原则:是否是二进制数据?

             大小写是否敏感?

             最大长度?

             定长还是变长?

             尾部空格是否保留?

             是否有固定的允许值集合?

   5.3 正确设置客户端连接的字符集

        方法:编辑.my.cnf,添加:[mysql] /n default-character-set=utf8

              建立连接后设置 mysql>set names 'utf8';    

                     or一并设置校对规则   mysql>set names 'utf8' collate 'utf8-general-c1';

              其他编程语言自己的设置方法。

   5.4 串字母

        方法:单双引号或者组合后把字母括起来

              用反斜线转义

              用十六进制。

   5.5 检查一个字符串的字符集charset()或字符排序collation(),即在字符集内用于比较字符的一套规则。

       函数:charset() 检查字符集;  collation() 检查排序规则

             mysql>select charset('abc') collation('abc')

   5.6 改变字符串的字符集或字符排序

       函数:convert(@var using utf8) 转换字符串的字符集

       操作符:collate 新的排序规则名location

   5.7 更改字符串字母的大小写

       函数:upper('abc')  upper(列名)

       函数:lower('ABC')  lower(列名)

   5.8 更改字符串字母的大小写失败的情况(和mysql版本有关系)

       原因:字符串为二进制,如binary  blob

       方法:转换为非二进制后再转换

   5.9 控制字符串比较中的大小写敏感

       使用比较操字符。根据需要来选择是否敏感

   5.10 使用SQL模式进行模式匹配

      操作符: like+正则表达式 %abc  abc% __abc% %abc%    

               not like+正则表达式 %abc  abc% __abc% %abc%

   5.11 使用正在表达式进行模式匹配

       ^   匹配字符串的开始部分

       $   匹配字符串的结尾部分

       .   匹配任何字符(包括回车和新行)

       [...]  括号内任意一个字符

       [^...] 除了括号内字符的任意一个字符

       p1|p2|p3 三者中的任意一个

       *    匹配0个或多个*之前的任何序列

       +    匹配1个或多个+之前的任何序列

       {n}  n个{n}前面的任何序列

       {m,n} 最少m个,最多n个{m,n}之前的任何序列

    5.12 模式匹配中的大小写问题

        方法:更改字符串属性,决定其在匹配过程中是否大小写敏感

              mysql默认大小写不敏感。因为字符集是latin1,比较排序为latin1_swedish_ci

    5.13 分割或者串联字符串

          分割函数:left(列名,n)

                    mid(列名,m,n)

                    right(列名,n)

                    substring(列名,n) 返回“从n开始到右结尾”的所有字符

                    substring_index(列名,c,n) 返回“从左侧查找字符c第n次出现的位置,从该位置开始到右结尾”的所有字符

                    concat() 把该函数参数全部串联起来。

   5.14 查询字符串

          函数:LOCATE('abc',name,3)从第三个字符开始查找子字符串出现的第一个位置。

   5.15 使用FULLTEXT查询:对大量文本进行查询

        优点:速度快。老SQL方法也能实现,但速度慢。

         方法:给表加上FULLTEXT索引 alter table kjv add fulltext(vtext);

               用match()函数指定索引列和用against()函数指定查询关键字:select count(*) from kjv where match(vtext) against('Mizraim');

   5.16 用短语来进行FULLTEXT查询

   5.17 要求或禁止FULLTEXT搜索单词

   5.18  用FULLTEXT索引来执行词组查询

6。使用日期和时间

   6.0

   6.1 选择合适的日期或者时间变量类型

       考虑:保存时间、日期 或者时间+日期

             起止范围是什么

             是否需要库自动为其初始化。

        DATE类型:保存日期 1000-01-01~9999-12-31

        TIME类型:保存时间 -838:59:59~838:59:59

        DATETIME类型:同时保存日期和时间值 1000-01-01 00:00:00~9999-12-31 23:59:59。

        TIMESTAMP类型:同时保存日期和时间值 1970-01-01 00:00:00~2037-12-31 23:59:59。

   6.2 修改Mysql中的日期格式

       mysql始终只能使用ISO格式的日期来保存和显示。

       方法:将非ISO格式的重写为ISO格式的来保存。

              用DATE_FORMAT(datetime,format)函数将其从ISO格式转换为其他格式显示。

        格式化字符:%Y %y %M %m %D %d 类似UNIX/LINUX系统时间格式。

   6.3 设置客户端时区

        若MYSQL服务器和客户端不在同一时区时需注意:双方按自己的时区来保存显示。

        服务器参数:--default-time-zone

   6.4 获取当前日期或时间

       获取客户端日期或时间: curdate()  curtime() now()

       获取当前utc日期或时间: utc_date() utc_time() utc_timestamp()

   6.5 使用TIMESTAMP(时间戳)来跟踪行修改时间

       方法:使用TIMESTAMP数据类型即可,如果不INSERT进值,它会自动初始化和自动更新的特性。

   6.6 从日期或者时间值中分解出各部分值

       方法:使用特定函数,如YEAR() MONTH() HOUR()MINUTE()SECOND()

             使用格式化函数 DATE_FORMAT()  TIME_FORMAT()

             当作字符串,用LEFT() MID()等函数。

   6.7 合成日期或者时间值

       方法:使用maketime(14,47,00)函数组合时分秒

             使用date_format() 或者time_format()来替换

             使用分解函数+concat()函数

   6.8 在时间数据类型和基本单位间进行转换

        方法:时间和秒间转换 time_to_sec()  sec_to_time()

              日期和天间转换 to_days() from_days()

              在timestamp or datetime类型值和秒间转换,用unix_timestamp() from_unixtime()

   6.9 计算两个日期和时间之间的间隔

         方法:时间差函数:datediff()

               双方都换算成天或者秒,求差后再换算。

   6.10 增加日期或时间值

         方法:使用时间加法函数

               使用+internal or -internal函数

                转换为基本计时单位,然后求和

   6.11 计算年龄

         方法:使用timestampdiff(单位(一般为YEAR),出生日期,当前日期(可用curdate()获得)

   6.12 将一个日期和时间值切换到另一个时区

        方法:conver-tz('源时间','源时区','目标时区')

              如SELECT CONVERT_TZ('2004-01-01 12:00:00','+00:00','+10:00');

   6.13 找出每月的第一天,最后一天或者天数

         第一天:将日期后移dayofmonth(t)-1 day:select t,date_sub(t,interval dayofmonth(t)-1 day)  from mail;

         最后一天:last_day()

         天数:dayofmonth(last_day(date))

   6.14 通过子串替换来计算日期

         把源日期当作字符串,替换后产生新的日期

   6.15 计算某个日期为星期几

         函数:dayname()

   6.16 查出给定的某周的某天的日期

   6.17 执行闰年计算

        闰年符合的条件:必须能够被4整除

                        世纪元年除非同时能被400整除,不能用被100整除来判断。

   6.18 接近但不是ISO格式的日期格式

   6.19 将日期或时间当成数值

        时间转化为数值形式:在时间后加0,或者在一个数值上下文中使用时间值

   6.20 强制mysql将字符串当作时间值

   6.21 基于时间特性来查询行

        即在WHERE语句中使用日期或时间条件。

7。排序查询结果

   7.0 引言 排序的目的:使查询结果有序并便于理解和检查

   7.1 使用order by(按。。。排序)命令排序查询结果

       数据默认查询会乱序的原因:存储数据是服务器的工作,不一定就是顺序的;且数据的增删改操作会打乱原来的索引顺序。

                                 所以每次查询出的数据顺序可能不一样,特别是数据变动后。

       要求:现实需求就是要查询输出有序数据,这样才符合人类的习惯。

       方法:查询时指定排序和排序规则;即order by

       order by特性:可以使用单独一列或多列来排序。

                    默认是升序,也可以降序(DESC)。

                    可以使用别名来排序

                    只有用order by指定的列才会排序;否则列是乱序的。

    7.2 使用表达式排序

        可以使用表达式来排序。

    7.3 显示一组按照其他属性排序的值

        即按照改变了数据类型的列来排序。比如输出的是数值,但按“改变数值为字母”后字母来排序。                                    

    7.4 字符串排序的大小写区分控制(数据库的字段类型的collation问题。不过实际使用中使用数据库默认的即可,或者指定一个以后就一直使用)

        方法:改变被排序数值的比较特征

        注意:二进制字符串是二进制序列,通过每个字节的数字值比较来实现。

              非二进制字符串是collation列,通过预先定义的collation顺序来实现字符和字符的对比。

              如果需要改变collation,则例: select name from mail order by name collate latin1_general_cs;

    7.5 基于日期的排序

        使用日期或时间数据类型排序即可。

    7.6 按日历排序

        用函数把日历中的需要排序的分解出即可。

        month() dayofmonth() dayofyear()

    7.7 按周历排序

        函数: dayofweek() 该函数mysql默认按周日 周一 周二。。。排序)

              mod()转换函数  mod(dayofweek(date)+5,7)=monday,....

       weekday() 周一为0,周二尾1,。。。(这个比较实用,符合常理)

    7.8 按时钟排序

         函数:hour(date) minute(date)  second(date)

               time_to_sec(date)

    7.9 按数据列的子串排序

        用函数提取后排序

    7.10 按固定长度的子串排序

        用函数提取后排序:left()  mid() right()

    7.11 按可变长度的子串排序

        substring()  char_length()

    7.12 按域名顺序排列主机名

         将主机名拆分,且将拆分部分从右到左排序

    7.13 按照数字顺序排序点分式IP地址

         方法:拆分字符串,按数字顺序排序各个数据片

               使用inet_aton()函数,把字符串IP转换为数字。

    7.14 将数值移动到排序结果的头部或尾部

        若为空则放在最大尾部: select val from t order by if(val is null,1,0),val

        若为空则放在最小头部: select val from t order by if(val is null,0,1),val

    7.15 按照用户定义排序

          函数:field(value,str1,str2,str3,str4) value会和这四个值比较,返回1or2or3or4,就看哪个匹配。若无匹配则返回0。

    7.16 排序枚举数值

         enum(枚举)数值不能像其他字符串一样排序。因为enum被认为是字母,但实际上是按数字方式存储的。如果想按字母排序,则用cast()函数转换。

8.生成摘要

8.0 数据库系统不仅能存储和查询数据,还可以以更简要的方式生成摘要。

8.1 使用COUNT函数生成摘要

    缺点:大表的话速度会慢。

    弥补方法(Version>=5.0):

            select table_rows from information_schema.tables where

               table_schema='cookbook' and table_name='states';

       or   show table status;

8.2 使用MIN()和MAX()函数生成摘要

8.3 使用SUM()和AVG()数字函数生成摘要

8.4 使用DISTINCT函数消除重复

    使用COUNT(DISTINCT)来计数

8.5 查找数值相关的最大值和最小值

    把MIX MAX函数用在子查询中。

8.6 控制MIN MAX函数的字符串大小写区分

8.7 将摘要划分为子群

    使用GROUP BY来分组

8.8 摘要与空值

    大部分聚类函数忽略NULL值

8.9 使用确定的特性选择组群(即只要部分聚类之后的数据)

    比如:SELECT COUNT(*),NAME FROM MAIL GROUP BY NAME HAVING COUNT(*)>3;

8.10 使用计数确定数值是否唯一

     联合使用HAVING COUNT函数来确认是否唯一

8.11 使用表达式结果分组

     将表达式方到GROUP BY 子句中。

8.12 分类无类别的数据

     使用GROUP BY+表达式将这些数值分组

8.13 控制摘要显示顺序

     GROUP BY + ORDER BY

8.14 查找最小或最大的摘要数值

     在语句中增加LIMIT子句

8.15 基于日期的摘要

8.16 同时使用每一组的摘要和全体的摘要

     使用WITH ROLLUP函数在group by最后一行来汇总所有的摘要

8.17 生成包括摘要和列表的报告

9 获取和使用元数据

9.0 引言

   元数据用来处理结果集的关系、表和库的信息、MYSQL服务器的信息。

   方法:用INFORMATION_SCHEMA库,里面有下列信息:数据库、表、列、字符集  

         用SHOW语句

9.1 获取受语句影响的数据行数目

    有的发起语句的函数会返回行数;

    有的需要自己调用单独函数返回。各种API语言不同。

9.2 获取设置元数据的结果

    各种API语言不同。

9.3 确定一条语句是否生成了结果集

   检查元数据中的数据列计数。若为0则无结果集。

9.4 使用元数据来格式化查询输出

9.5 列举或检查数据库或表的扩展

    INFORMATION_SCHEMA库中:SCHEMATA表里是库信息;TABLES表里是表信息。

9.6 访问表数据列定义

    即看看一张表里有那些列以及如何定义的。

    方法:从INFORMATION_SCHEMA的COLUMNS表里查询。

          用SHOW COLUMNS。

          用SHOW CREATE TABLE或MYSQLDUMP语句来显示表结构的CREATE TABLE语句。

9.7 获取ENUM和SET数据列信息

9.8 在应用程序中使用表结构信息

9.9 获取服务器元数据

    select version()

    select database()

    select user()

    select current_user()

    show global status

    show variables

9.10 编写适合MYSQL服务器版本的应用程序

9.11 确定默认数据库

      DATABASE()

9.12 监测MYSQL服务器

     SHOW VARIABLES

     SHOW STATUS

9.13 确定服务器支持哪个存储引擎

     show engines

10。数据导入和导出

  10.0引言:即不同格式数据的导入导出方法

 mysql原生工具集:导入 load data ; mysqlimport

                         导出 select ..into outfile;mysqldump

        导入的基本问题:

  记录分隔符;

  域定界符;

  列的顺序和数目;

  数据值是否需要进行验证或重新格式化;

  null或空值如何处理。

 导出的基本问题相反:

 文件格式:(常用的两类)制表定界格式和逗号定界(CSV)格式

 10.1 使用LOAD DATA和mysqlimport导入数据(insert.txt里字段分隔符为制表符,即TAB,记录符是换行/r)

 load data local infile '../../mail.txt' into table table_name;

        mysqlimport --local cookbook mail.txt

  10.2 指定数据文件位置

  load data --local指数据文件在服务器本地。

        load data 无local则按默认规则查找数据文件:

  若给绝对路径则直接读取。

  若给的是相对路径则从MYSQL默认库的数据目录下找。     

  10.3 指定数据文件的结构(即不是默认的字段符和记录分隔符)

  使用FIELDS和lines字句告诉load data如何解释数据文件。

  load data local infile 'mail.txt' into table mail /

   fields terminated by ':'/

   lines terminated by '/r';

            or  mysqlimport --local --fields-terminated-by=":" --line-terminated-by="/r" cookbook mail.txt

  10.4 处理引号和特殊字符

 要显示地表示引用字符,用ENCLOSED BY 。

 要改变默认的转义字符,用ESCAPED BY。

  10.5 导入CSV文件

  load data local infile 'mail.txt' into table mail /

   fields terminated by ','/

   lines terminated by '/r/n';

            or  mysqlimport --local --fields-terminated-by="," --line-terminated-by="/r/n" cookbook mail.txt

  10.6 读取不同操作系统的文件

 unix: lines terminated by '/n';

 windows: lines terminated by '/r/n';

  10.7 处理重复的键值(即原表里有重复数据时如何处理;否则会报错)

 覆盖: load data local infile 'mail.txt' replace into table mail;

 忽略:  load data local infile 'mail.txt' ignore into table mail;

  10.8 获取关于错误输入数据的诊断信息

       SHOW WARNINGS

  10.9 跳过数据文件行(即跳过开头的几行)

 load data local infile 'mail.txt' into table mail ignore 3 lines;

  10.10 指定输入列顺序

 如原表列顺序为a b c,而mail.txt里内容对应列顺序为b c a

  load data local infile 'mail.txt' into table mail (b,c,a)

  mysqlimport --local --columns=b,c,a cookbook mail.txt

  10.11 在插入输入值之前对数据文件进行预处理

 预处理用:用SET分开的一个或多个col_name=expr赋值表达式

  10.12 忽略数据文件列

 若多余的列都在尾部,不管。默认LOAD会忽略它们,因为前面的列都和原库表对上了。

 若多余的列在中间,则在LOAD里指定列表名,即把多余的列指定到变量里,不用这些变量。如:

  load data local infile 'mail.txt' into table mail fileds terminated by ':' (volum1,@dummy,volum2);

    mysqlimport --local --columns="volum1,@dummy,volum2" --fileds-terminated-by=":" cookbook mail.txt

  10.13 从MYSQL中导出查询结果

 select * from mail into outfile '/tmp/out.txt' fileds terminated by ',' lines terminated by '/r/n';

 mysql -e "select * from mail" --skip-column-names cookbook > /tmp/out.txt

  10.14 将表导出为文本文件

        mysqldump --no-create-info --tab=/tmp --fields-terminated-by="," cookbook mail

  10.15 以SQL格式导出表内容或定义

 mysqldump cookbook mail 〉/tmp/mail.sql

 mysqldump cookbook  〉/tmp/cookbook.sql

  10.16 将表或数据库拷贝到另一个服务器

 mysqldump cookbook mail 〉/tmp/mail.sql

 mysql test </tmp/mail.sql

      or mysqldump cookbook mail|mysql -h mysql2.test.com test

      or mysqldump cookbook mail|ssh  mysql2.test.com mysql test

  10.17 编写出自己的导出程序

  10.18 将数据文件从一种格式转化为另一种格式

  10.19 提取和重排数据文件列

  10.20 使用SQL模式来控制错误的输入数据处理

  方法:在客户端检查;

  服务器端设置MYSQL的SQL模式:set sql_mode='mode_value';

  设服务器端置mysql全局模式:set global sql_mod='mode_value';

  10.21 验证并转接数据

  10.22 使用模式匹配来验证数据

  10.23 使用模式来匹配广泛的内容类型

  10.24 使用模式来匹配数值

  10.25 使用模式来匹配日期或时间

  10.26 使用模式来匹配EMAIL地址或URL

  10.27 使用表元数据来验证数据

  10.28 使用一个查找表来验证数据

  10.29 将两个数字的年份值转化为四位形式

  10.30 验证日期和时间合法性

  10.31 编写时间处理工具

  10.32 使用不完整的日期

 mysql能够用0代替确实的部分,以ISO格式表示它们。

  10.33 导入非ISO格式日期值(即导入非CCYY-MM-DD格式)

 load date local infile 'mail.txt' into table mail (name,@date,value) set date=str_to_date(@date,'%m/%d/%y');

  10.34 使用非ISO格式导出日期值

 可以使用别的程序处理导出后的数据;或者用DATE_FORMAT()函数来格式化。

  10.35 导入和导出NULL值

  10.36 根据数据文件猜测表结构

 即有导入的文件但库里无此表。

 方法:自己建表或写程序自动识别并建表。

  10.37 在MYSQL和ACCESS之间交换数据

 方法:ACCESS作为客户端,通过ODBC连接到MYSQL服务器。

 or 自己动手ACCESS-〉TXT-〉MYSQL

  10.38 在mysql和ms excel之间交换数据

  10.39 将输出结果导出为XML

 $mysql --xml -e "select * from mail;"

  10.40 将XML导入到MYSQL

  10.41 尾声

11。生成和使用序列

  11.0 引言

 序列:即按顺序产生的唯一值,代表唯一一个记录。

 使用auto_increment列创建序列。

  11.1 创建一个序列列并生成序列值

 create table mail ( id int unsigned not null auto_increment,primary key(id), name varchar(30)...);

 注意:插入重复的auto_increment列时MYSQL会提示错误;

       auto_increment如被手工指定了值,下面行的auto_increment列会从它开始自增,会有断层序列未被使用。

  11.2 为序列列选择数据类型

 注意: auto_increment只能作用于整数类型数据,如int,bigint,tinyint,smallint,mediumint.

  使用unsigned来避免出现负的auo_increment值。

  使用not null来避免出现null。

  auto_increment列必须能够被索引。因为一个序列存在的目的就是提供一个唯一的标示,故使用primary key;若已经有primary key,则用unique(唯一)索引来确保唯一性。

  11.3 序列生成的行删除的效果

 删除行在不同的引擎下产生不同的结果:

  myisam or innodb引擎会机械单调增加序列号,不会使用已经删除的序列号。

  BDB引擎会自动调整序列行号,可以使用原来的序列号。

  11.4 查询序列值

 方法:select max(id) from mail;

  插入数据后执行select last_insert_id();

  11.5 对一个已有的序列进行重新计数

 情况:序列有断层,想重新计数。

 方法:删除该列后再增加该列。

  alter table mail drop id,add id int unsigned not null auto_increment first;

  11.6 扩展序列列的取值范围(修改表结构)

 方法:设置列的类型为UNSIGNED(可以扩大一倍)

  增大列的数据类型 alter table mail modify id bigint not null auto_increment;

  11.7序列顶部数值的再使用

 使用alter table重置序列计数器

  11.8 确保各行按照给定顺序重编号

  11.9 从某个特定值开始一个序列

 create table mail ( id int unsigned not null auto_increment,primary key(id)) auto_incremnet=100;...

  11.10 序列化一个未序列的表

 修改表结构即可:alter table mail add id int unsigned not null auto_increment,/

     add primary key (id);

  11.11 使用auto_increment栏来创建多重序列

 方法:把auto_increment列和其他列链接起来,使他们都是同一索引的一部分。

  ...primary key (name,id)

 注意:  如上例,ID必须是auto_increment;

         若name里有null值,则应该建立unique(name,id)索引,因为primary key不能有null.

  11.12 管理多重并发auto_increment数值

  11.13 使用auto_increment值将表进行关联

  11.14 将序列生成器用作计数器

 insert into booksales (titles,copies) /

  values('the Greater Trumps',last_insert_id(1))/

  on duplicate key update copies=last_insert_id(cpoies+1);

  11.15 创建循环序列

 使用divisio和modulo操作符生成循环元素

  11.16 按行顺序输出数列查询

12。使用多重表

  12.0 引言 多表间的JOIN:内部连接inner join ;外部链接out join.

  12.1 在表中找到与另一个表中的行相匹配的行

 select * from artist,painting where artist.a_id=painting.a_id;

 select * from artist inner join painting on artist.a_id=painting.a_id;

  若两表的匹配列名字相同且使用=操作符的话,可以用using(使用)来简化:select * from artist inner join painting using(a_id);

  注意:on or using用来匹配多个表;where用来限制哪些连接的行。

 三表内连接:select * from artist as a inner join painting as p on a.a_id=p.a_id inner join states as s on p.state=s.abbrev;

   select artist.name,count(painting.price),sum(painting.price),avg(painting.price) from artist inner join painting on artist.a_id=painting.a_id group by artist.name;

 内连接缺点:只能显示某个表中与其它表的值相匹配的值产生结果。

      当要比较的列未被索引的时候速度慢。

  12.2 查找与其它表不匹配的行

 使用外部链接:LEFT JOIN;RIGHT JOIN

 select artist.* from artist left join painting on artist.a_id = painting.a_id where painting.a_id IS NULL;

 select artist.* from painting right join artist on painting.a_id=artist.a_id where painting.a_id is null;

  12.3 将表与自身进行比较

 非JOIN语句:select a_id,title from painting where a_id=(select distinct a_id from painting where title="The Potato Eaters"

 INNER JOIN语句:select p2.a_id,p2.title from painting as p1 inner join painting as p2 on p1.a_id=p2.a_id where p1.title="The Potato Eaters";

  12.4 产生主从列表和摘要:即一对多

 select p.title,a.name from painting as p inner join artist as a on p.a_id=a.a_id order by p.title,a.name;

  12.5 枚举多对多的关系:既多对多

 select t.name,t.year,t.wins,t.losses,p.name,p.city from euchre_team as t inner join euchre_link as l inner join euchre_player as p on t.id=l.team_id and p.id=l.player_id order by t.year,t.wins DESC,p.name;

 注意:join的表写在一起,最后写on连接表的条件,再用where设置行的条件。这样写思路清晰。

  12.6 查找每组行中含有最大或最小值的行

  12.7 计算队伍排名

 select * from standings1 order by wins-losses DESC;

  12.8 使用连接补全或识别列表的缺口

  12.9 计算连续行的差值

  12.10 发现累计和与动态均值

  12.11 使用连接控制查询输出的顺序

  12.12 在单个查询中整合几个结果集

 使用union(联合)操作符将多个查询结果整合为一个

 注意:union后的结果集列名和列的个数取决于第一个select语句所获得的列名;

  默认情况下,union会消除重复记录,除非union all;

  12.13 识别并删除失配或独立行

 方法:使用LEFT JOIN。

  使用not in子查询:select * from artist  where a_id not in (select a_id from painting);

  12.14 为不同数据库间的表执行连接

 select * from 库名.表名。。。

  12.15 同时使用不同的MYSQL服务器

 方法:使用federated引擎的表,该类表能够使MYSQL服务器访问位于另一个mysql服务器的表。

  or 为每个服务器打开一个独立的连接,然后手动将两个表中的信息结合起来。

  or 拷贝表到另一个服务器后再操作。

  12.16 在程序中引用连接的输出列名称

 方法:在API中,将输出的多列存储到一个根据列名引用列值的数据结构中,再顺序取出显示。

13。统计技术

  13.0 引言

  13.1 计算描述统计

 通过计算一般的描述统计或概要统计特征以描述数据集。

  13.2 分组描述统计即:需要为感测数据中的每个子组生成描述统计

 方法:使用聚集函数,同时用GROUP BY子句将数据排列到合适的组中去。

  13.3 产生频率分布

  13.4 计数缺失值即:数据集合并不完整,你需要找出缺失了多少值。

 计算集合众空值出现的次数

  13.5 计算线性回归和相关系数即:为两个变量计算最小平方回归线或表示它们之间关系强弱的相关系数

 方法:运用摘要函数计算所需要的项。

  13.6 生成随机数

 mysql的rand()函数

  13.7 随机化行集合

 使用order by rand(),如:select name from mail order by rand();

  13.8 从行集合中随机选择条目

 方法:随机排列这些值,然后选择第一个或前几个。

  13.9 分配等级

 方法:确定一种分级方法然后使用该方法将值放入所期望的顺序。

 set @rank=0,@prev_val=null;

 select @rank:=if(@prev_val=score,@rank,@rank+1) as rank,@prev_val:=score as score from t order by score DESC;

14。处理重复项

  14.0引言即处理那些不可接受的重复行。

  14.1防止表中发生重复

 使用primary key  or unique索引

  14.2 处理向表中装载行时出现的重复错误

 使用insert ignore忽略 or replace 覆盖or insert ...on duplicate key update修改.

  14.3 计数和识别重复项

  14.4 从表中消除重复项

 方法: 从表中选择具有唯一性的行并放入第二张表中,用它来替代原始表;

  用ALTER TABLE增加一个唯一性索引;

  用DELETE。。。LIMIT N来删除给定重复行集合中多余的行。

  14.5 从自连接的结果中消除重复

15。执行事务

  15.0 引言

 使用事务原因:现实生活中,防止并发性和完整性的发生。

 事务特性:在事务执行过程中,别的客户端不能更新事务中所使用的数据。防止了并发。

    只有在事务中的语句都执行成功的情况下,它们才作为一个单元被聚合并提交,任何在发生错误前的操作都会被回滚,以保证相关表没有受影响。

  15.1 使用事务存储引擎

 事务引擎:InnoDB  NDB  BDB

 检查本MYSQL是否有支持事务的引擎:show engines;

 | MyISAM     | DEFAULT | Default engine as of MySQL 3.23 with great performance         |

 | MEMORY     | YES     | Hash based, stored in memory, useful for temporary tables      |

 | InnoDB     | YES     | Supports transactions, row-level locking, and foreign keys     |

 | MRG_MYISAM | YES     | Collection of identical MyISAM tables

  15.2 使用SQL执行事务

 使用start transaction(or begin)语句以挂起自动提交模式,然后发出组成事务的语句。若成功则用commit来结束事务。否则rollback回滚。

 缺点:有些语句不能作为事务的一部分,如DROP DATABASE。

  15.3 在程序中执行事务

 若程序语言API提供事务术语则直接使用它;

 若无则使用常用语句发布事务SQL语句,以直接利用普通数据库调用的API。

  事务中的语句连同COMMIT操作被聚合在一个控制结构中;

  若控制结构的状态显示了没有成功执行完毕,那么事务会被回滚。

  15.4 在PERL程序中使用事务

 使用标准DBI事务支持机制。

  15.5 在RUBY程序中使用事务

 使用标准DBI事务支持机制。

  15.6 在PHP程序中使用事务

 使用标准的PEAR DB事务支持机制

  使用autocommit()方法关闭auto-commit模式。在执行语句后,调用commit() or rollback以提交或会滚事务。

  15.7 在python程序中使用事务

 使用标准的DB-API事务支持机制

  15.8 在JAVA程序中使用事务

 使用标准的JDBC事务支持机制。

  15.9 使用事务的替代方法

 无事务的存储引擎,事务的替代方法:如显示地锁定表。

  使用锁来聚合语句:LOCK TABLE和UNLOCK TABLE

  使用重写语句以避免事务:

16。使用存储例程、触发器和事件

   16.0引言

    存储例程(函数和过程procedure [presi:dge]):

        存储函数执行计算并返回值,此返回值可以用于表达式,用法类似RAND()、NOW()等。

        存储过程只执行不需要返回值得计算,不能用于表达式,只能被CALL语句调用。

    触发器:触发器被定义为当表被修改时产生动作的对象。可以用于insert,update delete语句。

    事件:事件是在预定时间执行SQL语句的对象。类似系统里的计划任务。

   16.1 创建复合语句对象

    问题:定义存储例程 触发器 事件时的语句结束符为;,与mysql默认的结束符相同,因此会报错。

    方法:用delimiter(定界符)命令重新定义mysql语句结束符。

    如建函数:mysql>delimiter $$

        create function avg_mail_size (user varchar(8))

        returns float reads sql data

        begin

            if user is null then

                return (select avg(size) from mail);

            else

                return (select avg(size) from mail where srcuser =user);

            end if;

        end;

        $$

           mysql>delimiter ;

           mysql>select avg_mail_size(null),avg_mail_size('barb');

    如建存储过程:

    mysql> delimiter //

    mysql> CREATE PROCEDURE simpleproc (OUT param1 INT)

        -> BEGIN

            ->   SELECT COUNT(*) INTO param1 FROM t;

            -> END;

            -> //

        Query OK, 0 rows affected (0.00 sec)

        mysql> delimiter ;

        mysql> CALL simpleproc(@a);

        Query OK, 0 rows affected (0.00 sec)

        mysql> SELECT @a;

        +------+

        | @a   |

        +------+

        | 3    |

        +------+

        1 row in set (0.00 sec)

   16.2 使用存储函数封装计算

    使用存储函数来隐藏讨厌的计算细节并使之更易执行

   16.3 使用存储过程来“返回”多个值

    存储过程的参数可以有下面三类:IN(进)、OUT(出)、INOUT(可进可出)

    例如:create procedure mail_sender_stats(in user varchar(8),

                        out messages int,

                        out total_size float,

                        out avg_size float)

        ......

   16.4 用触发器来定义动态的默认列值

    CREATE

        [DEFINER = { user | CURRENT_USER }]

        TRIGGER trigger_name trigger_time trigger_event

        ON tbl_name FOR EACH ROW trigger_stmt

   16.5 为其他日期和时间类型模拟TIMESTAMP属性

   16.6 使用触发器记录表的变化

    例子(拍卖表)

    create table auction

    (

    id int unsigned not null auto_increment,

    ts timestamp,

    item varchar(30) not null,

    bid decimal(10,2) not null,

    primary key(id)

    );

    为了监测该表所以行的变化,建立日志表,使用触发器记录,如下:

    create table auction_log

    (

    action enmu('create','update','delete'),

    id int unsigned not null,

    ts timestamp,

    item varchar(30) not null,

    bid decimal(10,2) not null,

    index (id)

    );

    create trigger ai_auction after insert on auction for each row

        begin

        insert into auction_log (action,id,ts,item,bid) values('create',new.id,now(),new.item,new.bid);

        end

    create trigger au_auction after insert on auction for each row

        begin

        insert into auction_log (action,id,ts,item,bid) values('update',new.id,now(),new.item,new.bid);

        end

    create trigger ad_auction after insert on auction for each row

        begin

        insert into auction_log (action,id,ts,item,bid) values('delete',old.id,old.ts,old.item,old.bid);

        end        

   16.7 使用事件(event即定时器) 调度数据库动作

    即创建周期性运行的数据库操作,不需要用户交互。

    方法:创建根据计划执行的事件。

        create event event_name on schedule every 5 minute do insert into table_name(volum) values('...');

    检查事件状态:show variables like 'event_scheduler';

    手工激活事件:set global event_scheduler=1;

    永久激活事件: vi my.cnf

            [mysqld]

            event_scheduler=1

    删除事件:drop event event_name;

    停止事件:alter event event_name disable;

    重新激活事件:alter event event_name enable;

17。关于WEB应用中的MYSQL介绍

   17.0引言

   17.1 WEB页面产生的基本原则

    即从教本中产生WEB页面,而不是手工编写。

   17.2 使用APACHE运行WEB脚本

    使用APACHE的cgi-bin执行脚本。

   17.3 使用TOMCAT运行WEB脚本

    使用JSP符号来编写程序,在一个如TOMCAT的servlet容器中执行它。

   17.4 在WEB中输出编码特殊字符

    使用由你的API提供的方法来执行HTML编码和URL编码

18。在WEB页面中混合查询结果 (不同的开发语言不同的方法)

   18.0 引言 即格式化(段落、列表、表格、超链接、导航索引)输出数据

   18.1 以段落文本显示查询结果

   18.2 以列表形式显示查询结果

   18.3 以表格形式显示查询结果

   18.4 将查询结果显示为超链接

   18.5 根据数据库内容创建导航索引

   18.6 存储图片或其他二进制数据

    使用LOAD_FILE()函数存储图片

    使用脚本存储图片

   18.7 检索图片或其他二进制数据

   18.8 提供标语广告

   18.9 提供可下载的查询结果

   18.10 使用模板系统生成WEB页面

    如ruby的pagetemplate和php的smarty。

19 。用MYSQL处理WEB输入

   19.0引言

   19.1 编写脚本生成WEB表单

    使用WEB表单 <form> </form>

   19.2 根据数据库内容构建表单元素

   19.3 根据数据库内容构建多取表单元素

   19.4 将一条数据库记录导入表单

   19.5 收集WEB输入

   19.6 验证WEB输入

   19.7 将WEB输入存入数据库

    sql注入式攻击的结果:mysql服务器额外的负载;

                当脚本尝试消化从MYSQL中返回的结果集时,会引发内存溢出问题;

                当脚本把结果发送给客户端时,消耗额外的网络带宽。

   19.8 处理文件上传

   19.9 执行搜索并显示结果

   19.10 生成上一页和下一页链接

   19.11 生成点击排序的表格头单元

   19.12 WEB页面访问计数

   19.13 WEB页面访问日志

   19.14 使用mysql存储apache日志

20。使用基于MYSQL的WEB会话管理

   20.0 引言

    会话管理问题:

        客户端cookies;

        服务器端cookies;

   20.1 在PERL应用程序中使用基于MYSQL的会话

    perl模块: apache::session

   20.2 在ruby应用程序中使用基于mysql的存储

    ruby模块: CGI:sesson

   20.3 在PHP会话管理器中使用基于mysql的存储

    默认php使用临时文件来备份存储

   20.4 在TOMCAT中为会话支持存储使用mysql

    配置server.xml文件来设置jdbc参数。

继续阅读