﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-semovy-文章分类-My SQL数据库方面</title><link>http://www.blogjava.net/WshmAndLily/category/12010.html</link><description /><language>zh-cn</language><lastBuildDate>Thu, 10 Jan 2008 08:38:18 GMT</lastBuildDate><pubDate>Thu, 10 Jan 2008 08:38:18 GMT</pubDate><ttl>60</ttl><item><title>mysql项目sql schema</title><link>http://www.blogjava.net/WshmAndLily/articles/173440.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Mon, 07 Jan 2008 12:08:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/173440.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/173440.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/173440.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/173440.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/173440.html</trackback:ping><description><![CDATA[<p>###########################################<br />
#### teckotooling database schema #########<br />
###########################################</p>
<p>set names 'gbk';<br />
drop database if exists teckotooling;<br />
create database teckotooling <br />
&nbsp;character set utf8<br />
&nbsp;collate utf8_general_ci;<br />
use teckotooling;<br />
#页面表<br />
create table page<br />
(<br />
&nbsp;page_id int(11) not null primary key auto_increment,<br />
&nbsp;page_name varchar(12) not null unique key,<br />
&nbsp;title_en varchar(128) default '',<br />
&nbsp;title_cn varchar(128) default '',<br />
&nbsp;title_hk varchar(128) default '',<br />
&nbsp;keyword_en varchar(128) default '',<br />
&nbsp;keyword_cn varchar(128) default '',<br />
&nbsp;keyword_hk varchar(128) default '',&nbsp;<br />
&nbsp;title_content_en varchar(64) default '',<br />
&nbsp;title_content_cn varchar(64) default '',<br />
&nbsp;title_content_hk varchar(64) default '',<br />
&nbsp;content_en text default '',<br />
&nbsp;content_cn text default '',<br />
&nbsp;content_hk text default '',&nbsp;<br />
&nbsp;readTimes int(11)&nbsp;default 0<br />
)engine=innodb default charset=utf8;<br />
#类别系列类<br />
create table category<br />
(<br />
&nbsp;category_id int(11) not null primary key auto_increment,<br />
&nbsp;categoryName_en varchar(64) not null unique key,<br />
&nbsp;categoryName_cn varchar(64) not null unique key,<br />
&nbsp;categoryName_hk varchar(64) not null unique key,<br />
&nbsp;description_en text default '',<br />
&nbsp;description_cn text default '',<br />
&nbsp;description_hk text default '',<br />
&nbsp;img varchar(32)<br />
)engine=innodb default charset=utf8;<br />
#项目表<br />
create table item<br />
(<br />
&nbsp;item_id int(11) not null primary key auto_increment,<br />
&nbsp;item_no varchar(6) not null unique key,<br />
&nbsp;category_id int(11) not null ,<br />
&nbsp;itemName_en varchar(64) not null unique key,<br />
&nbsp;itemName_cn varchar(64) not null unique key,<br />
&nbsp;itemName_hk varchar(64) not null unique key,<br />
&nbsp;img varchar(64),<br />
&nbsp;publishedDt timestamp,<br />
&nbsp;lastOne char(1) default 'n',<br />
&nbsp;visible char(1) default 'y',<br />
&nbsp;readTimes int(11)&nbsp;<br />
)engine=innodb default charset=utf8;<br />
#基本文本属性表<br />
create table basicInfoText<br />
(<br />
&nbsp;id int(11) not null primary key auto_increment,<br />
&nbsp;item_id int(11) not null,<br />
&nbsp;propertyName_en varchar(128) not null,<br />
&nbsp;propertyName_cn varchar(128) not null,<br />
&nbsp;propertyName_hk varchar(128) not null,<br />
&nbsp;propertyValue_en varchar(256) default '',<br />
&nbsp;propertyValue_cn varchar(256) default '',<br />
&nbsp;propertyValue_hk varchar(256) default '',<br />
&nbsp;unit_en varchar(32) default '',<br />
&nbsp;unit_cn varchar(32) default '',<br />
&nbsp;unit_hk varchar(32) default '',<br />
&nbsp;visible char(1) default 'y'<br />
)engine=innodb default charset=utf8;<br />
#基本图片属性表<br />
create table basicInfoImg<br />
(<br />
&nbsp;id int(11) not null primary key auto_increment,<br />
&nbsp;item_id int(11) not null ,<br />
&nbsp;imgName_en varchar(64),<br />
&nbsp;imgName_cn varchar(64),<br />
&nbsp;imgName_hk varchar(64),<br />
&nbsp;imgUrl varchar(64),<br />
&nbsp;visible char(1) default 'y'<br />
)engine=innodb default charset=utf8;<br />
#基本图片属性表<br />
create table basicInfoDoc<br />
(<br />
&nbsp;id int(11) not null primary key auto_increment,<br />
&nbsp;item_id int(11) not null ,<br />
&nbsp;docName_en varchar(128),<br />
&nbsp;docName_cn varchar(128),<br />
&nbsp;docName_hk varchar(128),<br />
&nbsp;docUrl varchar(64),<br />
&nbsp;size varchar(16) default '',<br />
&nbsp;contentType varchar(32) default '',<br />
&nbsp;readTimes int(11),<br />
&nbsp;enable char(1) default 'y',<br />
&nbsp;password varchar(32),<br />
&nbsp;visible char(1) default 'y'<br />
)engine=innodb default charset=utf8;<br />
#详细属性表<br />
create table advancedInfo<br />
(<br />
&nbsp;id int(11) not null primary key auto_increment,<br />
&nbsp;item_id int(11) not null ,<br />
&nbsp;content_en longText,<br />
&nbsp;content_cn longText,<br />
&nbsp;content_hk longText,<br />
&nbsp;visible char(1) default 'y'<br />
)engine=innodb default charset=utf8;<br />
#评论表<br />
create table comment<br />
(<br />
&nbsp;id int(11) not null primary key auto_increment,<br />
&nbsp;item_id int(11) not null ,<br />
&nbsp;commenter varchar(32) not null,<br />
&nbsp;dateTime timestamp,<br />
&nbsp;content longText default '',<br />
&nbsp;visible char(1) default 'y'<br />
)engine=innodb default charset=utf8;<br />
#留言表<br />
create table leadWord<br />
(<br />
&nbsp;id int(11) not null primary key auto_increment,<br />
&nbsp;leadWorder varchar(32) not null,<br />
&nbsp;dateTime timestamp,<br />
&nbsp;content longText default '',<br />
&nbsp;visible char(1) default 'y'<br />
)engine=innodb default charset=utf8;<br />
#创建其它设置表<br />
create table otherConfig<br />
(<br />
&nbsp;id int(11) not null primary key,<br />
&nbsp;enablePress char(1) default 'y',<br />
&nbsp;isImagePress char(1) default 'y',<br />
&nbsp;textPress varchar(32) default '',<br />
&nbsp;imagePress varchar(32) default '',<br />
&nbsp;userFaceStyle varchar(32) default '',<br />
&nbsp;afficheEn longText default '',<br />
&nbsp;afficheCn longText default '',<br />
&nbsp;afficheHk longText default ''&nbsp;&nbsp;<br />
);<br />
#用户表<br />
create table user<br />
(<br />
&nbsp;user_id int(11) not null primary key auto_increment,<br />
&nbsp;user_name varchar(32) not null,<br />
&nbsp;password varchar(32),<br />
&nbsp;ENABLED tinyint(1) not null default 0<br />
)engine=innodb default charset=utf8;<br />
#用户权限表连接表<br />
create table user_auth<br />
(<br />
&nbsp;user_id int(11) not null,<br />
&nbsp;auth_id int(11) not null,<br />
&nbsp;primary key(user_id,auth_id)<br />
)engine=innodb default charset=utf8;<br />
#创建权限表<br />
create table authority<br />
(<br />
&nbsp;auth_id int(11) not null primary key auto_increment,<br />
&nbsp;authority varchar(255) not null,<br />
&nbsp;auth_type varchar(32) not null,<br />
&nbsp;protected_res varchar(128) not null,<br />
&nbsp;display varchar(64) not null,<br />
&nbsp;note varchar(64) default null<br />
) engine=innodb default charset=utf8;</p>
<p>#参照完整性</p>
<p>#项目参照类别<br />
alter table item <br />
add&nbsp; index&nbsp; index_cat(category_id),<br />
add constraint fk_item_category foreign key (category_id) references&nbsp; category(category_id) on update cascade&nbsp; on delete cascade ;<br />
#项目文本属性参照项目<br />
alter table basicInfoText <br />
add&nbsp; index&nbsp; index_bI(item_id),<br />
add constraint fk_basicInfoText_item foreign key (item_id) references&nbsp; item(item_id) on update cascade&nbsp; on delete cascade ;<br />
#项目图片属性参照项目<br />
alter table basicInfoImg <br />
add&nbsp; index&nbsp; index_bI(item_id),<br />
add constraint&nbsp; fk_basicInfoImg_item foreign key (item_id) references&nbsp; item(item_id) on update cascade&nbsp; on delete cascade ;<br />
#项目文档属性参照项目<br />
alter table basicInfoDoc <br />
add&nbsp; index&nbsp; index_bI(item_id),<br />
add constraint fk_basicInfoDoc_item foreign key (item_id) references&nbsp; item(item_id) on update cascade&nbsp; on delete cascade ;<br />
#项目详细文本参照项目<br />
alter table advancedInfo <br />
add&nbsp; index&nbsp; index_bI(item_id),<br />
add constraint fk_advancedInfo_item foreign key&nbsp; (item_id) references&nbsp; item(item_id) on update cascade&nbsp; on&nbsp; delete cascade ;<br />
#项目详细文本参照项目<br />
alter table comment <br />
add&nbsp; index&nbsp; index_cI(item_id),<br />
add constraint fk_comment_item foreign key&nbsp; (item_id) references&nbsp; item(item_id) on update cascade&nbsp; on&nbsp; delete cascade ;<br />
#权限连接表参照用户表<br />
alter table user_auth <br />
add&nbsp; index&nbsp; index_user(user_id),<br />
add constraint fk_user_auth_user foreign key&nbsp; (user_id) references&nbsp; user(user_id) on update cascade&nbsp; on&nbsp; delete cascade ;<br />
#初始化表</p>
<p>#用户表<br />
insert into user values(1,'admin','21232f297a57a5a743894a0e4a801fc3',1);<br />
#页面表<br />
insert into page<br />
&nbsp;values(1,'home','home','home','home','home','home','home','home','home','home','home','home','home',0),<br />
&nbsp;(2,'about','about','about','about','about','about','about','about','about','about','about','about','about',0),<br />
&nbsp;(3,'product','product','product','product','product','product','product','product','product','product','product','product','product',0),<br />
&nbsp;(4,'services','services','services','services','services','services','services','services','services','services','services','services','services',0),<br />
&nbsp;(5,'contactUs','contactUs','contactUs','contactUs','contactUs','contactUs','contactUs','contactUs','contactUs','contactUs','contactUs','contactUs','contactUs',0);<br />
#其它设置<br />
insert into otherConfig values(1,'y','y','semovy@gmail.com','logo.gif','blue.css','affiche here...','公告在此&#8230;&#8230;','公告在此&#8230;&#8230;');<br />
#初始资源鉴定表<br />
INSERT INTO `authority` (`AUTH_ID`, `AUTHORITY`, `AUTH_TYPE`, `PROTECTED_RES`, `DISPLAY`, `NOTE`) VALUES <br />
&nbsp; #项目资源保护鉴定&nbsp;<br />
&nbsp; (1,'AUTH_FUNC_ItemManager.saveItem','FUNCTION','com.semovy.service.IItemService.saveItem','创建项目',NULL),<br />
&nbsp; (2,'AUTH_FUNC_ItemManager.updateItem','FUNCTION','com.semovy.service.IItemService.updateItem','更新项目',NULL),<br />
&nbsp; (3,'AUTH_FUNC_ItemManager.deleteItemById','FUNCTION','com.semovy.service.IItemService.deleteItemById','删除项目',NULL),<br />
&nbsp; (4,'AUTH_FUNC_ItemManager.outPutXMLItem','FUNCTION','com.semovy.service.IItemService.outPutXMLItem','访问项目管理',NULL),<br />
&nbsp; #页面资源<br />
&nbsp; (5,'AUTH_FUNC_PageManager.updatePage','FUNCTION','com.semovy.service.IPageService.updatePage','修改页面',NULL),<br />
&nbsp; (6,'AUTH_FUNC_PageManager.outPutPageXML','FUNCTION','com.semovy.service.IPageService.outPutPageXML','访问管理页面',NULL),<br />
&nbsp; #其它管理<br />
&nbsp; (7,'AUTH_FUNC_OtherconfigManager.updateOtherconfig','FUNCTION','com.semovy.service.IOtherconfigService.updateOtherconfig','修改其它管理',NULL),<br />
&nbsp; (8,'AUTH_FUNC_OtherconfigManager.outPutOtherconfigXML','FUNCTION','com.semovy.service.IOtherconfigService.outPutOtherconfigXML','访问其它管理',NULL),<br />
&nbsp; #用户管理<br />
&nbsp; (9,'AUTH_FUNC_UserManager.updateUser','FUNCTION','com.semovy.service.IUserService.updateUser','修改用户',NULL),<br />
&nbsp; (10,'AUTH_FUNC_UserManager.outPutUsersListXML','FUNCTION','com.semovy.service.IUserService.outPutUsersListXML','访问用户管理',NULL),<br />
&nbsp; #留言管理<br />
&nbsp; (11,'AUTH_FUNC_LeadwordManager.updateUser','FUNCTION','com.semovy.service.ILeadwordService.updateLeadword','修改留言',NULL),<br />
&nbsp; (12,'AUTH_FUNC_LeadwordManager.outPutUsersListXML','FUNCTION','com.semovy.service.ILeadwordService.deleteLeadwordById','删除一条留言',NULL),&nbsp; <br />
&nbsp; (13,'AUTH_FUNC_LeadwordManager.getLeadWordsOfPageByCriteria','FUNCTION','com.semovy.service.ILeadwordService.getLeadWordsOfPageByCriteria','获取分页留言',NULL),<br />
&nbsp; (14,'AUTH_FUNC_LeadwordManager.outPutXMLLeadword','FUNCTION','com.semovy.service.ILeadwordService.outPutXMLLeadword','访问留言管理',NULL),&nbsp;&nbsp;&nbsp; <br />
&nbsp; #评论管理<br />
&nbsp; (15,'AUTH_FUNC_CommentManager.updateComment','FUNCTION','com.semovy.service.ICommentService.updateComment','修改评论',NULL),<br />
&nbsp; (16,'AUTH_FUNC_CommentManager.deleteCommentById','FUNCTION','com.semovy.service.ICommentService.deleteCommentById','删除一条评论',NULL),&nbsp; <br />
&nbsp; (17,'AUTH_FUNC_CommentManager.outPutXMLComment','FUNCTION','com.semovy.service.ICommentService.outPutXMLComment','访问评论管理',NULL),<br />
&nbsp; #项目基本文本管理<br />
&nbsp; (18,'AUTH_FUNC_BasicinfotextManager.getBasicinfotextById','FUNCTION','com.semovy.service.IBasicinfotextService.getBasicinfotextById','获取一个项目基本文本属性',NULL),<br />
&nbsp; (19,'AUTH_FUNC_BasicinfotextManager.saveBasicinfotext','FUNCTION','com.semovy.service.IBasicinfotextService.saveBasicinfotext','保存项目基本文本属性',NULL),&nbsp; <br />
&nbsp; (20,'AUTH_FUNC_BasicinfotextManager.deleteBasicinfotextById','FUNCTION','com.semovy.service.IBasicinfotextService.deleteBasicinfotextById','删除项目基本文本属性',NULL),<br />
&nbsp; #(21,'AUTH_FUNC_BasicinfotextManager.outPutLocaleUnitXML','FUNCTION','com.semovy.service.IBasicinfotextService.outPutLocaleUnitXML','访问基本文本属性单位',NULL),<br />
&nbsp; (22,'AUTH_FUNC_BasicinfotextManager.outPutBasicinfotextXMLOfItem','FUNCTION','com.semovy.service.IBasicinfotextService.outPutBasicinfotextXMLOfItem','访问基本文本属性管理',NULL),&nbsp;&nbsp;&nbsp; <br />
&nbsp; #项目基本图片管理<br />
&nbsp; (23,'AUTH_FUNC_BasicinfoimgManager.getBasicinfoimgById','FUNCTION','com.semovy.service.IBasicinfoimgService.getBasicinfoimgById','获取一个项目基本图片属性',NULL),<br />
&nbsp; (24,'AUTH_FUNC_BasicinfoimgManager.saveBasicinfoimg','FUNCTION','com.semovy.service.IBasicinfoimgService.saveBasicinfoimg','保存项目基本图片属性',NULL),&nbsp; <br />
&nbsp; (25,'AUTH_FUNC_BasicinfoimgManager.updateBasicinfoimg','FUNCTION','com.semovy.service.IBasicinfoimgService.updateBasicinfoimg','修改项目基本图片属性',NULL),<br />
&nbsp; (26,'AUTH_FUNC_BasicinfoimgManager.deleteBasicinfoimgById','FUNCTION','com.semovy.service.IBasicinfoimgService.deleteBasicinfoimgById','删除基本图片属性',NULL),<br />
&nbsp; (27,'AUTH_FUNC_BasicinfoimgManager.outputBasicinfoimgXML','FUNCTION','com.semovy.service.IBasicinfoimgService.outputBasicinfoimgXML','访问基本图片属性管理',NULL),&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp; #项目基本文档管理<br />
&nbsp; #(28,'AUTH_FUNC_BasicinfodocManager.getBasicinfodocById','FUNCTION','com.semovy.service.IBasicinfodocService.getBasicinfodocById','获取一个项目基本文档属性',NULL),<br />
&nbsp; (29,'AUTH_FUNC_BasicinfodocManager.saveBasicinfodoc','FUNCTION','com.semovy.service.IBasicinfodocService.saveBasicinfodoc','保存项目基本文档属性',NULL),&nbsp; <br />
&nbsp; (30,'AUTH_FUNC_BasicinfodocManager.updateBasicinfodoc','FUNCTION','com.semovy.service.IBasicinfodocService.updateBasicinfodoc','修改项目基本文档属性',NULL),<br />
&nbsp; (31,'AUTH_FUNC_BasicinfodocManager.deleteBasicinfodocById','FUNCTION','com.semovy.service.IBasicinfodocService.deleteBasicinfodocById','删除基本文档属性',NULL),<br />
&nbsp; (32,'AUTH_FUNC_BasicinfodocManager.outputBasicinfodocXML','FUNCTION','com.semovy.service.IBasicinfodocService.outputBasicinfodocXML','访问基本图片文档管理',NULL),&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp; #项目高级文本管理<br />
&nbsp; (33,'AUTH_FUNC_AdvancedinfoManager.getAdvancedinfoById','FUNCTION','com.semovy.service.IAdvancedinfoService.getAdvancedinfoById','获取一个项目高级文本属性',NULL),<br />
&nbsp; (34,'AUTH_FUNC_AdvancedinfoManager.saveAdvancedinfo','FUNCTION','com.semovy.service.IAdvancedinfoService.saveAdvancedinfo','保存项目项目高级文本',NULL),&nbsp; <br />
&nbsp; (35,'AUTH_FUNC_AdvancedinfoManager.updateAdvancedinfo','FUNCTION','com.semovy.service.IAdvancedinfoService.updateAdvancedinfo','修改项目项目高级文本',NULL),<br />
&nbsp; (36,'AUTH_FUNC_AdvancedinfoManager.deleteAdvancedinfoById','FUNCTION','com.semovy.service.IAdvancedinfoService.deleteAdvancedinfoById','删除项目高级文本',NULL),&nbsp; <br />
&nbsp; #项目类别管理<br />
&nbsp; (37,'AUTH_FUNC_CategoryManager.saveCategory','FUNCTION','com.semovy.service.ICategoryService.saveCategory','保存项目类别',NULL),<br />
&nbsp; (38,'AUTH_FUNC_CategoryManager.updateCategory','FUNCTION','com.semovy.service.ICategoryService.updateCategory','修改项目类别',NULL),&nbsp; <br />
&nbsp; (39,'AUTH_FUNC_CategoryManager.deleteCategoryById','FUNCTION','com.semovy.service.ICategoryService.deleteCategoryById','删除项目类别',NULL),<br />
&nbsp; (40,'AUTH_FUNC_CategoryManager.outputCategoriesXML','FUNCTION','com.semovy.service.ICategoryService.outputCategoriesXML','访问管理项目类别',NULL);&nbsp;&nbsp;&nbsp; <br />
#初始化user_auth表<br />
insert into user_auth values<br />
&nbsp;&nbsp; (1,1),<br />
&nbsp;&nbsp; (1,2),<br />
&nbsp;&nbsp; (1,3),&nbsp; <br />
&nbsp;&nbsp; (1,4),<br />
&nbsp;&nbsp; (1,5),<br />
&nbsp;&nbsp; (1,6),&nbsp; <br />
&nbsp;&nbsp; (1,7),<br />
&nbsp;&nbsp; (1,8),<br />
&nbsp;&nbsp; (1,9),&nbsp; <br />
&nbsp;&nbsp; (1,10),<br />
&nbsp;&nbsp; (1,11),<br />
&nbsp;&nbsp; (1,12),&nbsp; <br />
&nbsp;&nbsp; (1,13),<br />
&nbsp;&nbsp; (1,14),<br />
&nbsp;&nbsp; (1,15),&nbsp; <br />
&nbsp;&nbsp; (1,16),<br />
&nbsp;&nbsp; (1,17),<br />
&nbsp;&nbsp; (1,18),&nbsp; <br />
&nbsp;&nbsp; (1,19),<br />
&nbsp;&nbsp; (1,20),<br />
&nbsp;&nbsp; (1,21),&nbsp; <br />
&nbsp;&nbsp; (1,22),<br />
&nbsp;&nbsp; (1,23),<br />
&nbsp;&nbsp; (1,24),&nbsp; <br />
&nbsp;&nbsp; (1,25),<br />
&nbsp;&nbsp; (1,26),<br />
&nbsp;&nbsp; (1,27),&nbsp; <br />
&nbsp;&nbsp; (1,28),<br />
&nbsp;&nbsp; (1,29),<br />
&nbsp;&nbsp; (1,30), <br />
&nbsp;&nbsp; (1,31),&nbsp; <br />
&nbsp;&nbsp; (1,32),<br />
&nbsp;&nbsp; (1,33),<br />
&nbsp;&nbsp; (1,34),&nbsp; <br />
&nbsp;&nbsp; (1,35),<br />
&nbsp;&nbsp; (1,36),<br />
&nbsp;&nbsp; (1,37),&nbsp; <br />
&nbsp;&nbsp; (1,38),<br />
&nbsp;&nbsp; (1,39),<br />
&nbsp;&nbsp; (1,40);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
</p>
<img src ="http://www.blogjava.net/WshmAndLily/aggbug/173440.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2008-01-07 20:08 <a href="http://www.blogjava.net/WshmAndLily/articles/173440.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>mysql 命令</title><link>http://www.blogjava.net/WshmAndLily/articles/173438.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Mon, 07 Jan 2008 12:02:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/173438.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/173438.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/173438.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/173438.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/173438.html</trackback:ping><description><![CDATA[SHOW CREATE TABLE tablename显示创建表的语句.<br />
<br />
desc table显示表的结构<br />
<br />
show tables显示当前数据库的所有表
 <img src ="http://www.blogjava.net/WshmAndLily/aggbug/173438.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2008-01-07 20:02 <a href="http://www.blogjava.net/WshmAndLily/articles/173438.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java备份mysql</title><link>http://www.blogjava.net/WshmAndLily/articles/135022.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Tue, 07 Aug 2007 09:50:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/135022.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/135022.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/135022.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/135022.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/135022.html</trackback:ping><description><![CDATA[首先，设置mysql的环境变量（在path中添加%MYSQL_HOME%\bin），重启电脑。<br>完整代码：<br>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp; &nbsp;* @param args<br>&nbsp;&nbsp;&nbsp; &nbsp;*/<br>&nbsp;&nbsp;&nbsp; public static void main(String[] args) {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /*<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;* 备份和导入是一个互逆的过程。<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;* 备份：程序调用mysql的备份命令，读出控制台输入流信息，写入.sql文件；<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;* 导入：程序调用mysql的导入命令，把从.sql文件中读出的信息写入控制台的输出流<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;* 注意：此时定向符"&gt;"和"&lt;"是不能用的<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;*/<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; backup();<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; load();<br>&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp; &nbsp;* 备份检验一个sql文件是否可以做导入文件用的一个判断方法：把该sql文件分别用记事本和ultra<br>&nbsp;&nbsp;&nbsp; &nbsp;* edit打开，如果看到的中文均正常没有乱码，则可以用来做导入的源文件（不管sql文件的编码格式如何，也不管db的编码格式如何）<br>&nbsp;&nbsp;&nbsp; &nbsp;*/<br>&nbsp;&nbsp;&nbsp; public static void backup() {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; try {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Runtime rt = Runtime.getRuntime();<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 调用 mysql 的 cmd:<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Process child = rt<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; .exec("mysqldump -u root --set-charset=utf8 bjse act_obj");// 设置导出编码为utf8。这里必须是utf8<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 把进程执行中的控制台输出信息写入.sql文件，即生成了备份文件。注：如果不对控制台信息进行读出，则会导致进程堵塞无法运行<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; InputStream in = child.getInputStream();// 控制台的输出信息作为输入流<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; InputStreamReader xx = new InputStreamReader(in, "utf8");// 设置输出流编码为utf8。这里必须是utf8，否则从流中读入的是乱码<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; String inStr;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; StringBuffer sb = new StringBuffer("");<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; String outStr;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 组合控制台输出信息字符串<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BufferedReader br = new BufferedReader(xx);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; while ((inStr = br.readLine()) != null) {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sb.append(inStr + "\r\n");<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; outStr = sb.toString();<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 要用来做导入用的sql目标文件：<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; FileOutputStream fout = new FileOutputStream(<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "e:/mysql-5.0.27-win32/bin/bjse22.sql");<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; OutputStreamWriter writer = new OutputStreamWriter(fout, "utf8");<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; writer.write(outStr);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 注：这里如果用缓冲方式写入文件的话，会导致中文乱码，用flush()方法则可以避免<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; writer.flush();<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 别忘记关闭输入输出流<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; in.close();<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; xx.close();<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; br.close();<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; writer.close();<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fout.close();<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println("/* Output OK! */");<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } catch (Exception e) {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; e.printStackTrace();<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp; &nbsp;* 导入<br>&nbsp;&nbsp;&nbsp; &nbsp;*<br>&nbsp;&nbsp;&nbsp; &nbsp;*/<br>&nbsp;&nbsp;&nbsp; public static void load() {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; try {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; String fPath = "e:/mysql-5.0.27-win32/bin/bjse22.sql";<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Runtime rt = Runtime.getRuntime();<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 调用 mysql 的 cmd:<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Process child = rt.exec("mysql -u root bjse ");<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; OutputStream out = child.getOutputStream();//控制台的输入信息作为输出流<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; String inStr;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; StringBuffer sb = new StringBuffer("");<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; String outStr;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BufferedReader br = new BufferedReader(new InputStreamReader(<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; new FileInputStream(fPath), "utf8"));<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; while ((inStr = br.readLine()) != null) {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sb.append(inStr + "\r\n");<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; outStr = sb.toString();<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; OutputStreamWriter writer = new OutputStreamWriter(out, "utf8");<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; writer.write(outStr);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 注：这里如果用缓冲方式写入文件的话，会导致中文乱码，用flush()方法则可以避免<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; writer.flush();<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 别忘记关闭输入输出流<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; out.close();<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; br.close();<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; writer.close();<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.out.println("/* Load OK! */");<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } catch (Exception e) {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; e.printStackTrace();<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp; }<br>
<img src ="http://www.blogjava.net/WshmAndLily/aggbug/135022.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2007-08-07 17:50 <a href="http://www.blogjava.net/WshmAndLily/articles/135022.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>mysql数据类型</title><link>http://www.blogjava.net/WshmAndLily/articles/130973.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Wed, 18 Jul 2007 02:01:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/130973.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/130973.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/130973.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/130973.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/130973.html</trackback:ping><description><![CDATA[<div>
<h2 align=left>数值类型</h2>
<p align=left>　　MySQL 的数值数据类型可以大致划分为两个类别，一个是整数，另一个是浮点数或小数。许多不同的子类型对这些类别中的每一个都是可用的，每个子类型支持不同大小的数据，并且 MySQL 允许我们指定数值字段中的值是否有正负之分或者用零填补。</p>
<p align=left>　　表列出了各种数值类型以及它们的允许范围和占用的内存空间。</p>
<table style="MARGIN-BOTTOM: 0px; WIDTH: 496px; HEIGHT: 841px" cellSpacing=0 cellPadding=4 width=496 align=center border=1>
    <tbody>
        <tr>
            <td width="10%">
            <div align=left><strong>类型</strong></div>
            </td>
            <td width="15%">
            <div align=left><strong>大小</strong></div>
            </td>
            <td width="30%">
            <div align=left><strong>范围（有符号）</strong></div>
            </td>
            <td width="30%">
            <div align=left><strong>范围（无符号）</strong></div>
            </td>
            <td width="15%">
            <div align=left><strong>用途</strong></div>
            </td>
        </tr>
        <tr>
            <td width="10%">
            <div align=left>TINYINT</div>
            </td>
            <td width="15%">
            <div align=left>1 字节</div>
            </td>
            <td width="30%">
            <div align=left>(-128，127)</div>
            </td>
            <td width="30%">
            <div align=left>(0，255)</div>
            </td>
            <td width="15%">
            <div align=left>小整数值</div>
            </td>
        </tr>
        <tr>
            <td width="10%">
            <div align=left>SMALLINT</div>
            </td>
            <td width="15%">
            <div align=left>2 字节</div>
            </td>
            <td width="30%">
            <div align=left>(-32 768，32 767)</div>
            </td>
            <td width="30%">
            <div align=left>(0，65 535)</div>
            </td>
            <td width="15%">
            <div align=left>大整数值</div>
            </td>
        </tr>
        <tr>
            <td width="10%">
            <div align=left>MEDIUMINT</div>
            </td>
            <td width="15%">
            <div align=left>3 字节</div>
            </td>
            <td width="30%">
            <div align=left>(-8 388 608，8 388 607)</div>
            </td>
            <td width="30%">
            <div align=left>(0，16 777 215)</div>
            </td>
            <td width="15%">
            <div align=left>大整数值</div>
            </td>
        </tr>
        <tr>
            <td width="10%">
            <div align=left>INT或INTEGER</div>
            </td>
            <td width="15%">
            <div align=left>4 字节</div>
            </td>
            <td width="30%">
            <div align=left>(-2 147 483 648，2 147 483 647)</div>
            </td>
            <td width="30%">
            <div align=left>(0，4 294 967 295)</div>
            </td>
            <td width="15%">
            <div align=left>大整数值</div>
            </td>
        </tr>
        <tr>
            <td width="10%">
            <div align=left>BIGINT</div>
            </td>
            <td width="15%">
            <div align=left>8 字节</div>
            </td>
            <td width="30%">
            <div align=left>(-9 233 372 036 854 775 808，9 223 372 036 854 775 807)</div>
            </td>
            <td width="30%">
            <div align=left>(0，18 446 744 073 709 551 615)</div>
            </td>
            <td width="15%">
            <div align=left>极大整数值</div>
            </td>
        </tr>
        <tr>
            <td>
            <div align=left>FLOAT</div>
            </td>
            <td width="15%">
            <div align=left>4 字节</div>
            </td>
            <td width="30%">
            <div align=left>(-3.402 823 466 E+38，1.175 494 351 E-38)，0，(1.175 494 351 E-38，3.402 823 466 351 E+38)</div>
            </td>
            <td width="30%">
            <div align=left>0，(1.175 494 351 E-38，3.402 823 466 E+38)</div>
            </td>
            <td>
            <div align=left>单精度<br>浮点数值</div>
            </td>
        </tr>
        <tr>
            <td>
            <div align=left>DOUBLE</div>
            </td>
            <td width="15%">
            <div align=left>8 字节</div>
            </td>
            <td width="30%">
            <div align=left>(1.797 693 134 862 315 7 E+308，2.225 073 858 507 201 4 E-308)，0，(2.225 073 858 507 201 4 E-308，1.797 693 134 862 315 7 E+308)</div>
            </td>
            <td width="30%">
            <div align=left>0，(2.225 073 858 507 201 4 E-308，1.797 693 134 862 315 7 E+308)</div>
            </td>
            <td>
            <div align=left>双精度<br>浮点数值</div>
            </td>
        </tr>
        <tr>
            <td>
            <div align=left>DECIMAL</div>
            </td>
            <td width="15%">
            <div align=left>对DECIMAL(M,D) ，如果M&gt;D，为M+2否则为D+2</div>
            </td>
            <td width="30%">
            <div align=left>依赖于M和D的值</div>
            </td>
            <td width="30%">
            <div align=left>依赖于M和D的值</div>
            </td>
            <td>
            <div align=left>小数值</div>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<h3 align=left>INT 类型</h3>
<p align=left>　　在 MySQL 中支持的 5 个主要整数类型是 TINYINT，SMALLINT，MEDIUMINT，INT 和 BIGINT。这些类型在很大程度上是相同的，只有它们存储的值的大小是不相同的。</p>
<p align=left>　　MySQL 以一个可选的显示宽度指示器的形式对 SQL 标准进行扩展，这样当从数据库检索一个值时，可以把这个值加长到指定的长度。例如，指定一个字段的类型为 INT(6)，就可以保证所包含数字少于 6 个的值从数据库中检索出来时能够自动地用空格填充。需要注意的是，使用一个宽度指示器不会影响字段的大小和它可以存储的值的范围。</p>
<p align=left>　　万一我们需要对一个字段存储一个超出许可范围的数字，MySQL 会根据允许范围最接近它的一端截短后再进行存储。还有一个比较特别的地方是，MySQL 会在不合规定的值插入表前自动修改为 0。</p>
<p align=left>　　UNSIGNED 修饰符规定字段只保存正值。因为不需要保存数字的正、负符号，可以在储时节约一个&#8220;位&#8221;的空间。从而增大这个字段可以存储的值的范围。</p>
<p align=left>　　ZEROFILL 修饰符规定 0（不是空格）可以用来真补输出的值。使用这个修饰符可以阻止 MySQL 数据库存储负值。</p>
<h3 align=left>FLOAT、DOUBLE 和 DECIMAL 类型</h3>
<p align=left>　　MySQL 支持的三个浮点类型是 FLOAT、DOUBLE 和 DECIMAL 类型。FLOAT 数值类型用于表示单精度浮点数值，而 DOUBLE 数值类型用于表示双精度浮点数值。</p>
<p align=left>　　与整数一样，这些类型也带有附加参数：一个显示宽度指示器和一个小数点指示器。比如语句 FLOAT(7,3) 规定显示的值不会超过 7 位数字，小数点后面带有 3 位数字。</p>
<p align=left>　　对于小数点后面的位数超过允许范围的值，MySQL 会自动将它四舍五入为最接近它的值，再插入它。</p>
<p align=left>　　DECIMAL 数据类型用于精度要求非常高的计算中，这种类型允许指定数值的精度和计数方法作为选择参数。精度在这里指为这个值保存的有效数字的总个数，而计数方法表示小数点后数字的位数。比如语句 DECIMAL(7,3) 规定了存储的值不会超过 7 位数字，并且小数点后不超过 3 位。</p>
<p align=left>　　忽略 DECIMAL 数据类型的精度和计数方法修饰符将会使 MySQL 数据库把所有标识为这个数据类型的字段精度设置为 10，计算方法设置为 0。</p>
<p align=left>　　UNSIGNED 和 ZEROFILL 修饰符也可以被 FLOAT、DOUBLE 和 DECIMAL 数据类型使用。并且效果与 INT 数据类型相同。</p>
<h2 align=left>字符串类型</h2>
<p align=left>　　MySQL 提供了 8 个基本的字符串类型，可以存储的范围从简单的一个字符到巨大的文本块或二进制字符串数据。</p>
<table style="WIDTH: 510px; HEIGHT: 448px" cellSpacing=0 cellPadding=4 width=510 align=center border=1>
    <tbody>
        <tr>
            <td width="20%">
            <div align=left><strong>类型</strong></div>
            </td>
            <td width="25%">
            <div align=left><strong>大小</strong></div>
            </td>
            <td width="55%">
            <div align=left><strong>用途</strong></div>
            </td>
        </tr>
        <tr>
            <td width="20%">
            <div align=left>CHAR</div>
            </td>
            <td width="25%">
            <div align=left>0-255字节</div>
            </td>
            <td width="55%">
            <div align=left>定长字符串</div>
            </td>
        </tr>
        <tr>
            <td width="20%">
            <div align=left>VARCHAR</div>
            </td>
            <td width="25%">
            <div align=left>0-255字节</div>
            </td>
            <td width="55%">
            <div align=left>变长字符串</div>
            </td>
        </tr>
        <tr>
            <td width="20%">
            <div align=left>TINYBLOB</div>
            </td>
            <td width="25%">
            <div align=left>0-255字节</div>
            </td>
            <td width="55%">
            <div align=left>不超过 255 个字符的二进制字符串</div>
            </td>
        </tr>
        <tr>
            <td width="20%">
            <div align=left>TINYTEXT</div>
            </td>
            <td width="25%">
            <div align=left>0-255字节</div>
            </td>
            <td width="55%">
            <div align=left>短文本字符串</div>
            </td>
        </tr>
        <tr>
            <td width="20%">
            <div align=left>BLOB</div>
            </td>
            <td width="25%">
            <div align=left>0-65 535字节</div>
            </td>
            <td width="55%">
            <div align=left>二进制形式的长文本数据</div>
            </td>
        </tr>
        <tr>
            <td width="20%">
            <div align=left>TEXT</div>
            </td>
            <td width="25%">
            <div align=left>0-65 535字节</div>
            </td>
            <td width="55%">
            <div align=left>长文本数据</div>
            </td>
        </tr>
        <tr>
            <td width="20%">
            <div align=left>MEDIUMBLOB</div>
            </td>
            <td width="25%">
            <div align=left>0-16 777 215字节</div>
            </td>
            <td width="55%">
            <div align=left>二进制形式的中等长度文本数据</div>
            </td>
        </tr>
        <tr>
            <td width="20%">
            <div align=left>MEDIUMTEXT</div>
            </td>
            <td width="25%">
            <div align=left>0-16 777 215字节</div>
            </td>
            <td width="55%">
            <div align=left>中等长度文本数据</div>
            </td>
        </tr>
        <tr>
            <td width="20%">
            <div align=left>LOGNGBLOB</div>
            </td>
            <td width="25%">
            <div align=left>0-4 294 967 295字节</div>
            </td>
            <td width="55%">
            <div align=left>二进制形式的极大文本数据</div>
            </td>
        </tr>
        <tr>
            <td width="20%">
            <div align=left>LONGTEXT</div>
            </td>
            <td width="25%">
            <div align=left>0-4 294 967 295字节</div>
            </td>
            <td width="55%">
            <div align=left>极大文本数据</div>
            </td>
        </tr>
    </tbody>
</table>
</div>
<div>
<h3 align=left>CHAR 和 VARCHAR 类型</h3>
<p align=left>　　CHAR 类型用于定长字符串，并且必须在圆括号内用一个大小修饰符来定义。这个大小修饰符的范围从 0-255。比指定长度大的值将被截短，而比指定长度小的值将会用空格作填补。</p>
<p align=left>　　CHAR 类型可以使用 BINARY 修饰符。当用于比较运算时，这个修饰符使 CHAR 以二进制方式参于运算，而不是以传统的区分大小写的方式。</p>
<p align=left>　　CHAR 类型的一个变体是 VARCHAR 类型。它是一种可变长度的字符串类型，并且也必须带有一个范围在 0-255 之间的指示器。CHAR 和 VARCHGAR 不同之处在于 MuSQL 数据库处理这个指示器的方式：CHAR 把这个大小视为值的大小，不长度不足的情况下就用空格补足。而 VARCHAR 类型把它视为最大值并且只使用存储字符串实际需要的长度（增加一个额外字节来存储字符串本身的长度）来存储值。所以短于指示器长度的 VARCHAR 类型不会被空格填补，但长于指示器的值仍然会被截短。</p>
<p align=left>　　因为 VARCHAR 类型可以根据实际内容动态改变存储值的长度，所以在不能确定字段需要多少字符时使用 VARCHAR 类型可以大大地节约磁盘空间、提高存储效率。</p>
<p align=left>　　VARCHAR 类型在使用 BINARY 修饰符时与 CHAR 类型完全相同。</p>
<h3 align=left>TEXT 和 BLOB 类型</h3>
<p align=left>　　对于字段长度要求超过 255 个的情况下，MySQL 提供了 TEXT 和 BLOB 两种类型。根据存储数据的大小，它们都有不同的子类型。这些大型的数据用于存储文本块或图像、声音文件等二进制数据类型。</p>
<p align=left>　　TEXT 和 BLOB 类型在分类和比较上存在区别。BLOB 类型区分大小写，而 TEXT 不区分大小写。大小修饰符不用于各种 BLOB 和 TEXT 子类型。比指定类型支持的最大范围大的值将被自动截短。</p>
<p align=left>&nbsp;</p>
<h2 align=left>日期和时间类型</h2>
<p align=left>　　在处理日期和时间类型的值时，MySQL 带有 5 个不同的数据类型可供选择。它们可以被分成简单的日期、时间类型，和混合日期、时间类型。根据要求的精度，子类型在每个分类型中都可以使用，并且 MySQL 带有内置功能可以把多样化的输入格式变为一个标准格式。</p>
<table style="WIDTH: 484px; HEIGHT: 509px" cellSpacing=0 cellPadding=4 width=484 align=center border=1>
    <tbody>
        <tr>
            <td width="10%">
            <div align=left><strong>类型</strong></div>
            </td>
            <td width="10%">
            <div align=left><strong>大小<br>(字节)</strong></div>
            </td>
            <td width="40%">
            <div align=left><strong>范围</strong></div>
            </td>
            <td width="20%">
            <div align=left><strong>格式</strong></div>
            </td>
            <td width="20%">
            <div align=left><strong>用途</strong></div>
            </td>
        </tr>
        <tr>
            <td width="10%">
            <div align=left>DATE</div>
            </td>
            <td width="10%">
            <div align=left>3</div>
            </td>
            <td width="40%">
            <div align=left>1000-01-01/9999-12-31</div>
            </td>
            <td width="20%">
            <div align=left>YYYY-MM-DD</div>
            </td>
            <td width="20%">
            <div align=left>日期值</div>
            </td>
        </tr>
        <tr>
            <td width="10%">
            <div align=left>TIME</div>
            </td>
            <td width="10%">
            <div align=left>3</div>
            </td>
            <td width="40%">
            <div align=left>'-838:59:59'/'838:59:59'</div>
            </td>
            <td width="20%">
            <div align=left>HH:MM:SS</div>
            </td>
            <td width="20%">
            <div align=left>时间值或持续时间</div>
            </td>
        </tr>
        <tr>
            <td width="10%">
            <div align=left>YEAR</div>
            </td>
            <td width="10%">
            <div align=left>1</div>
            </td>
            <td width="40%">
            <div align=left>1901/2155</div>
            </td>
            <td width="20%">
            <div align=left>YYYY</div>
            </td>
            <td width="20%">
            <div align=left>年份值</div>
            </td>
        </tr>
        <tr>
            <td width="10%">
            <div align=left>DATETIME</div>
            </td>
            <td width="10%">
            <div align=left>8</div>
            </td>
            <td width="40%">
            <div align=left>1000-01-01 00:00:00/9999-12-31 23:59:59</div>
            </td>
            <td width="20%">
            <div align=left>YYYY-MM-DD HH:MM:SS</div>
            </td>
            <td width="20%">
            <div align=left>混合日期和时间值</div>
            </td>
        </tr>
        <tr>
            <td width="10%">
            <div align=left>TIMESTAMP</div>
            </td>
            <td width="10%">
            <div align=left>8</div>
            </td>
            <td width="40%">
            <div align=left>1970-01-01 00:00:00/2037 年某时</div>
            </td>
            <td width="20%">
            <div align=left>YYYYMMDD HHMMSS</div>
            </td>
            <td width="20%">
            <div align=left>混合日期和时间值，时间戳</div>
            </td>
        </tr>
    </tbody>
</table>
<h3 align=left>DATE、TIME 和 TEAR 类型</h3>
<p align=left>　　MySQL 用 DATE 和 TEAR 类型存储简单的日期值，使用 TIME 类型存储时间值。这些类型可以描述为字符串或不带分隔符的整数序列。如果描述为字符串，DATE 类型的值应该使用连字号作为分隔符分开，而 TIME 类型的值应该使用冒号作为分隔符分开。</p>
<p align=left>　　需要注意的是，没有冒号分隔符的 TIME 类型值，将会被 MySQL 理解为持续的时间，而不是时间戳。</p>
<p align=left>　　MySQL 还对日期的年份中的两个数字的值，或是 SQL 语句中为 TEAR 类型输入的两个数字进行最大限度的通译。因为所有 TEAR 类型的值必须用 4 个数字存储。MySQL 试图将 2 个数字的年份转换为 4 个数字的值。把在 00-69 范围内的值转换到 2000-2069 范围内。把 70-99 范围内的值转换到 1970-1979 之内。如果 MySQL 自动转换后的值并不符合我们的需要，请输入 4 个数字表示的年份。</p>
<h3 align=left>DATEYIME 和 TIMESTAMP 类型</h3>
<p align=left>　　 除了日期和时间数据类型，MySQL 还支持 DATEYIME 和 TIMESTAMP 这两种混合类型。它们可以把日期和时间作为单个的值进行存储。这两种类型通常用于自动存储包含当前日期和时间的时间戳，并可在需要执行大量数据库事务和需要建立一个调试和审查用途的审计跟踪的应用程序中发挥良好作用。</p>
<p align=left>　　如果我们对 TIMESTAMP 类型的字段没有明确赋值，或是被赋与了 null 值。MySQL 会自动使用系统当前的日期和时间来填充它。</p>
<p align=left>&nbsp;</p>
<h2 align=left>复合类型</h2>
<p align=left>　　MySQL 还支持两种复合数据类型 ENUM 和 SET，它们扩展了 SQL 规范。虽然这些类型在技术上是字符串类型，但是可以被视为不同的数据类型。一个 ENUM 类型只允许从一个集合中取得一个值；而 SET 类型允许从一个集合中取得任意多个值。</p>
<p align=left>&nbsp;</p>
<h3 align=left>ENUM 类型</h3>
<p align=left>　　ENUM 类型因为只允许在集合中取得一个值，有点类似于单选项。在处理相互排拆的数据时容易让人理解，比如人类的性别。ENUM 类型字段可以从集合中取得一个值或使用 null 值，除此之外的输入将会使 MySQL 在这个字段中插入一个空字符串。另外如果插入值的大小写与集合中值的大小写不匹配，MySQL 会自动使用插入值的大小写转换成与集合中大小写一致的值。</p>
<p align=left>　　 ENUM 类型在系统内部可以存储为数字，并且从 1 开始用数字做索引。一个 ENUM 类型最多可以包含 65536 个元素，其中一个元素被 MySQL 保留，用来存储错误信息，这个错误值用索引 0 或者一个空字符串表示。</p>
<p align=left>　　MySQL 认为 ENUM 类型集合中出现的值是合法输入，除此之外其它任何输入都将失败。这说明通过搜索包含空字符串或对应数字索引为 0 的行就可以很容易地找到错误记录的位置。</p>
<h3 align=left>SET 类型</h3>
<p align=left>　　SET 类型与 ENUM 类型相似但不相同。SET 类型可以从预定义的集合中取得任意数量的值。并且与 ENUM 类型相同的是任何试图在 SET 类型字段中插入非预定义的值都会使 MySQL 插入一个空字符串。如果插入一个即有合法的元素又有非法的元素的记录，MySQL 将会保留合法的元素，除去非法的元素。</p>
<p align=left>　　一个 SET 类型最多可以包含 64 项元素。在 SET 元素中值被存储为一个分离的&#8220;位&#8221;序列，这些&#8220;位&#8221;表示与它相对应的元素。&#8220;位&#8221;是创建有序元素集合的一种简单而有效的方式。并且它还去除了重复的元素，所以 SET 类型中不可能包含两个相同的元素。</p>
<p align=left>　　希望从 SET 类型字段中找出非法的记录只需查找包含空字符串或二进制值为 0 的行。</p>
</div>
<img src ="http://www.blogjava.net/WshmAndLily/aggbug/130973.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2007-07-18 10:01 <a href="http://www.blogjava.net/WshmAndLily/articles/130973.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jsp 备份和还原 mysql 数据库</title><link>http://www.blogjava.net/WshmAndLily/articles/116807.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Fri, 11 May 2007 09:30:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/116807.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/116807.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/116807.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/116807.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/116807.html</trackback:ping><description><![CDATA[请问大家，如何用<a href="http://www.zhanso.com/JAVA/JAVA_1_7455.html" target=_blank><a href="http://www.zhanso.com/JAVA/JAVA_1_7102.html" target=_blank><font color=#000000>js</font></a>p</a>实现备份和还原<a href="http://www.zhanso.com/PHP/PHP_1_7563.html" target=_blank><font color=#000000>my</font><a href="http://www.zhanso.com/database/database_1_7487.html" target=_blank><font color=#000000>sql</font></a></a><a href="http://www.zhanso.com/JAVA/JAVA_1_7088.html" target=_blank><font color=#000000>数据库</font></a>，请给出代码实例，谢谢！
<div class=ad2 id=ad2>
<script src="../js/ad2.js"></script>
<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
<iframe name=google_ads_frame marginWidth=0 marginHeight=0 src="http://pagead2.googlesyndication.com/pagead/ads?client=ca-pub-3253660882875051&amp;dt=1178874152485&amp;lmt=1175597667&amp;format=728x90_as&amp;output=html&amp;url=http%3A%2F%2Fwww.zhanso.com%2FJAVA%2FJAVA_1_7477.html&amp;color_bg=FFFFFF&amp;color_text=000000&amp;color_link=0000FF&amp;color_url=000000&amp;color_border=FFFFFF&amp;ad_type=text_image&amp;cc=346&amp;flash=9&amp;u_h=768&amp;u_w=1024&amp;u_ah=738&amp;u_aw=1024&amp;u_cd=32&amp;u_tz=480&amp;u_java=true" frameBorder=0 width=728 scrolling=no height=90 allowTransparency></iframe></div>
<div class=feedback>回复2急：<a href="http://www.zhanso.com/JAVA/JAVA_1_7455.html" target=_blank><a href="http://www.zhanso.com/JAVA/JAVA_1_7102.html" target=_blank><font color=#000000>js</font></a>p</a> 备份和还原 <a href="http://www.zhanso.com/PHP/PHP_1_7563.html" target=_blank><font color=#000000>my</font><a href="http://www.zhanso.com/database/database_1_7487.html" target=_blank><font color=#000000>sql</font></a></a> <a href="http://www.zhanso.com/JAVA/JAVA_1_7088.html" target=_blank><font color=#000000>数据库</font></a></div>
这个帖一定要顶
<div class=feedback>回复3急：<a href="http://www.zhanso.com/JAVA/JAVA_1_7455.html" target=_blank><a href="http://www.zhanso.com/JAVA/JAVA_1_7102.html" target=_blank><font color=#000000>js</font></a>p</a> 备份和还原 <a href="http://www.zhanso.com/PHP/PHP_1_7563.html" target=_blank><font color=#000000>my</font><a href="http://www.zhanso.com/database/database_1_7487.html" target=_blank><font color=#000000>sql</font></a></a> <a href="http://www.zhanso.com/JAVA/JAVA_1_7088.html" target=_blank><font color=#000000>数据库</font></a></div>
MS<a href="http://www.zhanso.com/database/database_1_7487.html" target=_blank><font color=#000000>sql</font></a> 的知道 <a href="http://www.zhanso.com/PHP/PHP_1_7563.html" target=_blank><font color=#000000>my</font><a href="http://www.zhanso.com/database/database_1_7487.html" target=_blank><font color=#000000>sql</font></a></a>的不知道 MS<a href="http://www.zhanso.com/database/database_1_7487.html" target=_blank><font color=#000000>sql</font></a>备份语句 BACKUP DATABASE [<a href="http://www.zhanso.com/JAVA/JAVA_1_7088.html" target=_blank><font color=#000000>数据库</font></a>名称] TO DISK=存放路径文件名 WITH Format（完全备份）还原用 RESTORE DATABASE [<a href="http://www.zhanso.com/JAVA/JAVA_1_7088.html" target=_blank><font color=#000000>数据库</font></a>名称] FROM 期待答案ING
<div class=feedback>回复4急：<a href="http://www.zhanso.com/JAVA/JAVA_1_7455.html" target=_blank><a href="http://www.zhanso.com/JAVA/JAVA_1_7102.html" target=_blank><font color=#000000>js</font></a>p</a> 备份和还原 <a href="http://www.zhanso.com/PHP/PHP_1_7563.html" target=_blank><font color=#000000>my</font><a href="http://www.zhanso.com/database/database_1_7487.html" target=_blank><font color=#000000>sql</font></a></a> <a href="http://www.zhanso.com/JAVA/JAVA_1_7088.html" target=_blank><font color=#000000>数据库</font></a></div>
<a href="http://www.zhanso.com/PHP/PHP_1_7563.html" target=_blank><font color=#000000>my</font><a href="http://www.zhanso.com/database/database_1_7487.html" target=_blank><font color=#000000>sql</font></a></a>dump databasename &gt;路径 及名字 恢复使用&lt; Runtime runtime = Runtime.getRuntime(); runtime.exec("<a href="http://www.zhanso.com/PHP/PHP_1_7563.html" target=_blank><font color=#000000>my</font><a href="http://www.zhanso.com/database/database_1_7487.html" target=_blank><font color=#000000>sql</font></a></a>dump table &gt; d:/20070308.bak") 
<img src ="http://www.blogjava.net/WshmAndLily/aggbug/116807.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2007-05-11 17:30 <a href="http://www.blogjava.net/WshmAndLily/articles/116807.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何才能实现MySQL的自动备份</title><link>http://www.blogjava.net/WshmAndLily/articles/116792.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Fri, 11 May 2007 08:54:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/116792.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/116792.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/116792.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/116792.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/116792.html</trackback:ping><description><![CDATA[MySQL自动备份是非常关键的，特别是对于DBA来说。这里主要用代码来说明这个问题，希望对各位有所帮助。可以将这个脚本放进crontab，每天凌晨执行一次，自动备份。<br><br>这个脚本每天最多只执行一次，而且只保留最近五天的备份在服务器上。<br><br>代码:<br><br>#!/bin/bash <br>#This is a ShellScript For Auto DB Backup <br>#Powered by ASPbiz <br>#2004-09 <br><br>#Setting <br>#设置数据库名，数据库登录名，密码，备份路径，日志路径，数据文件位置，以及备份方式 <br>#默认情况下备份方式是tar，还可以是mysqldump,mysqldotcopy <br>#默认情况下，用root(空)登录mysql数据库，备份至/root/dbxxxxx.tgz <br>DBName=mysql <br>DBUser=root <br>DBPasswd= <br>BackupPath=/root/ <br>LogFile=/root/db.log <br>DBPath=/var/lib/mysql/ <br>#BackupMethod=mysqldump <br>#BackupMethod=mysqlhotcopy <br>#BackupMethod=tar <br>#Setting End <br><br><br>NewFile="￥BackupPath"db￥(date +%y%m%d).tgz <br>DumpFile="￥BackupPath"db￥(date +%y%m%d) <br>OldFile="￥BackupPath"db￥(date +%y%m%d --date='5 days ago').tgz <br><br>echo "-------------------------------------------" &gt;&gt; ￥LogFile <br>echo ￥(date +"%y-%m-%d %H:%M:%S") &gt;&gt; ￥LogFile <br>echo "--------------------------" &gt;&gt; ￥LogFile <br>#Delete Old File <br>if [ -f ￥OldFile ] <br>then <br>rm -f ￥OldFile &gt;&gt; ￥LogFile 2&gt;&amp;1 <br>echo "[￥OldFile]Delete Old File Success!" &gt;&gt; ￥LogFile <br>else <br>echo "[￥OldFile]No Old Backup File!" &gt;&gt; ￥LogFile <br>fi <br><br>if [ -f ￥NewFile ] <br>then <br>echo "[￥NewFile]The Backup File is exists,Can't Backup!" &gt;&gt; ￥LogFile <br>else <br>case ￥BackupMethod in <br>mysqldump) <br>if [ -z ￥DBPasswd ] <br>then <br>mysqldump -u ￥DBUser --opt ￥DBName &gt; ￥DumpFile <br>else <br>mysqldump -u ￥DBUser -p￥DBPasswd --opt ￥DBName &gt; ￥DumpFile <br>fi <br>tar czvf ￥NewFile ￥DumpFile &gt;&gt; ￥LogFile 2&gt;&amp;1 <br>echo "[￥NewFile]Backup Success!" &gt;&gt; ￥LogFile <br>rm -rf ￥DumpFile <br>;; <br>mysqlhotcopy) <br>rm -rf ￥DumpFile <br>mkdir ￥DumpFile <br>if [ -z ￥DBPasswd ] <br>then <br>mysqlhotcopy -u ￥DBUser ￥DBName ￥DumpFile &gt;&gt; ￥LogFile 2&gt;&amp;1 <br>else <br>mysqlhotcopy -u ￥DBUser -p ￥DBPasswd ￥DBName ￥DumpFile &gt;&gt;￥LogFile 2&gt;&amp;1 <br>fi <br>tar czvf ￥NewFile ￥DumpFile &gt;&gt; ￥LogFile 2&gt;&amp;1 <br>echo "[￥NewFile]Backup Success!" &gt;&gt; ￥LogFile <br>rm -rf ￥DumpFile <br>;; <br>*) <br>/etc/init.d/mysqld stop &gt;/dev/null 2&gt;&amp;1 <br>tar czvf ￥NewFile ￥DBPath￥DBName &gt;&gt; ￥LogFile 2&gt;&amp;1 <br>/etc/init.d/mysqld start &gt;/dev/null 2&gt;&amp;1 <br>echo "[￥NewFile]Backup Success!" &gt;&gt; ￥LogFile <br>;; <br>esac <br>fi <br><br>echo "-------------------------------------------" &gt;&gt; ￥LogFile <br>
<img src ="http://www.blogjava.net/WshmAndLily/aggbug/116792.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2007-05-11 16:54 <a href="http://www.blogjava.net/WshmAndLily/articles/116792.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Mysql日常自动备份和增量备份脚本</title><link>http://www.blogjava.net/WshmAndLily/articles/116791.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Fri, 11 May 2007 08:51:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/116791.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/116791.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/116791.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/116791.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/116791.html</trackback:ping><description><![CDATA[<strong><span class=tpc_title>Mysql日常自动备份和增量备份脚本</span><br><!----><br></strong><span class=tpc_content><font size=2>序 <br>你是否在寻找一个MySQL备份脚本? <br><br>适合对象 <br><br>本文是在Linux下,mysql 4.1.14版本下测试的,经过适当修改可能适合mysql 4.0,5.0及其其他版本. <br><br>本文适合于没有启动复制功能的mysql,如果启动了复制,可能不需要采取这种备份策略或者需要修改相关参数. <br><br>每个人的备份策略都可能不同,所以请根据实际情况修改,做到举一反三,不要照搬照抄,可能会造成不必要的损失. <br><br>希望你明白这个脚本要干什么工作! <br><br>脚本描述 <br><br>每7天备份一次所有数据,每天备份binlog,也就是增量备份. <br><br>(如果数据少,每天备份一次完整数据即可,可能没必要做增量备份) <br><br>作者对shell脚本不太熟悉,所以很多地方写的很笨 :) <br><br>开启 bin log <br><br>在mysql 4.1版本中,默认只有错误日志,没有其他日志.可以通过修改配置打开bin log.方法很多,其中一个是在/etc/my.cnf中的mysqld部分加入: <br><br><br>[mysqld]<br>log-bin<br><br><br>这个日志的主要作用是增量备份或者复制(可能还有其他用途). <br><br>如果想增量备份,必须打开这个日志. <br><br>对于数据库操作频繁的mysql,这个日志会变得很大,而且可能会有多个. <br><br>在数据库中flush-logs,或者使用mysqladmin,mysqldump调用flush-logs后并且使用参数delete-master-logs,这些日志文件会消失,并产生新的日志文件(开始是空的). <br><br>所以如果从来不备份,开启日志可能没有必要. <br><br>完整备份的同时可以调用flush-logs,增量备份之前flush-logs,以便备份最新的数据. <br><br>完整备份脚本 <br><br>如果数据库数据比较多,我们一般是几天或者一周备份一次数据,以免影响应用运行,如果数据量比较小,那么一天备份一次也无所谓了. <br><br>下载假设我们的数据量比较大,备份脚本如下:(参考过网络上一个mysql备份脚本,致谢 :)) <br><br><br>#!/bin/sh<br># mysql data backup script<br># by scud </font><a href="http://www.jscud.com/" target=_blank><font color=#0000ff size=2>http://www.jscud.com</font></a><br><font size=2># 2005-10-30<br>#<br># use mysqldump --help,get more detail.<br>#<br>BakDir=/backup/mysql<br>LogFile=/backup/mysql/mysqlbak.log<br>DATE=`date +%Y%m%d`<br>echo " " &gt;&gt; $LogFile<br>echo " " &gt;&gt; $LogFile<br>echo "-------------------------------------------" &gt;&gt; $LogFile <br>echo $(date +"%y-%m-%d %H:%M:%S") &gt;&gt; $LogFile <br>echo "--------------------------" &gt;&gt; $LogFile <br>cd $BakDir<br>DumpFile=$DATE.sql<br>GZDumpFile=$DATE.sql.tgz<br>mysqldump --quick --all-databases --flush-logs <br>--delete-master-logs --lock-all-tables &gt; $DumpFile<br>echo "Dump Done" &gt;&gt; $LogFile<br>tar czvf $GZDumpFile $DumpFile &gt;&gt; $LogFile 2&gt;&amp;1 <br>echo "[$GZDumpFile]Backup Success!" &gt;&gt; $LogFile <br>rm -f $DumpFile <br>#delete previous daily backup files:采用增量备份的文件,如果完整备份后,则删除增量备份的文件.<br>cd $BakDir/daily<br>rm -f * &nbsp; &nbsp; &nbsp; <br>cd $BakDir &nbsp; <br>echo "Backup Done!"<br>echo "please Check $BakDir Directory!"<br>echo "copy it to your local disk or ftp to somewhere !!!"<br>ls -al $BakDir<br><br><br>上面的脚本把mysql备份到本地的/backup/mysql目录,增量备份的文件放在/backup/mysql/daily目录下. <br><br>注意:上面的脚本并没有把备份后的文件传送到其他远程计算机,也没有删除几天前的备份文件:需要用户增加相关脚本,或者手动操作. <br><br>增量备份 <br><br>增量备份的数据量比较小,但是要在完整备份的基础上操作,用户可以在时间和成本上权衡,选择最有利于自己的方式. <br><br>增量备份使用bin log,脚本如下: <br><br><br>#!/bin/sh<br>#<br># mysql binlog backup script<br>#<br>/usr/bin/mysqladmin flush-logs<br>DATADIR=/var/lib/mysql<br>BAKDIR=/backup/mysql/daily<br>###如果你做了特殊设置,请修改此处或者修改应用此变量的行:缺省取机器名,mysql缺省也是取机器名<br>HOSTNAME=`uname -n`<br>cd $DATADIR<br>FILELIST=`cat $HOSTNAME-bin.index`<br>##计算行数,也就是文件数<br>COUNTER=0<br>for file in $FILELIST<br>do<br>COUNTER=`expr $COUNTER + 1 `<br>done<br>NextNum=0<br>for file in $FILELIST<br>do<br>&nbsp; &nbsp; &nbsp; &nbsp; base=`basename $file`<br>NextNum=`expr $NextNum + 1`<br>if [ $NextNum -eq $COUNTER ] <br>then<br>echo "skip lastest"<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else<br>dest=$BAKDIR/$base<br>if(test -e $dest)<br>then<br>echo "skip exist $base"<br>else<br>echo "copying $base"<br>cp $base $BAKDIR<br>fi<br>fi<br>done<br>echo "backup mysql binlog ok"<br><br><br>增量备份脚本是备份前flush-logs,mysql会自动把内存中的日志放到文件里,然后生成一个新的日志文件,所以我们只需要备份前面的几个即可,也就是不备份最后一个. <br><br>因为从上次备份到本次备份也可能会有多个日志文件生成,所以要检测文件,如果已经备份过,就不用备份了. <br><br>注:同样,用户也需要自己远程传送,不过不需要删除了,完整备份后程序会自动生成. <br><br>访问设置 <br><br>脚本写完了,为了能让脚本运行,还需要设置对应的用户名和密码,mysqladmin和mysqldump都是需要用户名和密码的,当然可以写在脚本中,但是修改起来不太方便,假设我们用系统的root用户来运行此脚本,那么我们需要在/root(也就是root用户的home目录)创建一个.my.cnf文件,内容如下 <br><br><br>[mysqladmin]<br>password =password<br>user= root<br>[mysqldump]<br>user=root<br>password=password<br><br><br>注: 设置本文件只有root可读.(chmod 600 .my.cnf ) <br><br>此文件说明程序使用mysql的root用户备份数据,密码是对应的设置.这样就不需要在脚本里写用户名和密码了. <br><br>自动运行 <br><br>为了让备份程序自动运行,我们需要把它加入crontab. <br><br>有2种方法,一种是把脚本根据自己的选择放入到/etc/cron.daily,/etc/cron.weekly这么目录里. <br><br>一种是使用crontab -e放入到root用户的计划任务里,例如完整备份每周日凌晨3点运行,日常备份每周一-周六凌晨3点运行. <br><br>具体使用,请参考crontab的帮助. <br><br>所为何 <br><br>在网上没有找到类似的脚本,只好学习shell语法,自己写了一个 :) <br><br>适合自己的,就是最好的!</font></span><br>
<img src ="http://www.blogjava.net/WshmAndLily/aggbug/116791.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2007-05-11 16:51 <a href="http://www.blogjava.net/WshmAndLily/articles/116791.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用mysqldump 来备份数据库</title><link>http://www.blogjava.net/WshmAndLily/articles/96294.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Sat, 27 Jan 2007 09:58:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/96294.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/96294.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/96294.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/96294.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/96294.html</trackback:ping><description><![CDATA[
		<table cellspacing="1" cellpadding="4" width="100%" border="0">
				<tbody>
						<tr>
								<td valign="top">
										<div class="subhead">
												<strong>用mysqldump 来备份数据库</strong>
										</div>
								</td>
						</tr>
						<tr>
								<td valign="top">
										<div class="content">
												<p>写在前面:<br />-----------------------------------------------------------------<br />有时候经常要把数据库转来转去,或者导入导出,以前记得命令,后来又忘记了,现在写出来备忘!<br />------------------------------------------------------------------</p>
												<p>注意:mysqldump比直接拷贝数据库文件夹速度要慢<br />但,直接复制文件夹不能100%转移到其它机子上用,我说的不是windows下 :)</p>
												<p>#mysqldump db_name &gt;/path/name.sql</p>
												<p>上面的命令意思是把一个库导出到一个SQL文件. 当然,你直接在有ROOT密码的机子上执行以上命令一定会报错.所以,请用</p>
												<p>#mysqldump db_name &gt;/path/name.sql -uroot -p </p>
												<p>这回会要求你输入密码,输入正确,找找/path下是不是有name.sql文件了?</p>
												<p>数据库太大了,想压缩一下?好,用这个命令就行</p>
												<p>#mysqldump db_name |gzip &gt;/path/name.gz -uroot -p </p>
												<p>
														<strong>
																<font color="#330066">想备份全部的库呢?</font>
														</strong>
												</p>
												<p>
														<font color="#330066">
																<font color="#000000">#mysqldump --all-databases  &gt;/path/name.sql -uroot -p </font>
														</font>
												</p>
												<p>
														<font color="#330066">
																<font color="#000000">#mysqldump --all-databases |gzip &gt;/path/name.gz -uroot -p (很明显,这条命令是加压缩的意思)</font>
														</font>
												</p>
												<p>
														<font color="#ff0000">
																<strong>只想备份一个单独或者几个表?</strong>
														</font>
												</p>
												<p>
														<font color="#330066">
																<font color="#000000">有时候数据库很大很大,整个库备份就不好管理,那就单独备份</font>
														</font>
												</p>
												<p>#mysqldump db_name tab_name &gt;/path/sqlname.sql -uroot -p </p>
												<p>
														<strong>
																<font color="#ff0000">备份做好了.遇到问题的时候.怎么用备份恢复数据?</font>
														</strong>
												</p>
												<p>
														<font color="#000000">再简单不过了,</font>
												</p>
												<p>mysql db_name &lt; backup-file.sql -uroot -p</p>
												<p>
														<strong>注意:</strong>如果你想恢复的数据库是包含授权表的mysql数据库，你需要用--skip-grant-table选项运行服务器。否则，它会抱怨不能找到授权表。在你已经恢复表后，执行mysqladmin flush-privileges告诉服务器装载授权标并使用它们 </p>
												<font color="#330066">
														<p>
																<font color="#ff0000">
																		<strong>恢复单个表</strong>
																</font>
														</p>
														<p>
																<font color="#000000">　恢复单个表较为复杂,如果你用一个由mysqldump生成的备份文件，并且它不包含你感兴趣的表的数据，你需要从相关行中提取它们并将它们用作mysql的输入。这是容易的部分。难的部分是从只运用于该表的更新日志中拉出片断。你会发觉mysql_find_rows实用程序对此很有帮助，它从更新日志中提取多行查询。</font>
														</p>
														<p>
																<font color="#000000">好了,就这些,看起来并不难,</font>
														</p>
												</font>
										</div>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/WshmAndLily/aggbug/96294.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2007-01-27 17:58 <a href="http://www.blogjava.net/WshmAndLily/articles/96294.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>mysql的级联更新和级联删除</title><link>http://www.blogjava.net/WshmAndLily/articles/89087.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Wed, 20 Dec 2006 09:47:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/89087.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/89087.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/89087.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/89087.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/89087.html</trackback:ping><description><![CDATA[user表： <br />create table user <br />( <br />userid integer not null auto_increment primary key, <br />username varchar(12) not null <br />) <br />type=innodb; <br /><br />password表： <br />create table password <br />( <br />userid integer not null, <br />password varchar(12) not null, <br />index (userid), <br />foreign key (userid) references user (userid) <br />on delete cascade <br />on update cascade <br />) <br />type=innodb; <br /><br />1、MySQL支持外键约束，并提供与其它DB相同的功能，但表类型必须为 InnoDB <br />2、建外键的表的那个列要加上index. <br /><img src ="http://www.blogjava.net/WshmAndLily/aggbug/89087.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2006-12-20 17:47 <a href="http://www.blogjava.net/WshmAndLily/articles/89087.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>struts+MySQL实现图片的存储与显示</title><link>http://www.blogjava.net/WshmAndLily/articles/88347.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Sun, 17 Dec 2006 08:30:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/88347.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/88347.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/88347.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/88347.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/88347.html</trackback:ping><description><![CDATA[
		<p class="altq" style="TEXT-INDENT: 26pt">
				<span style="FONT-FAMILY: 宋体">人事信息管理系统中，需要管理用户的个人身份照片。通常这种格式的照片只有几</span>
				<span lang="EN-US">K</span>
				<span style="FONT-FAMILY: 宋体">到几十</span>
				<span lang="EN-US">K</span>
				<span style="FONT-FAMILY: 宋体">大小，保存在数据库中易于进行管理和维护（如果放在文件夹下容易发生误操作而引起数据被修改或丢失）。</span>
		</p>
		<p class="altq" style="TEXT-INDENT: 27.85pt">
				<span class="Alt2Char">
						<span style="FONT-FAMILY: 黑体">功能设计：</span>
				</span>
				<span style="FONT-FAMILY: 宋体">给用户提供一个上传的界面，并设定上传文件的尺寸上限。用户上传的照片先统一保存在一个临时文件夹中，之后可以用</span>
				<span lang="EN-US">&lt;img&gt;</span>
				<span style="FONT-FAMILY: 宋体">指向临时文件夹中的这个图片，让用户可以预览自己上传的照片。当所有的用户信息都收集完成后，将图片和其他信息一并提交，保存到数据库中。保存成功以后，删除临时文件夹中的图片。</span>
		</p>
		<p class="Alt2" style="TEXT-INDENT: 27.85pt">
				<span style="FONT-FAMILY: 黑体">实现步骤：</span>
		</p>
		<p class="altq" style="TEXT-INDENT: 26pt">
				<span style="FONT-FAMILY: 宋体">我使用的是从</span>
				<span lang="EN-US">struts</span>
				<span style="FONT-FAMILY: 宋体">主页上下载的</span>
				<span lang="EN-US">struts-<?XML:NAMESPACE PREFIX = ST1 /?><st1:chsdate isrocdate="False" islunardate="False" day="30" month="12" year="1899" w:st="on">1.2.8</st1:chsdate>-src</span>
				<span style="FONT-FAMILY: 宋体">，其中</span>
				<span lang="EN-US">web/examples/</span>
				<span style="FONT-FAMILY: 宋体">目录下有一个</span>
				<span lang="EN-US">upload</span>
				<span style="FONT-FAMILY: 宋体">的例子，稍微修改了一下就直接拿过来用了。这是一个</span>
				<span lang="EN-US">JSP</span>
				<span style="FONT-FAMILY: 宋体">页面、</span>
				<span lang="EN-US">ActionForm</span>
				<span style="FONT-FAMILY: 宋体">和</span>
				<span lang="EN-US">Action</span>
				<span style="FONT-FAMILY: 宋体">的组合。下面分别列出各自的代码。</span>
		</p>
		<p class="altq" style="TEXT-INDENT: 26pt">
				<span lang="EN-US">upload.jsp</span>
				<span style="FONT-FAMILY: 宋体">的部分源代码：</span>
		</p>
		<p class="AltL">
				<span lang="EN-US" style="BACKGROUND: white 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">&lt;html:form action="/UploadSubmit" enctype="multipart/form-data"&gt;<span>      </span></span>
		</p>
		<p class="AltL">
				<span lang="EN-US" style="BACKGROUND: white 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">
						<span>      </span>
				</span>
				<span style="BACKGROUND: white 0% 50%; FONT-FAMILY: 宋体; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">请选择需要上传的照片</span>
				<span lang="EN-US" style="BACKGROUND: white 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">: </span>
		</p>
		<p class="AltL">
				<span lang="EN-US" style="BACKGROUND: white 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">
						<span>     </span>&lt;html:file property="theFile"/&gt;</span>
		</p>
		<p class="AltL">
				<span lang="EN-US" style="BACKGROUND: white 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">
						<span>     </span>&lt;html:submit value="</span>
				<span style="BACKGROUND: white 0% 50%; FONT-FAMILY: 宋体; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">上传</span>
				<span lang="EN-US" style="BACKGROUND: white 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">"/&gt;<span>      </span></span>
		</p>
		<p class="AltL">
				<span lang="EN-US" style="BACKGROUND: white 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">&lt;/html:form&gt;</span>
		</p>
		<p class="altq" style="TEXT-INDENT: 26pt">
				<span style="FONT-FAMILY: 宋体">接下来需要在</span>
				<span lang="EN-US">ActionForm</span>
				<span style="FONT-FAMILY: 宋体">中声明这个属性，并设置</span>
				<span lang="EN-US">getter</span>
				<span style="FONT-FAMILY: 宋体">和</span>
				<span lang="EN-US">setter</span>
				<span style="FONT-FAMILY: 宋体">方法，这部分源代码如下：</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">public class UploadForm extends ActionForm {</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>    </span>protected FormFile theFile;</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>    </span>public FormFile getTheFile() {</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>        </span>return theFile;</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>    </span>}</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>    </span>public void setTheFile(FormFile theFile) {</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>        </span>this.theFile = theFile;</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>    </span>}</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">}</span>
		</p>
		<p class="altq" style="TEXT-INDENT: 26pt">
				<span style="FONT-FAMILY: 宋体">这个表单的</span>
				<span lang="EN-US">theFile</span>
				<span style="FONT-FAMILY: 宋体">属性不是</span>
				<span lang="EN-US">String</span>
				<span style="FONT-FAMILY: 宋体">或</span>
				<span lang="EN-US">boolean</span>
				<span style="FONT-FAMILY: 宋体">，而是</span>
				<span lang="EN-US">org.apache.struts.upload.FormFile</span>
				<span style="FONT-FAMILY: 宋体">。因为用户上传的是一个二进制文件，而</span>
				<span lang="EN-US">HTTP</span>
				<span style="FONT-FAMILY: 宋体">协议是以文本形式传输数据的，这就需要进行转换。打个比方，一辆汽车需要从甲地送到乙地，但是两地之间只有一条索道，汽车没法开，所以就想个办法在甲地把汽车先拆了，把零件送到乙地再重新组装成一辆汽车。</span>
				<span lang="EN-US">FormFile</span>
				<span style="FONT-FAMILY: 宋体">起的就是拆卸和组装的作用，只不过它把拆卸、传输和组装的过程都封装起来了，我们看到的是一辆汽车从甲地开进</span>
				<span lang="EN-US">FormFile</span>
				<span style="FONT-FAMILY: 宋体">，过一会它就从乙地开出来了</span>
				<span lang="EN-US" style="FONT-FAMILY: Wingdings">
						<span>J</span>
				</span>
				<span style="FONT-FAMILY: 宋体">我们要决定的只是把它停到什么地方，这就是</span>
				<span lang="EN-US">Action</span>
				<span style="FONT-FAMILY: 宋体">的活了。</span>
		</p>
		<p class="altq" style="TEXT-INDENT: 26pt">
				<span style="FONT-FAMILY: 宋体">按照功能设计，</span>
				<span lang="EN-US">Action</span>
				<span style="FONT-FAMILY: 宋体">要把这部车停到一个临时文件夹下面，这部分源代码如下：</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">public ActionForward execute(ActionMapping mapping,</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>                                 </span>ActionForm form,</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>                                 </span>HttpServletRequest request,</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>                                 </span>HttpServletResponse response)</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>        </span>throws Exception {</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>        </span>if (form instanceof UploadForm) {</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>            </span>UploadForm theForm = (UploadForm) form;</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>      </span>
						<span>      </span>
						<span style="COLOR: green">//</span>
				</span>
				<span style="COLOR: green; FONT-FAMILY: 宋体">获取上传的数据文件</span>
				<span lang="EN-US" style="COLOR: green">
						<?XML:NAMESPACE PREFIX = O /?>
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>            </span>FormFile file = theForm.getTheFile();</span>
		</p>
		<p class="AltL">
				<span lang="EN-US" style="COLOR: green">
						<span>            </span>//</span>
				<span style="COLOR: green; FONT-FAMILY: 宋体">获取文件名</span>
				<span lang="EN-US" style="COLOR: green">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>            </span>String filename= file.getFileName();</span>
		</p>
		<p class="AltL">
				<span lang="EN-US" style="COLOR: green">
						<span>            </span>//</span>
				<span style="COLOR: green; FONT-FAMILY: 宋体">设置图片文件临时存放的路径</span>
				<span lang="EN-US" style="COLOR: green">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>            </span>HttpSession session = request.getSession();</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>            </span>String path = session.getServletContext().getRealPath("/") + "temp\\" + filename;</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>            </span>try {</span>
		</p>
		<p class="AltL">
				<span lang="EN-US" style="COLOR: green">
						<span>                </span>//</span>
				<span style="COLOR: green; FONT-FAMILY: 宋体">读取文件中的数据，获取二进制的数据流</span>
				<span lang="EN-US" style="COLOR: green">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>InputStream stream = file.getInputStream();</span>
		</p>
		<p class="AltL">
				<span lang="EN-US" style="COLOR: green">
						<span>             </span>// </span>
				<span style="COLOR: green; FONT-FAMILY: 宋体">把数据写到指定路径</span>
				<span lang="EN-US" style="COLOR: green">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>OutputStream bos = new FileOutputStream(path);</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>int bytesRead = 0;</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>byte[] buffer = new byte[8192];</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>while ((bytesRead = stream.read(buffer, 0, 8192)) != -1) {</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>                 </span>bos.write(buffer, 0, bytesRead);</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>}</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>bos.close();</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>logger.info("The file has been written to \""</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>                     </span>
						<span>  </span>+ path + "\"");</span>
		</p>
		<p class="AltL">
				<span lang="EN-US" style="COLOR: green">
						<span>                </span>//</span>
				<span style="COLOR: green; FONT-FAMILY: 宋体">设计一个标记，说明用户已经上传过照片了。</span>
				<span lang="EN-US">
						<span>               </span>
				</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>session.setAttribute("imageuploaded","true");</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>session.setAttribute("filename",filename);</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="AltL">
				<span lang="EN-US" style="COLOR: green">
						<span>             </span>// close the stream<o:p></o:p></span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>stream.close();</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>bos.flush();</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>bos.close();</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>            </span>}catch (FileNotFoundException fnfe) {</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>                </span>return null;</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>            </span>}catch (IOException ioe) {</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>                </span>return null;</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>            </span>}</span>
		</p>
		<p class="AltL">
				<span lang="EN-US" style="COLOR: green">
						<span>            </span>//destroy the temporary file created<o:p></o:p></span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>            </span>file.destroy();</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="AltL">
				<span lang="EN-US" style="COLOR: green">
						<span>            </span>//</span>
				<span style="COLOR: green; FONT-FAMILY: 宋体">转向下一个页面</span>
				<span lang="EN-US" style="COLOR: green">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>            </span>return mapping.findForward("next");</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>        </span>}</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>      </span>
						<span>  </span>//this shouldn't happen in this example</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>        </span>return null;</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>    </span>}</span>
		</p>
		<p class="altq" style="TEXT-INDENT: 26pt">
				<span style="FONT-FAMILY: 宋体">这样图片就被放在</span>
				<span lang="EN-US">temp</span>
				<span style="FONT-FAMILY: 宋体">的临时文件夹下，显示的时候，只需要先检查一下标记，看看用户是否上传了照片，如果已经上传，就用一个</span>
				<span lang="EN-US">&lt;img src=””&gt;</span>
				<span style="FONT-FAMILY: 宋体">引用这个图片。还有一个小地方需要修改，因为限定上传的是身份照片，需要限定一个尺寸上限，这个在</span>
				<span lang="EN-US">struts</span>
				<span style="FONT-FAMILY: 宋体">的</span>
				<span lang="EN-US">upload</span>
				<span style="FONT-FAMILY: 宋体">里面有现成的例子。先在</span>
				<span lang="EN-US">struts-config.xml</span>
				<span style="FONT-FAMILY: 宋体">中配置这个</span>
				<span lang="EN-US">ActionForm</span>
				<span style="FONT-FAMILY: 宋体">和</span>
				<span lang="EN-US">Action</span>
				<span style="FONT-FAMILY: 宋体">：</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">&lt;form-bean name="uploadForm"</span>
		</p>
		<p class="AltL" style="MARGIN-LEFT: 8.5pt; TEXT-INDENT: 80.1pt">
				<span lang="EN-US">
						<span> </span>type="org.apache.struts.webapp.upload.UploadForm"/&gt;</span>
		</p>
		<p class="AltL">
				<span style="FONT-FAMILY: 宋体">……</span>
		</p>
		<p class="AltL">
				<span lang="EN-US" style="BACKGROUND: white 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">&lt;action input="/pages/hr/error.jsp" name="uploadForm"<o:p></o:p></span>
		</p>
		<p class="AltL">
				<span lang="EN-US" style="BACKGROUND: white 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">
						<span> </span>
						<span>        </span>path="/UploadSubmit" scope="request" <o:p></o:p></span>
		</p>
		<p class="AltL" style="MARGIN-LEFT: 75.3pt; TEXT-INDENT: 0cm">
				<span lang="EN-US" style="BACKGROUND: white 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">type="org.apache.struts.webapp.upload.UploadAction" validate="true"&gt;</span>
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="AltL">
				<span lang="EN-US" style="BACKGROUND: white 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">
						<span>   </span>&lt;forward name="next" path="/pages/hr/input.jsp"/&gt;</span>
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="AltL">
				<span lang="EN-US" style="BACKGROUND: white 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">&lt;/action&gt;</span>
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="AltL">
				<span style="FONT-FAMILY: 宋体">……</span>
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">&lt;controller maxFileSize="<st1:chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="2" unitname="m">2M</st1:chmetcnv>" inputForward="true" /&gt;<o:p></o:p></span>
		</p>
		<p class="altq" style="TEXT-INDENT: 26pt">
				<span style="FONT-FAMILY: 宋体">在配置文件中已经看到</span>
				<span lang="EN-US">&lt;action&gt;</span>
				<span style="FONT-FAMILY: 宋体">的</span>
				<span lang="EN-US">validate</span>
				<span style="FONT-FAMILY: 宋体">属性被设置成“</span>
				<span lang="EN-US">true</span>
				<span style="FONT-FAMILY: 宋体">”，这就是说表单提交之前先要对其内容进行验证，这里我们要验证的就是</span>
				<span lang="EN-US">theFile</span>
				<span style="FONT-FAMILY: 宋体">是否超出了</span>
				<span lang="EN-US">controller</span>
				<span style="FONT-FAMILY: 宋体">中设定的最大尺寸</span>
				<span lang="EN-US">”<st1:chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="2" unitname="m">2M</st1:chmetcnv>”</span>
				<span style="FONT-FAMILY: 宋体">。这个验证是通过</span>
				<span lang="EN-US">ActionForm</span>
				<span style="FONT-FAMILY: 宋体">的</span>
				<span lang="EN-US">validate</span>
				<span style="FONT-FAMILY: 宋体">方法来实现的：</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">/**</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>* Check to make sure the client hasn't exceeded the maximum allowed upload size inside of this validate method.</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">**/</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>    </span>public ActionErrors validate(ActionMapping mapping,</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>        </span>HttpServletRequest request) {<span>            </span></span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>        </span>ActionErrors errors = null;</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>        </span>//has the maximum length been exceeded?</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>        </span>Boolean maxLengthExceeded =</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>            </span>(Boolean) request.getAttribute(</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>                </span>MultipartRequestHandler.ATTRIBUTE_MAX_LENGTH_EXCEEDED);<span>                </span></span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>        </span>if ((maxLengthExceeded != null) &amp;&amp; (maxLengthExceeded.booleanValue())) {</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>            </span>errors = new ActionErrors();</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>            </span>errors.add(</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>                </span>ActionMessages.GLOBAL_MESSAGE ,</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>                </span>new ActionMessage("maxLengthExceeded"));</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>            </span>errors.add(</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>                </span>ActionMessages.GLOBAL_MESSAGE ,</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>                </span>new ActionMessage("maxLengthExplanation"));</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>        </span>}</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>        </span>return errors;</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>    </span>}</span>
		</p>
		<p class="altq" style="TEXT-INDENT: 26pt">
				<span style="FONT-FAMILY: 宋体">这里我估计有个</span>
				<span lang="EN-US">hook</span>
				<span style="FONT-FAMILY: 宋体">之类的东西先截获了表单（应该和</span>
				<span lang="EN-US">controller</span>
				<span style="FONT-FAMILY: 宋体">有关），对</span>
				<span lang="EN-US">theFile</span>
				<span style="FONT-FAMILY: 宋体">的尺寸进行校验，然后把结果保存在</span>
				<span lang="EN-US">request scope</span>
				<span style="FONT-FAMILY: 宋体">中。</span>
				<span lang="EN-US">Validate</span>
				<span style="FONT-FAMILY: 宋体">方法只要检查一下这个结果就可以了，如果尺寸超标，表单就不会被提交给</span>
				<span lang="EN-US">Action</span>
				<span style="FONT-FAMILY: 宋体">。</span>
		</p>
		<p class="altq" style="TEXT-INDENT: 26pt">
				<span style="FONT-FAMILY: 宋体">以上算是完成了第一步，从用户那里拿到照片，并保存在临时文件夹当中。接下来要做的就是把照片保存到</span>
				<span lang="EN-US">MySQL</span>
				<span style="FONT-FAMILY: 宋体">数据库中，这个字段我用的是</span>
				<span lang="EN-US">MEDIUMBLOB</span>
				<span style="FONT-FAMILY: 宋体">，因为</span>
				<span lang="EN-US">BLOB</span>
				<span style="FONT-FAMILY: 宋体">最大长度是</span>
				<span lang="EN-US">2<sup>16</sup>-1</span>
				<span style="FONT-FAMILY: 宋体">字节，大约</span>
				<span lang="EN-US">64K</span>
				<span style="FONT-FAMILY: 宋体">；</span>
				<span lang="EN-US">MEDIUMBLOB</span>
				<span style="FONT-FAMILY: 宋体">是</span>
				<span lang="EN-US">2<sup>24</sup>-1</span>
				<span style="FONT-FAMILY: 宋体">字节，约</span>
				<st1:chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="16" unitname="m">
						<span lang="EN-US">16M</span>
				</st1:chmetcnv>
				<span style="FONT-FAMILY: 宋体">，足够用了。保存图片的主要代码如下：</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">/**</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>
						</span>
						<span> </span>* </span>
				<span style="FONT-FAMILY: 宋体">将用户的照片保存在数据表中，添加成功后，删除临时文件夹中的图片。</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>
						</span>
						<span> </span>* @param id </span>
				<span style="FONT-FAMILY: 宋体">用户的身份号，作为图片的标识码</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>
						</span>
						<span> </span>* @param path </span>
				<span style="FONT-FAMILY: 宋体">图片存放的路径。一般存放在一个临时文件夹中。</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>
						</span>
						<span> </span>* @return</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>
						</span>
						<span> </span>*/</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>
						</span>public static void saveImage(int id, String path) throws SQLException{</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>String time = new java.util.Date().toString();</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>Connection conn = null;</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>PreparedStatement pstmt = null;</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>boolean flag = false;</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>// </span>
				<span style="FONT-FAMILY: 宋体">获取连接</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>try {</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>conn = DbManager.getConnection();</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>logger.info(time + ":saveImage() </span>
				<span style="FONT-FAMILY: 宋体">从</span>
				<span lang="EN-US">DbManager</span>
				<span style="FONT-FAMILY: 宋体">数据库连接池获取一个连接。</span>
				<span lang="EN-US">");</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>} catch (SQLException e) {</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>// </span>
				<span style="FONT-FAMILY: 宋体">如果没有能够从</span>
				<span lang="EN-US">DbManager</span>
				<span style="FONT-FAMILY: 宋体">获取连接，此次查询操作失败</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>logger.error(time + ": saveImage()</span>
				<span style="FONT-FAMILY: 宋体">不能获取数据库连接，无法保存图片！</span>
				<span lang="EN-US">");</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>throw new SQLException(":saveImage()</span>
				<span style="FONT-FAMILY: 宋体">不能获取数据库连接，无法保存图片！</span>
				<span lang="EN-US">");</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>}</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>
				</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>//</span>
				<span style="FONT-FAMILY: 宋体">执行查询</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>try {</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>pstmt = conn.prepareStatement("UPDATE hr01 SET hr01_photo=? where hr01_id=?");</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>FileInputStream in = new FileInputStream(path);</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>pstmt.setBinaryStream(1,in,in.available());</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>pstmt.setInt(2,id);<span>     </span><span>    </span></span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>pstmt.executeUpdate();</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>pstmt.executeUpdate("COMMIT");</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>logger.info("</span>
				<span style="FONT-FAMILY: 宋体">图片</span>
				<span lang="EN-US">" + path + " </span>
				<span style="FONT-FAMILY: 宋体">被添加到数据库中！</span>
				<span lang="EN-US">");</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>flag = true;<span>            </span></span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>}catch(IOException e){</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>logger.error("</span>
				<span style="FONT-FAMILY: 宋体">图片</span>
				<span lang="EN-US">" + path + "</span>
				<span style="FONT-FAMILY: 宋体">文件读写错误！请检查文件路径是否正确</span>
				<span lang="EN-US">");</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>throw new SQLException("</span>
				<span style="FONT-FAMILY: 宋体">无法保存图片！</span>
				<span lang="EN-US">");</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>}catch (SQLException ex) {</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>logger.error(new java.util.Date() + "Error:Insert into table."</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>                 </span>+ ex.getMessage());<span>         </span></span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>logger.error("</span>
				<span style="FONT-FAMILY: 宋体">图片</span>
				<span lang="EN-US">" + path +"</span>
				<span style="FONT-FAMILY: 宋体">没有被保存到数据库</span>
				<span lang="EN-US">.");</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>throw new SQLException("</span>
				<span style="FONT-FAMILY: 宋体">图片</span>
				<span lang="EN-US">" + path +"</span>
				<span style="FONT-FAMILY: 宋体">没有被保存到数据库</span>
				<span lang="EN-US">.");</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>
				</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>} finally {</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>try {</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>pstmt.close();</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>conn.close();</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>logger.info("DbHrinfo saveImage() closed the connection created at " + time);</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>} catch (SQLException e) {</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>}</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>}<br />&gt;<span>     </span></span>
		</p>
		<p>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>//</span>
				<span style="FONT-FAMILY: 宋体">图片添加成功以后就删除临时文件夹中的图片数据</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>if(flag == true){</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>File file = new File(path);</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>if(file.exists()){</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>file.delete();</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>}</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>}</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>
						</span>}</span>
		</p>
		<p class="altq" style="TEXT-INDENT: 26pt">
				<span style="FONT-FAMILY: 宋体">需要注意的是</span>
				<span lang="EN-US">pstmt.executeUpdate("COMMIT");</span>
				<span style="FONT-FAMILY: 宋体">这行代码，最初我并没有写这行，程序能顺利执行，日志中也显示“图片××被添加到数据库中”，但是到库里一查询，什么都没有。</span>
				<span lang="EN-US">SQL</span>
				<span style="FONT-FAMILY: 宋体">语句被提交，但是数据库里面没有即时的显示，估计是缓冲区的作用，它把我的</span>
				<span lang="EN-US">SQL</span>
				<span style="FONT-FAMILY: 宋体">语句缓存起来而不是立即提交给数据库。后来我在</span>
				<span lang="EN-US">textpad</span>
				<span style="FONT-FAMILY: 宋体">里面单独执行这段代码，发现不用“</span>
				<span lang="EN-US">COMMIT</span>
				<span style="FONT-FAMILY: 宋体">”</span>
				<span lang="EN-US">SQL</span>
				<span style="FONT-FAMILY: 宋体">语句就立即被提交了。这个地方还没有弄清楚，以后需要继续研究。</span>
		</p>
		<p class="altq" style="TEXT-INDENT: 26pt">
				<span style="FONT-FAMILY: 宋体">功能上做一点小改进，用户提交了照片以后，浏览了一下觉得不满意，只要还没有最终提交数据，当然允许他重新上传一个照片。我们只需要在</span>
				<span lang="EN-US">&lt;img src=””&gt;</span>
				<span style="FONT-FAMILY: 宋体">下面提供一个“重新提交”的链接就可以了。这个链接指向一个</span>
				<span lang="EN-US">AlterImageAction</span>
				<span style="FONT-FAMILY: 宋体">，它的功能就是清除</span>
				<span lang="EN-US">session</span>
				<span style="FONT-FAMILY: 宋体">中用户已经上传照片的标记，并把刚才保存到临时文件夹中的照片删掉，等待用户重新上传。这部分代码如下：</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">public ActionForward execute(ActionMapping mapping,</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>ActionForm form,HttpServletRequest request,</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>HttpServletResponse response) </span>
		</p>
		<p class="AltL" style="MARGIN-LEFT: 8.5pt; TEXT-INDENT: 93.6pt">
				<span lang="EN-US">throws IOException,ServletException{</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>
				</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>HttpSession session = request.getSession();</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>        </span>//1.</span>
				<span style="FONT-FAMILY: 宋体">从临时文件夹中删除图片</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>String filename = (String)session.getAttribute("filename");</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>String path = session.getServletContext().getRealPath("/") </span>
		</p>
		<p class="AltL" style="MARGIN-LEFT: 8.5pt; TEXT-INDENT: 125.1pt">
				<span lang="EN-US">+ "temp\\" + filename;</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>File file = new File(path);</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>if(file.exists()){</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>file.delete();</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>logger.info("</span>
				<span style="FONT-FAMILY: 宋体">文件</span>
				<span lang="EN-US"> " + path + "</span>
				<span style="FONT-FAMILY: 宋体">已经被删除</span>
				<span lang="EN-US">");</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>}</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>
				</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>//2.</span>
				<span style="FONT-FAMILY: 宋体">从</span>
				<span lang="EN-US">session</span>
				<span style="FONT-FAMILY: 宋体">中清除上传图片的标记</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>
				</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>session.removeAttribute("imageuploaded");</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>session.removeAttribute("filename");<span>        </span></span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>return mapping.findForward("next");<span>     </span></span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>
						</span>}</span>
		</p>
		<p class="altq" style="TEXT-INDENT: 26pt">
				<span style="FONT-FAMILY: 宋体">提交和保存到此功德圆满。下次用户想要查询自己的信息的时候，因为临时文件夹中已经没有用户照片，需要从数据库中读取。用一个</span>
				<span lang="EN-US">ShowImageAction</span>
				<span style="FONT-FAMILY: 宋体">来实现这个功能：</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">public ActionForward execute(ActionMapping mapping,</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>ActionForm form, HttpServletRequest request,</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>HttpServletResponse response) </span>
		</p>
		<p class="AltL" style="MARGIN-LEFT: 8.5pt; TEXT-INDENT: 84.6pt">
				<span lang="EN-US">throws IOException,ServletException{</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>//</span>
				<span style="FONT-FAMILY: 宋体">需要的情况下设置数据源</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>if (!DbManager.hasSetDataSource()) {</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>javax.sql.DataSource dataSource;</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>try {</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>dataSource = getDataSource(request);</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>DbManager.setDataSource(dataSource);</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>} catch (Exception e) {</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>logger.error(e.getMessage());</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>mapping.findForward("error");</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>}</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>}</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>
				</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>String photo_no = request.getParameter("photo_no");</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>Connection conn = null;</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>Statement stmt = null;</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>// </span>
				<span style="FONT-FAMILY: 宋体">获取连接</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>try {</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>conn = DbManager.getConnection();</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>logger.info("showimage.jsp </span>
				<span style="FONT-FAMILY: 宋体">从</span>
				<span lang="EN-US">DbManager</span>
				<span style="FONT-FAMILY: 宋体">数据库连接池获取一个连接。</span>
				<span lang="EN-US">");</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>} catch (SQLException e) {</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>// </span>
				<span style="FONT-FAMILY: 宋体">如果没有能够从</span>
				<span lang="EN-US">DbManager</span>
				<span style="FONT-FAMILY: 宋体">获取连接，此次查询操作失败</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>
						</span>
						<span>        </span>logger.error(" showimage.jsp </span>
				<span style="FONT-FAMILY: 宋体">不能获取数据库连接，无法读取图片！</span>
				<span lang="EN-US">");</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>}</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>try {</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>// </span>
				<span style="FONT-FAMILY: 宋体">准备语句执行对象</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>stmt = conn.createStatement();</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>String sql = " SELECT hr01_photo FROM hr01 WHERE hr01_id='" + photo_no + "'";</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>ResultSet rs = stmt.executeQuery(sql);</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>if (rs.next()) {</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>InputStream in = rs.getBinaryStream("hr01_photo");</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>int bytesRead = 0;</span>
		</p>
		<p class="AltL" style="MARGIN-LEFT: 8.5pt; TEXT-INDENT: 98.1pt">
				<span lang="EN-US">byte[] buffer = new byte[8192];</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>response.setContentType("image/jpeg");</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>response.setContentLength(in.available());</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>OutputStream outs = response.getOutputStream();</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>
						<span>                        </span>
				</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>while ((bytesRead = in.read(buffer, 0, 8192)) != -1) {</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>                 </span>outs.write(buffer, 0, bytesRead);</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>}</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>outs.flush();</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>in.close();</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>rs.close();</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>} else {</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>rs.close();</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>response.sendRedirect("error.jsp");</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>}</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>}catch(SQLException e){</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>
				</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>}finally {</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>try{</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>stmt.close();</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>conn.close();</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>}catch(SQLException ex){</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>             </span>
				</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>         </span>}</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>}</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>     </span>return null;</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">
						<span>
						</span>}</span>
		</p>
		<p class="altq" style="TEXT-INDENT: 26pt">
				<span style="FONT-FAMILY: 宋体">以前一直不清楚</span>
				<span lang="EN-US">execute</span>
				<span style="FONT-FAMILY: 宋体">方法中的</span>
				<span lang="EN-US">response</span>
				<span style="FONT-FAMILY: 宋体">参数的用法，因为处理完以后总要</span>
				<span lang="EN-US">redirect</span>
				<span style="FONT-FAMILY: 宋体">到另外一个页面，所以用的最多的就是把数据保存在</span>
				<span lang="EN-US">session</span>
				<span style="FONT-FAMILY: 宋体">中，在另一个页面里再取出来用。这次纯粹是试验性地在</span>
				<span lang="EN-US">response</span>
				<span style="FONT-FAMILY: 宋体">中写入</span>
				<span lang="EN-US">image/jpeg</span>
				<span style="FONT-FAMILY: 宋体">内容，然后返回一个</span>
				<span lang="EN-US">null</span>
				<span style="FONT-FAMILY: 宋体">值。最后的执行结果跟我预期的一样，在浏览器中直接显示从数据库中读出的图片。那么接下来就很好做了，只需要在</span>
				<span lang="EN-US">JSP</span>
				<span style="FONT-FAMILY: 宋体">页面中设置一个</span>
				<span lang="EN-US">&lt;image&gt;</span>
				<span style="FONT-FAMILY: 宋体">标签，指向这个</span>
				<span lang="EN-US">Action</span>
				<span style="FONT-FAMILY: 宋体">就可以，当然，在这之前需要在</span>
				<span lang="EN-US">struts-config.xml</span>
				<span style="FONT-FAMILY: 宋体">中先部署这个</span>
				<span lang="EN-US">Action</span>
				<span style="FONT-FAMILY: 宋体">：</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">&lt;action path="/ShowImage"<o:p></o:p></span>
		</p>
		<p class="AltL" style="MARGIN-LEFT: 8.5pt; TEXT-INDENT: 62.1pt">
				<span lang="EN-US">
						<span> </span>type="software.action.ShowImageAction"&gt;&lt;/action&gt;</span>
		</p>
		<p class="altq" style="TEXT-INDENT: 26pt">
				<span style="FONT-FAMILY: 宋体">然后在</span>
				<span lang="EN-US">JSP</span>
				<span style="FONT-FAMILY: 宋体">页面中引用这个</span>
				<span lang="EN-US">Action</span>
				<span style="FONT-FAMILY: 宋体">来显示图像</span>
				<span lang="EN-US">:</span>
		</p>
		<p class="AltL">
				<span lang="EN-US">&lt;img src="/tibet/ShowImage.do?photo_no=666542"&gt;<o:p></o:p></span>
		</p>
		<p class="altq" style="TEXT-INDENT: 26pt">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<br />&lt; p&gt;<img src ="http://www.blogjava.net/WshmAndLily/aggbug/88347.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2006-12-17 16:30 <a href="http://www.blogjava.net/WshmAndLily/articles/88347.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Mysql与JSP网页中文乱码问题的解决方案(转载)</title><link>http://www.blogjava.net/WshmAndLily/articles/86640.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Sun, 10 Dec 2006 02:10:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/86640.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/86640.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/86640.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/86640.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/86640.html</trackback:ping><description><![CDATA[
		<p>自从以前学习JSP开始，中文乱码问题就一直不断，苦不堪言。这次在项目开始之前，我们要解决的第一个问题就是把mysql的中文乱码问题搞定。经过多天的努力，终于成功的解决了中文乱码问题，特写在这里，以备后用。 <br /><br />软件及环境：Windows XP(2000), j2sdk1.4.2, Tomcat 5.0.25, mysql 4.1, EMS Mysql Manager 2(方便建表，版本2.8.5.1)，驱动为mysql-connector-java-3.1.4-beta-bin.jar。 <br /><br />目标：在该环境下，实现中文的正常显示，读取与插入数据库。 <br /><br />注：我只在此环境下测试通过，别的系统及不同版本未测试 <br /><img src="http://blogteam.bokee.com/pub/neweditor/editor/images/smiley/1/24.gif" /><br />要点：统一字符集（JSP页面编码，mysql建库时字符集选择，连接数据库URL，request设定等） <br />-------我自己的<br />/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;<br />/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;<br />/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;<br /><font style="BACKGROUND-COLOR: #ffffff" color="#ff0000">/*!40101 SET NAMES 'gbk' */;</font></p>
		<p>#drop database named teckoparts</p>
		<p>drop database if exists teckoparts;</p>
		<p>#create database named teckoparts</p>
		<p>create database teckoparts;</p>
		<p>#use database teckoparts</p>
		<p>use teckoparts;</p>
		<p>#create table catalog<br />create table catalog<br />(<br /> id varchar(255) not null primary key,<br /> parentId varchar(128) not null,<br /> text_en  varchar(256) not null,<br /> text_hk  varchar(256) ,<br /> text_ch  varchar(256),<br /> info     varchar(1024)<br />) ENGINE=InnoDB <font color="#ff0000">DEFAULT CHARSET=gbk;</font></p>
		<p>insert into catalog values('1','0','teckoparts','達藝零件','达艺零件','总目录');</p>
		<p>#create table admin<br />create table admin<br />(<br /> id int(11) not null primary key,<br /> userName  varchar(128) not null,<br /> passWord  varchar(12)  not null,<br /> role   char(1)<br />) ENGINE=InnoDB DEFAULT CHARSET=gbk;</p>
		<p>insert into admin values(1,'admin','admin','1');</p>
		<p>/*!40101 SET <a href="mailto:CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT">CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT</a> */;<br />/*!40101 SET <a href="mailto:CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS">CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS</a> */;<br />/*!40101 SET <a href="mailto:COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION">COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION</a> */;<br /><br />下面我以GBK为例讲解。如果要使用utf-8，只要在相应的GBK处换成utf-8即可 <br /><br />--------------------------- 步骤1 以GBK字符集建库建表 ------------------------------------- <br /><br />我使用EMS来建mysql的数据库及表，因为它是图形界面，方便操作（就像SQL SERVER 2000中的企业管理器一样）。 <br /><br />建库时，从EMS菜单中选create Database...新建一个数据库，CharacterSet选gbk_bin(另一个gbk_chinese_ci不知道与这个有什么区别，我找资料也没有找到。如果你知道，请告诉我，我补充在这里)。不要把工具栏上有一个加号和数据库模样的图标当成新建数据库了，那个新注册一个已经存在的数据库。 <br />后面建表时，也要选择同样的字符集。 <br /><br />建好后，此时不要用EMS向里面插入数据，否则你看到的中文依然是乱码。 <br /><br />--------------------------- 步骤2 连接数据库的URL后加些参数 ------------------------------- <br /><br />假设我新建的数据库是testdb，那么我连接数据库的url应该为： <br /><br />jdbc:mysql://localhost:3306/testdb?useUnicode=true&amp;characterEncoding=gbk <br /><br />此时要注意：如果我是把这个url写在JAVA代码中，就直接这样写。但如果是在xml配置文件中（如struts-config.xml,web.xml等），要把其中的&amp;改为&amp;amp;才行，否则会出错。也就是： <br /><br />jdbc:mysql://localhost:3306/testdb?useUnicode=true&amp;amp;characterEncoding=gbk <br /><br />--------------------------- 步骤3 每个JSP页面都要声明该中文字符集 ---------------------------- <br /><br />在每个JSP页面的最上面都加上一句 <br /><br />&lt;%@ page language="java" contentType="text/html;charset=GBK" %&gt; <br /><br />这样才能保证JSP页面中的中文显示正常 <br /><br />--------------------------- 步骤4 加一个传递参数时设定request字符集的filter类 ----------------------- <br /><br />因为网络中字符在传递的时候，都是统一以iso-8859-1的编码传递，所以我们必须对request重新设定字符集，才能正常显示中文。如果采用filter类来实现，我们不用在每次取中文参数时都要重新设定。 <br /><br />filter类的内容： <br /><br />/* <br />* ==================================================================== <br />* <br />* JavaWebStudio 开源项目 <br />* <br />* Struts_db v0.1 <br />* <br />* ==================================================================== <br />*/ <br />package com.strutsLogin.util; <br /><br />import java.io.IOException; <br /><br />import javax.servlet.Filter; <br />import javax.servlet.FilterChain; <br />import javax.servlet.FilterConfig; <br />import javax.servlet.ServletException; <br />import javax.servlet.ServletRequest; <br />import javax.servlet.ServletResponse; <br /><br />/** <br />* 中文过滤器 <br />*/ <br />public class SetCharacterEncodingFilter implements Filter { <br /><br />// ----------------------------------------------------- Instance Variables <br /><br />/** <br />* The default character encoding to set for requests that pass through <br />* this filter. <br />*/ <br />protected String encoding = null; <br /><br />/** <br />* The filter configuration object we are associated with. If this value <br />* is null, this filter instance is not currently configured. <br />*/ <br />protected FilterConfig filterConfig = null; <br /><br />/** <br />* Should a character encoding specified by the client be ignored? <br />*/ <br />protected boolean ignore = true; <br /><br />// --------------------------------------------------------- Public Methods <br /><br />/** <br />* Take this filter out of service. <br />*/ <br />public void destroy() { <br /><br />this.encoding = null; <br />this.filterConfig = null; <br /><br />} <br /><br />/** <br />* Select and set (if specified) the character encoding to be used to <br />* interpret request parameters for this request. <br />* <br />* @param request The servlet request we are processing <br />* @param result The servlet response we are creating <br />* @param chain The filter chain we are processing <br />* <br />* @exception IOException if an input/output error occurs <br />* @exception ServletException if a servlet error occurs <br />*/ <br />public void doFilter(ServletRequest request, ServletResponse response, <br />FilterChain chain) <br />throws IOException, ServletException { <br /><br />// Conditionally select and set the character encoding to be used <br />if (ignore || (request.getCharacterEncoding() == null)) { <br />String encoding = selectEncoding(request); <br />if (encoding != null) <br />request.setCharacterEncoding(encoding); <br />} <br /><br />// Pass control on to the next filter <br />chain.doFilter(request, response); <br /><br />} <br /><br />/** <br />* Place this filter into service. <br />* <br />* @param filterConfig The filter configuration object <br />*/ <br />public void init(FilterConfig filterConfig) throws ServletException { <br /><br />this.filterConfig = filterConfig; <br />this.encoding = filterConfig.getInitParameter("encoding"); <br />String value = filterConfig.getInitParameter("ignore"); <br />if (value == null) <br />this.ignore = true; <br />else if (value.equalsIgnoreCase("true")) <br />this.ignore = true; <br />else if (value.equalsIgnoreCase("yes")) <br />this.ignore = true; <br />else <br />this.ignore = false; <br /><br />} <br /><br />// ------------------------------------------------------ Protected Methods <br /><br />/** <br />* Select an appropriate character encoding to be used, based on the <br />* characteristics of the current request and/or filter initialization <br />* parameters. If no character encoding should be set, return <br />* &lt;code&gt;null&lt;/code&gt;. <br />* &lt;p&gt; <br />* The default implementation unconditionally returns the value configured <br />* by the &lt;strong&gt;encoding&lt;/strong&gt; initialization parameter for this <br />* filter. <br />* <br />* @param request The servlet request we are processing <br />*/ <br />protected String selectEncoding(ServletRequest request) { <br /><br />return (this.encoding); <br /><br />} <br /><br />}//EOC <br /><br /><br />该代码来自于www.javawebstudio.com，特此感谢！ <br /><br />然后我们在web.xml中加一些配置，就可以了，配置如下： <br /><br />&lt;filter&gt; <br />&lt;filter-name&gt;Set Character Encoding&lt;/filter-name&gt; <br />&lt;filter-class&gt;javawebstudio.struts_db.SetCharacterEncodingFilter&lt;/filter-class&gt; <br />&lt;init-param&gt; <br />&lt;param-name&gt;encoding&lt;/param-name&gt; <br />&lt;param-value&gt;GBK&lt;/param-value&gt; <br />&lt;/init-param&gt; <br />&lt;init-param&gt; <br />&lt;param-name&gt;ignore&lt;/param-name&gt; <br />&lt;param-value&gt;true&lt;/param-value&gt; <br />&lt;/init-param&gt; <br />&lt;/filter&gt; <br /><br />&lt;filter-mapping&gt; <br />&lt;filter-name&gt;Set Character Encoding&lt;/filter-name&gt; <br />&lt;servlet-name&gt;action&lt;/servlet-name&gt; <br />&lt;/filter-mapping&gt; <br /><br />放在web.xml的合适位置。一般在最后，&lt;jsp-config&gt;标签之前(如果有的话) <br /><br />经过以上步骤，JSP和mysql的中文显示及插入就都正常了。在STRUTS中也正常。 <br /><br />但是，此时如果你用EMS或mysql的命令行控制台来看表中的数据，却发现它们都是????。这是怎么回事呢？ <br /><br />不用担心，只要我们运行下面的这几行命令，就能看到正常的中文了! <br /><br />SET character_set_client = gbk; <br />SET character_set_connection = gbk; <br />SET character_set_database = gbk; <br />SET character_set_results = gbk; <br />SET character_set_server = gbk; <br /><br />SET collation_connection = gbk_bin; <br />SET collation_database = gbk_bin; <br />SET collation_server = gbk_bin; <br /><br />如果你用的是mysql的命令行，则直接输入就好。 <br /><br />如果是EMS，则在工具栏中有一个Show SQL Editor按钮,点一下，把上面的命令输入，再按一个"execute"的按钮，就行了! <br /><br />而且在这种情况下，你可以甚至可以用中文名来建数据库，表名和字段名!!!! <br /><br />---------------------------------------------------------------------------------------------------- <br /><br />但是有一点要特别注意! <br /><br />像GBK，UTF-8这样的名字，在mysql与JAVA中有不同的规定，写的时候要格外注意，否则会出错。 <br /><br />比如GBK，在JAVA中要写成GBK，但在mysql中要写成gbk(连接数据库的URL) <br /><br />比如UTF-8，在JAVA中要写成UTF-8，但在Mysql中要写成utf8 <br /><br />其它的字集符也有类似的区别 </p>
<img src ="http://www.blogjava.net/WshmAndLily/aggbug/86640.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2006-12-10 10:10 <a href="http://www.blogjava.net/WshmAndLily/articles/86640.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MySQL Join詳解</title><link>http://www.blogjava.net/WshmAndLily/articles/76554.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Sat, 21 Oct 2006 09:30:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/76554.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/76554.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/76554.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/76554.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/76554.html</trackback:ping><description><![CDATA[還是先 Create table 吧
<p>create table emp(<br />id int not null primary key,<br />name varchar(10)<br />);</p><p>create table emp_dept(<br />dept_id varchar(4) not null,<br />emp_id int not null,<br />emp_name varchar(10),<br />primary key (dept_id,emp_id));<br /></p><p>insert into emp() values<br />(1,"Dennis-1"),<br />(2,"Dennis-2"),<br />(3,"Dennis-3"),<br />(4,"Dennis-4"),<br />(5,"Dennis-5"),<br />(6,"Dennis-6"),<br />(7,"Dennis-7"),<br />(8,"Dennis-8"),<br />(9,"Dennis-9"),<br />(10,"Dennis-10");</p><p>insert into emp_dept() values<br />("R&amp;D",1,"Dennis-1"),<br />("DEv",2,"Dennis-2"),<br />("R&amp;D",3,"Dennis-3"),<br />("Test",4,"Dennis-4"),<br />("Test",5,"Dennis-5");</p><p>&gt;&gt; left join<br />-------------<br />select a.id,a.name,b.dept_id<br />from emp a left join emp_dept b on (a.id=b.emp_id);</p><p># 挑出左邊的 table emp 中的所有資料,即使 emp_dept 中沒有的資料也挑出來,沒有的就用 NULL 來顯示,<br /># 也即顯示資料是以左邊的 table emp 中的資料為基礎</p><p>mysql&gt; select a.id,a.name,b.dept_id<br />-&gt; from emp a left join emp_dept b on (a.id=b.emp_id);<br />+----+-----------+---------+<br />| id | name | dept_id |<br />+----+-----------+---------+<br />| 1 | Dennis-1 | R&amp;D |<br />| 2 | Dennis-2 | DEv |<br />| 3 | Dennis-3 | R&amp;D |<br />| 4 | Dennis-4 | Test |<br />| 5 | Dennis-5 | Test |<br />| 6 | Dennis-6 | NULL |<br />| 7 | Dennis-7 | NULL |<br />| 8 | Dennis-8 | NULL |<br />| 9 | Dennis-9 | NULL |<br />| 10 | Dennis-10 | NULL |<br />+----+-----------+---------+</p><p># 挑出 table emp 中有而 table emp_dept 中沒有的人員資料<br />select a.id,a.name,b.dept_id<br />from emp a left join emp_dept b on (a.id=b.emp_id)<br />where b.dept_id IS NULL;</p><p>mysql&gt; select a.id,a.name,b.dept_id<br />-&gt; from emp a left join emp_dept b on (a.id=b.emp_id)<br />-&gt; where b.dept_id IS NULL;<br />+----+-----------+---------+<br />| id | name | dept_id |<br />+----+-----------+---------+<br />| 6 | Dennis-6 | NULL |<br />| 7 | Dennis-7 | NULL |<br />| 8 | Dennis-8 | NULL |<br />| 9 | Dennis-9 | NULL |<br />| 10 | Dennis-10 | NULL |<br />+----+-----------+---------+</p><p># 把 table emp_dept 放在左邊的情形(當然以 emp_dept 中的數據為基礎來顯示資料,emp 中比emp_dept 中多的資料也就不會顯示出來了):</p><p>select a.id,a.name,b.dept_id<br />from emp_dept b left join emp a on (a.id=b.emp_id);<br />mysql&gt; select a.id,a.name,b.dept_id<br />-&gt; from emp_dept b left join emp a on (a.id=b.emp_id);<br />+------+----------+---------+<br />| id | name | dept_id |<br />+------+----------+---------+<br />| 2 | Dennis-2 | DEv |<br />| 1 | Dennis-1 | R&amp;D |<br />| 3 | Dennis-3 | R&amp;D |<br />| 4 | Dennis-4 | Test |<br />| 5 | Dennis-5 | Test |<br />+------+----------+---------+</p><p>&gt;&gt; right join<br />---------------<br />select a.id,a.name,b.dept_id<br />from emp a right join emp_dept b on (a.id=b.emp_id);<br /># 挑資料時以右邊 table emp_dept 中的資料為基礎來顯示資料</p><p>mysql&gt; select a.id,a.name,b.dept_id<br />-&gt; from emp a right join emp_dept b on (a.id=b.emp_id);<br />+------+----------+---------+<br />| id | name | dept_id |<br />+------+----------+---------+<br />| 2 | Dennis-2 | DEv |<br />| 1 | Dennis-1 | R&amp;D |<br />| 3 | Dennis-3 | R&amp;D |<br />| 4 | Dennis-4 | Test |<br />| 5 | Dennis-5 | Test |<br />+------+----------+---------+<br />5 rows in set (0.00 sec)</p><p># 我們再把 table 的位置交換一下,再用 right join 試試</p><p>select a.id,a.name,b.dept_id<br />from emp_dept b right join emp a on (a.id=b.emp_id);</p><p>mysql&gt; select a.id,a.name,b.dept_id<br />-&gt; from emp_dept b right join emp a on (a.id=b.emp_id);<br />+----+-----------+---------+<br />| id | name | dept_id |<br />+----+-----------+---------+<br />| 1 | Dennis-1 | R&amp;D |<br />| 2 | Dennis-2 | DEv |<br />| 3 | Dennis-3 | R&amp;D |<br />| 4 | Dennis-4 | Test |<br />| 5 | Dennis-5 | Test |<br />| 6 | Dennis-6 | NULL |<br />| 7 | Dennis-7 | NULL |<br />| 8 | Dennis-8 | NULL |<br />| 9 | Dennis-9 | NULL |<br />| 10 | Dennis-10 | NULL |<br />+----+-----------+---------+</p><p># 是不是和 left join 一樣了?</p><p>&gt;&gt; direct join<br />--------------<br /># 如果用right join 同不用 Join 直接挑資料是相同的,它等介於以下的指令</p><p>select a.id,a.name,b.dept_id<br />from emp a ,emp_dept b <br />where a.id=b.emp_id;<br /></p><p>mysql&gt; select a.id,a.name,b.dept_id<br />-&gt; from emp a ,emp_dept b<br />-&gt; where a.id=b.emp_id;<br />+----+----------+---------+<br />| id | name | dept_id |<br />+----+----------+---------+<br />| 2 | Dennis-2 | DEv |<br />| 1 | Dennis-1 | R&amp;D |<br />| 3 | Dennis-3 | R&amp;D |<br />| 4 | Dennis-4 | Test |<br />| 5 | Dennis-5 | Test |<br />+----+----------+---------+<br /></p><p>怎樣,弄明白了嗎?</p><img src ="http://www.blogjava.net/WshmAndLily/aggbug/76554.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2006-10-21 17:30 <a href="http://www.blogjava.net/WshmAndLily/articles/76554.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MySQL语法语句大全</title><link>http://www.blogjava.net/WshmAndLily/articles/76553.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Sat, 21 Oct 2006 09:24:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/76553.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/76553.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/76553.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/76553.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/76553.html</trackback:ping><description><![CDATA[
		<p>一、SQL速成  <br />结构查询语言(SQL)是用于查询关系数据库的标准语言，它包括若干关键字和一致的语法，便于数据库元件(如表、索引、字段等)的建立和操纵。  <br />以下是一些重要的SQL快速参考，有关SQL的语法和在标准SQL上增加的特性，请查询MySQL手册。  <br />1．创建表  <br />表是数据库的最基本元素之一，表与表之间可以相互独立，也可以相互关联。创建表的基本语法如下：  <br />create table table_name  <br />(column_name data无效 {identity |null|not null}，  <br />…)  <br />其中参数table_name和column_name必须满足用户数据库中的识别器(identifier)的要求，参数data无效是一个标准的SQL类型或由用户数据库提供的类型。用户要使用non-null从句为各字段输入数据。  <br />create table还有一些其他选项，如创建临时表和使用select子句从其他的表中读取某些字段组成新表等。还有，在创建表是可用PRIMARY KEY、KEY、INDEX等标识符设定某些字段为主键或索引等。  <br />书写上要注意：  <br />在一对圆括号里的列出完整的字段清单。  <br />字段名间用逗号隔开。  <br />字段名间的逗号后要加一个空格。  <br />最后一个字段名后不用逗号。  <br />所有的SQL陈述都以分号";"结束。  <br />例：  <br />mysql&gt; CREATE TABLE test (blob_col BLOB， index(blob_col(10)));  </p>
		<p>2．创建索引  <br />索引用于对数据库的查询。一般数据库建有多种索引方案，每种方案都精于某一特定的查询类。索引可以加速对数据库的查询过程。创建索引的基本语法如下：  <br />create index index_name  <br />on table_name (col_name[(length)]，... )  <br />例：  <br />mysql&gt; CREATE INDEX part_of_name ON customer (name(10));  </p>
		<p>3．改变表结构  <br />在数据库的使用过程中，有时需要改变它的表结构，包括改变字段名，甚至改变不同数据库字段间的关系。可以实现上述改变的命令是alter，其基本语法如下：  <br />alter table table_name alter_spec [， alter_spec ...]  <br />例：  <br />mysql&gt; ALTER TABLE t1 CHANGE a b INTEGER;  </p>
		<p>4．删除数据对象  <br />很多数据库是动态使用的，有时可能需要删除某个表或索引。大多数数据库对象可以下面的命令删除：  <br />drop object_name  <br />mysql&gt; DROP TABLE tb1;  </p>
		<p>5．执行查询  <br />查询是使用最多的SQL命令。查询数据库需要凭借结构、索引和字段类型等因素。大多数数据库含有一个优化器(optimizer)，把用户的查询语句转换成可选的形式，以提高查询效率。  <br />值得注意的是MySQL不支持SQL92标准的嵌套的where子句，即它只支持一个where子句。其基本语法如下：  <br />SELECT [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [HIGH_PRIORITY]  <br />[DISTINCT | DISTINCTROW | ALL]  <br />select_expression，...  <br />[INTO {OUTFILE | DUMPFILE} ’file_name’ export_options]  <br />[FROM table_references  <br />][WHERE where_definition]  <br />[GROUP BY col_name，...]  <br />[HAVING where_definition]  <br />[ORDER BY {unsigned_integer | col_name | formula} ][ASC | DESC] ，...]  <br />[LIMIT ][offset，] rows]  <br />[PROCEDURE procedure_name] ]  <br />其中where从句是定义选择标准的地方，where_definition可以有不同的格式，但都遵循下面的形式：  <br />字段名操作表达式  <br />字段名操作字段名  <br />在第一种形式下，标准把字段的值与表达式进行比较；在第二种形式下，把两个字段的值进行比较。根据所比较的数据类型，search_condition中的操作可能选以下几种：  <br />= 检查是否相等  <br />！= 检查是否不等  </p>
		<p>&gt; (或&gt;=) 检查左边值是否大于(或大于等于)右边值  <br />&lt; (或&lt;=) 检查左边值是否小于(或小于等于)右边值  <br />[not] between 检查左边值是否在某个范围内  <br />[not] in 检查左边是否某个特定集的成员  <br />[not] like 检查左边是否为右边的子串  <br />is [not] null 检查左边是否为空值  <br />在这里，可以用通配符_代表任何一个字符，％代表任何字符串。使用关键字&lt;AND&gt;、&lt;OR&gt;和&lt;NOT&gt;可以生成复杂的词，它们运行检查时使用布尔表达式的多重标准集。  <br />例：  <br />mysql&gt; select t1.name， t2.salary from employee AS t1， info AS t2 where t1.name = t2.name;  <br />mysql&gt; select college， region， seed from tournament  <br />ORDER BY region， seed;  <br />mysql&gt; select col_name from tbl_name WHERE col_name &gt; 0;  </p>
		<p>6．修改表中数据  <br />在使用数据库过程中，往往要修改其表中的数据，比如往表中添加新数据，删除表中原有数据，或对表中原有数据进行更改。它们的基本语法如下：  <br />数据添加：  <br />insert [into] table_name [(column(s))]  <br />values (expression(s))  <br />例：  <br />mysql&gt; INSERT INTO tbl_name (col1，col2) VALUES(15，col1*2);  <br />数据删除：  <br />删除 from table_name where search_condition  <br />数据更改：  <br />更新 table_name  <br />set column1=expression1，  <br />column2=expression2，…  <br />where search_condition  </p>
		<p>7．数据库切换  <br />当存在多个数据库时，可以用下面的命令定义用户想使用的数据库：  <br />use database_name  </p>
		<p>8．统计函数  <br />SQL有一些统计函数，它们对于生成数据表格很有帮助。下面介绍几个常用的统计函数：  <br />sum (exepression) 计算表达式的和  <br />avg (exepression) 计算表达式的平均值  <br />count (exepression) 对表达式进行简单的计数  <br />count (*) 统计记录数  <br />max (exepression) 求最大值  <br />min (exepression) 求最小值  <br />其中exepression为任何有效的SQL表达式，它可以是一个或多个记录，也可以是别的SQL函数的组合。  </p>
		<p>二、MySQL使用导引  <br />1．运用MySQL建立新数据库  <br />在shell下运行：  <br />＄&gt;mysqladmin create database01  <br />Database "database01" created.  </p>
		<p>2．启动MySQL  <br />在shell下运行：  <br />＄&gt;mysql  <br />Welcome to the MySQL monitor. Commands end with ; or g.  <br />Your MySQL connection id is 22 to server version: 3.21. 29a-gamma-debug  <br />无效 ’help’ for help.  </p>
		<p>3．更换数据库  <br />mysql&gt;use database01  <br />database changed.  </p>
		<p>4．创建表  <br />mysql&gt;create table table01 (field01 integer， field02 char(10));  <br />Query OK， 0 rows affected (0.00 sec)  </p>
		<p>5．列出表清单  <br />mysql&gt;show tables;  <br />Tables in database01  <br />Table01  <br />table02  </p>
		<p>6．列出表中的字段清单  <br />mysql&gt;show columns from table01;  <br />Field 无效 Null Key Default Extra  <br />field01 int(11) YES  <br />field02 char(10) YES  </p>
		<p>7．表的数据填写  <br />插入数据  <br />mysql&gt;insert into table01 (field01， field02) values (1， ’first’);  <br />Query OK， 1 row affected (0.00 sec)  </p>
		<p>8．字段的增加  <br />...一次一个字段  <br />mysql&gt;alter table table01 add column field03 char(20);  <br />Query OK， l row affected (0.04 sec)  <br />Records: 1 Duplicates: 0 Warnings: 0  <br />...一次多个字段  <br />mysql&gt;alter table table01 add column field04 date， add column field05 time;  <br />Query OK， l row affected (0.04 sec)  <br />Records: 1 Duplicates: 0 Warnings: 0  <br />注意：每一列都必须以"add column"重新开始。  <br />它运行了吗？让我们看看。  <br />mysql&gt;select * from table01;  <br />field01 field02 field03 field04 field05  <br />1 first NULL NULL NULL  </p>
		<p>9．多行命令输入  <br />MySQL命令行界面允许把陈述作为一行输入，也可以把它展开为多行输入。这两者之间并没有语法上的区别。使用多行输入，你可以将SQL陈述一步步分解，从而使你更容易理解。  <br />在多行方式下，注释器把每一行都添加到前面的行后，直到你用分号";"来结束这个SQL陈述。一旦键入分号并按回车键，这个陈述即被执行。  <br />下面的例子是同一个严格的SQL陈述的两种输入方法：  <br />单行输入  <br />Mysql&gt;create table table33 (field01 integer， field02 char(30));  <br />多行输入  <br />Mysql&gt;create table table33  <br />-&gt;(field01  <br />-&gt;integer，  <br />-&gt;field02  <br />-&gt;char(30));  <br />注意不能将单词断开，如：  <br />正确  <br />mysql&gt;create table table33  <br />-&gt;( field01  <br />-&gt;integer，  <br />-&gt;field02  <br />-&gt;char(30));  <br />错误  <br />mysql&gt;create table table33  <br />-&gt;( field01 inte  <br />-&gt;ger，  <br />-&gt;field02  <br />-&gt;char(30));  <br />当插入或更改数据时，不能将字段的字符串展开到多行里，否则硬回车将被储存到数据中：  <br />标准操作  <br />mysql&gt;insert into table33 (field02)  <br />-&gt;values  <br />-&gt;(’who thought of foo?’);  <br />硬回车储存到数据中  <br />mysql&gt;insert into table33 (field02)  <br />-&gt;values  <br />-&gt;(’who thought  <br />-&gt;of foo?’);  <br />结果如下：  <br />mysql&gt;select * from table33;  <br />field01 field02  <br />NULL who thought of foo?  <br />NULL who thought  <br />Of foo?  </p>
		<p>10．表的数据嵌入  <br />mysql&gt;insert into table01 (field01， field02， field03， field04， field05) values  <br />-&gt;(2， ’second’， ’another’， ’1999-10-23’， ’10:30:00’);  <br />Query OK， 1 row affected (0.00 sec)  <br />标准日期格式是"yyyy-mm-dd"。  <br />标准时间格式是"hh:mm:ss"。  <br />引号内要求所给的是上述的标准日期和时间格式。  <br />日期也可以"yyyymmdd"形式，时间也可以"hhmmss"形式输入，但其值不需要再加引号。  <br />数字值不需要加引号。这种保存与数据类型无关，这些数据类型都有格式化的专栏来包含(例如：文本，日期，时间，整数等)。  <br />MySQL有一个很有用的命令缓冲区。它保存着你目前已经键入的SQL语句利用它，对于相同的命令，你就不必一遍又一遍地重复输入。下一步我们就来看这样的一个例子。  <br />利用命令缓冲区(及任意的日期和时间格式)增加另一个数据  <br />按两次键盘上的向上箭头键。  <br />回车。  <br />在圆括号内输入新的值，并以分号结尾。  <br />(3， ’a third’， ’more’， 19991024， 103004);  <br />回车。  <br />新值存在里面了吗？  <br />mysql&gt;select * from table01;  <br />field01 field02 field03 field04 field05  <br />1 first NULL NULL NULL  <br />2 second another 1999-10-23 10:30:00  <br />3 a third more 1999-10-24 10:30:04  </p>
		<p>11．表的数据更新  <br />一次修改一个字段  <br />再次注意语法。文本需要加引号但数字不要。  <br />mysql&gt;更新 table01 set field03=’new info’ where field01=1;  <br />Query OK， 1 row affected (0.00 sec)  <br />一次改变多个字段  <br />记住在每一个更新的字段间用逗号隔开。  <br />mysql&gt;更新 table01 set field04=19991022， field05=062218 where field01=1;  <br />Query OK， 1 row affected (0.00 sec)  <br />一次更新多个数据  <br />mysql&gt;更新 table01 set field05=152901 where field04&gt;19990101;  <br />Query OK， 3 rows affected (0.00 sec)  </p>
		<p>12．删除数据  <br />mysql&gt;删除 from table01 where field01=3;  <br />Query OK， 1 row affected (0.00 sec)  </p>
		<p>13．退出  <br />mysql&gt;quit  <br />Bye  <br />现在你已经了解了一些运行MySQL中的数据库的根本命令。由于MySQL是通过执行SQL调用来操作的，在你的处理过程中需要一个强有力工具的充足的数组。例如，通过联接相关的字段，你可以同时显示几个表中的数据。同样，SQL允许综合显示、更新或者删除多个符合具体标准的数据。如果你还想精通掌握它，下一步就要学习所有SQL的知识。</p>
<img src ="http://www.blogjava.net/WshmAndLily/aggbug/76553.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2006-10-21 17:24 <a href="http://www.blogjava.net/WshmAndLily/articles/76553.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习MySQL多表操作和备份处理</title><link>http://www.blogjava.net/WshmAndLily/articles/51388.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Thu, 08 Jun 2006 08:23:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/51388.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/51388.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/51388.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/51388.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/51388.html</trackback:ping><description><![CDATA[
		<strong>多表操作</strong>
		<br />
		<br />    在一个数据库中，可能存在多个表，这些表都是相互关联的。我们继续使用前面的例子。前面建立的表中包含了员工的一些基本信息，如姓名、性别、出生日期、出生地。我们再创建一个表，该表用于描述员工所发表的文章，内容包括作者姓名、文章标题、发表日期。 <br /><br />    1、查看第一个表mytable的内容： <br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>mysql&gt; select * from mytable; 
+----------+------+------------+-----------+ 
| name | sex | birth | birthaddr | 
+----------+------+------------+-----------+ 
| abccs |f | 1977-07-07 | china | 
| mary |f | 1978-12-12 | usa | 
| tom |m | 1970-09-02 | usa | 
+----------+------+------------+-----------+</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />    2、创建第二个表title（包括作者、文章标题、发表日期）: <br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>mysql&gt; create table title(writer varchar(20) not null, 
-&gt; title varchar(40) not null, 
-&gt; senddate date); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;向该表中填加记录，最后表的内容如下： 
&lt;ccid_nobr&gt;
&lt;table width="400" border="1" cellspacing="0" cellpadding="2" 
 bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"&gt;
&lt;tr&gt;
    &lt;td bgcolor="e6e6e6" class="code" style="font-size:9pt"&gt;
    &lt;pre&gt;&lt;ccid_code&gt;  mysql&gt; select * from title; 
+--------+-------+------------+ 
| writer | title | senddate | 
+--------+-------+------------+ 
| abccs | a1 | 2000-01-23 | 
| mary | b1 | 1998-03-21 | 
| abccs | a2 | 2000-12-04 | 
| tom | c1 | 1992-05-16 | 
| tom | c2 | 1999-12-12 | 
+--------+-------+------------+ 
5 rows in set (0.00sec)</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />    3、多表查询 <br /><br />    现在我们有了两个表: mytable 和 title。利用这两个表我们可以进行组合查询： <br />    例如我们要查询作者abccs的姓名、性别、文章： <br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>mysql&gt; SELECT name,sex,title FROM mytable,title 
-&gt; WHERE name=writer AND name=′abccs′; 
+-------+------+-------+ 
| name | sex | title | 
+-------+------+-------+ 
| abccs | f | a1 | 
| abccs | f | a2 | 
+-------+------+-------+</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />    上面例子中，由于作者姓名、性别、文章记录在两个不同表内，因此必须使用组合来进行查询。必须要指定一个表中的记录如何与其它表中的记录进行匹配。 <br /><br />    注意：如果第二个表title中的writer列也取名为name（与mytable表中的name列相同）而不是writer时，就必须用mytable.name和title.name表示，以示区别。 <br /><br />    再举一个例子，用于查询文章a2的作者、出生地和出生日期： <br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>mysql&gt; select title,writer,birthaddr,birth from mytable,title 
-&gt; where mytable.name=title.writer and title=′a2′; 
+-------+--------+-----------+------------+ 
| title | writer | birthaddr | birth | 
+-------+--------+-----------+------------+ 
| a2 | abccs | china | 1977-07-07 | 
+-------+--------+-----------+------------+</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />    <b>修改和备份、批处理 </b><br />    有时我们要对数据库表和数据库进行修改和删除，可以用如下方法实现： <br /><br />    1、增加一列： <br />    如在前面例子中的mytable表中增加一列表示是否单身single: <br />    mysql&gt; alter table mytable add column single char(1); <br /><br />    2、修改记录 <br />    将abccs的single记录修改为“y”： <br />    mysql&gt; update mytable set single=′y′ where name=′abccs′;     现在来看看发生了什么： <br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>mysql&gt; select * from mytable; 
+----------+------+------------+-----------+--------+ 
| name | sex | birth | birthaddr | single | 
+----------+------+------------+-----------+--------+ 
| abccs |f | 1977-07-07 | china | y | 
| mary |f | 1978-12-12 | usa | NULL | 
| tom |m | 1970-09-02 | usa | NULL | 
+----------+------+------------+-----------+--------+</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />    3、增加记录 <br />    前面已经讲过如何增加一条记录，为便于查看，重复与此： <br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>mysql&gt; insert into mytable 
-&gt; values (′abc′,′f′,′1966-08-17′,′china′,′n′); 
Query OK, 1 row affected (0.05 sec)</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />查看一下： <br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>mysql&gt; select * from mytable; 
+----------+------+------------+-----------+--------+ 
| name | sex | birth | birthaddr | single | 
+----------+------+------------+-----------+--------+ 
| abccs |f | 1977-07-07 | china | y | 
| mary |f | 1978-12-12 | usa | NULL | 
| tom |m | 1970-09-02 | usa | NULL | 
| abc |f | 1966-08-17 | china | n | 
+----------+------+------------+-----------+--------+</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />    4、删除记录 <br />    用如下命令删除表中的一条记录：mysql&gt; delete from mytable where name=′abc′; <br />    DELETE从表中删除满足由where给出的条件的一条记录。 <br />    再显示一下结果： <br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>mysql&gt; select * from mytable; 
+----------+------+------------+-----------+--------+ 
| name | sex | birth | birthaddr | single | 
+----------+------+------------+-----------+--------+ 
| abccs |f | 1977-07-07 | china | y | 
| mary |f | 1978-12-12 | usa | NULL | 
| tom |m | 1970-09-02 | usa | NULL | 
+----------+------+------------+-----------+--------+</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />    5、删除表： <br />    mysql&gt; drop table ****(表1的名字)，***表2的名字; <br />    可以删除一个或多个表，小心使用。 <br /><br />    6、数据库的删除： <br />    mysql&gt; drop database 数据库名; <br />    小心使用。 <br /><br />    7、数据库的备份：<br />    退回到DOS：<br />    mysql&gt; quit<br />    d:mysqlbin <br /><br />    使用如下命令对数据库abccs进行备份： <br />    mysqldump --opt abccs&gt;abccs.dbb <br />    abccs.dbb就是你的数据库abccs的备份文件。 <br /><br />    8、用批处理方式使用MySQL: <br /><br />    首先建立一个批处理文件mytest.sql,内容如下： <br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>use abccs; 
select * from mytable; 
select name,sex from mytable where name=′abccs′;</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />    在DOS下运行如下命令：d:mysqlbin mysql &lt; mytest.sql <br /><br />    在屏幕上会显示执行结果。 <br /><br />    如果想看结果，而输出结果很多，则可以用这样的命令： mysql &lt; mytest.sql | more <br /><br />    我们还可以将结果输出到一个文件中： mysql &lt; mytest.sql &gt; mytest.out <img src ="http://www.blogjava.net/WshmAndLily/aggbug/51388.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2006-06-08 16:23 <a href="http://www.blogjava.net/WshmAndLily/articles/51388.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习MySQL常用操作命令</title><link>http://www.blogjava.net/WshmAndLily/articles/51386.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Thu, 08 Jun 2006 08:19:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/51386.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/51386.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/51386.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/51386.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/51386.html</trackback:ping><description><![CDATA[
		<div class="content" id="BodyLabel" style="PADDING-RIGHT: 10px; DISPLAY: block; PADDING-LEFT: 10px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px">1<b>、启动MySQL服务器 </b><br /><br />    实际上上篇已讲到如何启动MySQL。两种方法： 一是用winmysqladmin，如果机器启动时已自动运行，则可直接进入下一步操作。 二是在DOS方式下运行 d:mysqlbinmysqld <br /><br />    <b>2、进入mysql交互操作界面</b><br /><br />    在DOS方式下，运行： d:mysqlbinmysql <br /><br />    出现: mysql 的提示符，此时已进入mysql的交互操作方式。 <br /><br />    如果出现 "ERROR 2003: Can′t connect to MySQL server on ′localhost′ (10061)“， <br /><br />说明你的MySQL还没有启动。 <br /><br />    <b>3、退出MySQL操作界面 </b><br /><br />    在mysql&gt;提示符下输入quit可以随时退出交互操作界面： <br />    mysql&gt; quit <br />    Bye <br />    你也可以用control-D退出。 <br /><br />    <b>4、第一条命令 </b><br /><br /><ccid_nobr></ccid_nobr><span class="myp111"><font id="zoom"><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>mysql&gt; select version(),current_date(); 
+----------------+-----------------+ 
| version() | current_date() | 
+----------------+-----------------+ 
| 3.23.25a-debug | 2001-05-17 | 
+----------------+-----------------+ 
1 row in set (0.01 sec) 
mysql&gt;</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />    此命令要求mysql服务器告诉你它的版本号和当前日期。尝试用不同大小写操作上述命令，看结果如何。结果说明mysql命令的大小写结果是一致的。 <br /><br />    练习如下操作： <br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>mysql&gt;Select (20+5)*4; 
mysql&gt;Select (20+5)*4,sin(pi()/3); 
mysql&gt;Select (20+5)*4 AS Result,sin(pi()/3); (AS: 指定假名为Result) 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;B&gt;5、多行语句&lt;/B&gt; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;一条命令可以分成多行输入，直到出现分号“；”为止： 
&lt;ccid_nobr&gt;
&lt;table width="400" border="1" cellspacing="0" cellpadding="2" 
 bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"&gt;
&lt;tr&gt;
    &lt;td bgcolor="e6e6e6" class="code" style="font-size:9pt"&gt;
    &lt;pre&gt;&lt;ccid_code&gt;  mysql&gt; select 
-&gt; USER() 
-&gt; , 
-&gt; now() 
-&gt;; 
+--------------------+---------------------+ 
| USER() | now() | 
+--------------------+---------------------+ 
| ODBC@localhost | 2001-05-17 22:59:15 | 
+--------------------+---------------------+ 
1 row in set (0.06 sec) 
mysql&gt;</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />    注意中间的逗号和最后的分号的使用方法。 <br /><br />    <b>6、一行多命令</b><br /><br />    输入如下命令： <br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>mysql&gt; SELECT USER(); SELECT NOW(); 
+------------------+ 
| USER() | 
+------------------+ 
| ODBC@localhost | 
+------------------+ 
1 row in set (0.00 sec) 

+---------------------+ 
| NOW() | 
+---------------------+ 
| 2001-05-17 23:06:15 | 
+---------------------+ 
1 row in set (0.00 sec) 
mysql&gt;</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />    注意中间的分号，命令之间用分号隔开。 <br /><br />    <b>7、显示当前存在的数据库 </b><br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>mysql&gt; show databases; 
+----------+ 
| Database | 
+----------+ 
| mysql | 
| test | 
+----------+ 
2 row in set (0.06 sec) 
mysql&gt;</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />    <b>8、选择数据库并显示当前选择的数据库</b><br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>mysql&gt; USE mysql 
Database changed 
mysql&gt; 
(USE 和 QUIT 命令不需要分号结束。） 
mysql&gt; select database(); 
+---------------+ 
| database() | 
+---------------+ 
| mysql | 
+---------------+ 
1 row in set (0.00 sec)</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />    <b>9、显示当前数据库中存在的表 </b><br />    mysql&gt; SHOW TABLES; <br /><br />    <b>10、显示表(db)的内容</b><br />mysql&gt;select * from db; <br /><br />    <b>11、命令的取消</b><br /><br />    当命令输入错误而又无法改变（多行语句情形）时，只要在分号出现前就可以用 c来取消该条命令 <br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>mysql&gt; select 
-&gt; user() 
-&gt; c 
mysql&gt;</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />    这是一些最常用的最基本的操作命令，通过多次练习就可以牢牢掌捂了。</font></span></div>
<img src ="http://www.blogjava.net/WshmAndLily/aggbug/51386.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2006-06-08 16:19 <a href="http://www.blogjava.net/WshmAndLily/articles/51386.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MySQL安全性指南</title><link>http://www.blogjava.net/WshmAndLily/articles/51382.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Thu, 08 Jun 2006 08:03:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/51382.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/51382.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/51382.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/51382.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/51382.html</trackback:ping><description><![CDATA[作为一个MySQL的系统管理员，你有责任维护你的MySQL数据库系统的数据安全性和完整性。本文主要主要介绍如何建立一个安全的MySQL系统，从系统内部和外部网络两个角度，为你提供一个指南。 <br /><br />本文主要考虑下列安全性有关的问题： <br /><br />为什么安全性很重要，你应该防范那些攻击？ <br />服务器面临的风险（内部安全性），如何处理？ <br />连接服务器的客户端风险（外部安全性），如何处理？ <br />MySQL管理员有责任保证数据库内容的安全性，使得这些数据记录只能被那些正确授权的用户访问，这涉及到数据库系统的内部安全性和外部安全性。 <br />内部安全性关心的是文件系统级的问题，即，防止MySQL数据目录（DATADIR）被在服务器主机有账号的人（合法或窃取的）进行攻击。如果数据目录内容的权限过分授予，使得每个人均能简单地替代对应于那些数据库表的文件，那么确保控制客户通过网络访问的授权表设置正确，对此毫无意义。 <br /><br />外部安全性关心的是从外部通过网络连接服务器的客户的问题，即，保护MySQL服务器免受来自通过网络对服务器的连接的攻击。你必须设置MySQL授权表（grant table），使得他们不允许访问服务器管理的数据库内容，除非提供有效的用户名和口令。 <br /><br />下面就详细介绍如何设置文件系统和授权表mysql，实现MySQL的两级安全性。 <br /><br /><br />一、内部安全性-保证数据目录访问的安全<br />MySQL服务器通过在MySQL数据库中的授权表提供了一个灵活的权限系统。你可以设置这些表的内容，允许或拒绝客户对数据库的访问，这提供了你防止未授权的网络访问对你数据库攻击的安全手段，然而如果主机上其他用户能直接访问数据目录内容，建立对通过网络访问数据库的良好安全性对你毫无帮助，除非你知道你是登录MySQL服务器运行主机的唯一用户，否则你需要关心在这台机器上的其他用户获得对数据目录的访问的可能性。<br /><br />以下是你应该保护的内容：<br /><br />数据库文件。很明显，你要维护服务器管理的数据库的私用性。数据库拥有者通常并且应该考虑数据库内容的安全性，即使他们不想，也应该考虑时数据库内容公开化，而不是通过糟糕的数据目录的安全性来暴露这些内容。 <br />日志文件。一般和更新日志必须保证安全，因为他们包含查询文本。对日志文件有访问权限的任何人可以监视数据库进行过的操作。<br />更要重点考虑的日志文件安全性是诸如GRANT和SET PASSWORD等的查询也被记载了，一般和更新日志包含有敏感查询的文本，包括口令（MySQL使用口令加密，但它在已经完成设置后才运用于以后的连接建立。设置一个口令的过程设计象GRANT或SET PASSWORD等查询，并且这些查询以普通文本形式记载在日志文件中）。如果一个攻击者犹如日文件的读权限，只需在日志文件上运行grep寻找诸如GRANT和PASSWORD等词来发现敏感信息。 <br />显然，你不想让服务器主机上的其他用户有数据库目录文件的写权限，因为他们可以重写你的状态文件或数据库表文件，但是读权限也很危险。如果一个数据库表文件能被读取，偷取文件并得到MySQL本身，以普通文本显示表的内容也很麻烦，为什么？因为你要做下列事情：<br /><br />在服务器主机上安装你自己“特制”的MySQL服务器，但是有一个不同于官方服务器版本的端口、套接字和数据目录。 <br />运行mysql_install_db初始化你的数据目录，这赋予你作为MySQL root用户访问你的服务器的权限，所以你有对服务器访问机制的完全控制，它也建立一个test数据库。 <br />将对应于你想偷取得表文件拷贝到你服务器的数据库目录下的test目录。 <br />启动你的服务器。你可以随意访问数据库表，SHOW TABLES FROM test显示你有一个偷来的表的拷贝，SELECT *显示它们任何一个的全部内容。 <br />如果你确实很恶毒，将权限公开给你服务器的任何匿名用户，这样任何人能从任何地方连接服务器访问你的test数据库。你现在将偷来的数据库表公布于众了。<br />在考虑一下，从相反的角度，你想让别人对你这样吗？当然不！你可以通过在数据库录下执行ls -l命令确定你的数据库是否包含不安全的文件和目录。查找有“组”和“其他用户”权限设置的文件和目录。下面是一个不安全数据目录的一部分列出：<br /><br />　<br />% ls -l<br />total 10148<br />drwxrwxr-x  11  mysqladm wheel    1024 May  8 12:20 <br />drwxr-xr-x  22  root     wheel     512 May  8 13:31 ..<br />drwx------   2  mysqladm mysqlgrp  512 Apr 16 15:57 menagerie<br />drwxrwxr-x   2  mysqladm wheel     512 Jan 25 20:40 mysql<br />drwxrwxr-x   7  mysqladm wheel     512 Aug 31  1998 sql-bench<br />drwxrwxr-x   2  mysqladm wheel    1536 May  6 06:11 test<br />drwx------   2  mysqladm mysqlgrp 1024 May  8 18:43 tmp<br />....<br /><br /><br />正如你看到的，有些数据库有正确的权限，而其他不是。本例的情形是经过一段时间后的结果。较少限制的权限由在权限设置方面比更新版本更不严格的较早版本服务器设置的（注意更具限制的目录menageria和tmp都有较近日期）。MySQL当前版本确保这些文件只能由运行服务器的用户读取。<br /><br />让我们来修正这些权限，使得只用服务器用户可访问它们。你的主要保护工具来自于由UNIX文件系统本身提供的设置文件和目录属主和模式的工具。下面是我们要做的：<br /><br />进入该目录<br />% cd DATADIR<br /><br />设置所有在数据目录下的文件属主为由用于运行服务器的账号拥有（你必须以root执行这步）。在本文使用mysqladm和mysqlgrp作为该账号的用户名和组名。你可以使用下列命令之一改变属主：<br /># chown mysqladm.mysqlgrp .<br /><br /># find . -follow -type d -print | xargs chown mysqladm.mysqlgrp<br /><br />设置你的数据目录和数据库目录的模式使得他们只能由mysqladm读取，这阻止其他用户访问你数据库目录的内容。你可以用下列命令之一以root或mysqladm身份运行。<br />% chmod -R go-rwx  .<br /><br />% find . -follow -type d -print | xargs chmod go-rwx<br /><br />数据目录内容的属主和模式为mysqladm设置。现在你应该保证你总是以mysqladm用户运行服务器，因为现在这是唯一由访问数据库目录权限的用户（除root）。 <br />在完成这些设置后，你最终应该得到下面的数据目录权限：<br /><br />% ls -l<br />total 10148<br />drwxrwx---  11  mysqladm mysqlgrp 1024 May  8 12:20 .<br />drwxr-xr-x  22  root     wheel     512 May  8 13:31 ..<br />drwx------   2  mysqladm mysqlgrp  512 Apr 16 15:57 menagerie<br />drwx------   2  mysqladm mysqlgrp  512 Jan 25 20:40 mysq<br />drwx------   7  mysqladm mysqlgrp  512 Aug 31  1998 sql-bench<br />drwx------   2  mysqladm mysqlgrp 1536 May  6 06:11 test<br />drwx------   2  mysqladm mysqlgrp 1024 May  8 18:43 tmp<br />....<br /><br /><br /><br />二、外部安全性-保证网络访问的安全<br />MySQL的安全系统是很灵活的，它允许你以多种不同方式设置用户权限。一般地，你可使用标准的SQL语句GRANT和REVOKE语句做，他们为你修改控制客户访问的授权表，然而，你可能由一个不支持这些语句的老版本的MySQL（在3.22.11之前这些语句不起作用），或者你发觉用户权限看起来不是以你想要的方式工作。对于这种情况，了解MySQL授权表的结构和服务器如何利用它们决定访问权限是有帮助的，这样的了解允许你通过直接修改授权表增加、删除或修改用户权限，它也允许你在检查这些表时诊断权限问题。<br /><br />关于如何管理用户账号，见《MySQL的用户管理》。而对GRANT和REVOKE语句详细描述，见《MySQL参考手册》。<br /><div class="content" id="BodyLabel" style="PADDING-RIGHT: 10px; DISPLAY: block; PADDING-LEFT: 10px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px">2.1 MySQL授权表的结构和内容<br />通过网络连接服务器的客户对MySQL数据库的访问由授权表内容来控制。这些表位于mysql数据库中，并在第一次安装MySQL的过程中初始化（运行mysql_install_db脚本）。授权表共有5个表：user、db、host、tables_priv和columns_priv。<br /><br />表1 user、db和host授权表结构 <br />访问范围列<br /><br />user db host <br />Host Host Host <br />User Db Db <br />Password User  <br />数据库/表权限列 <br />Alter_priv Alter_priv Alter_priv <br />Create_priv Create_priv Create_priv <br />Delete_priv Delete_priv Delete_priv <br />Drop_priv Drop_priv Drop_priv <br />Index_priv Index_priv Index_priv <br />Insert_priv Insert_priv Insert_priv <br />References_priv References_priv References_priv <br />Select_priv Select_priv Select_priv <br />Update_priv Update_priv Update_priv <br />File_priv Grant_priv Grant_priv <br />Grant_priv   <br />Process_priv   <br />Reload_priv   <br />Shutdown_priv   <br />　 <br />表2 tables_priv和columns_priv属权表结构<br /><br />访问范围列 <br />tables_priv  columns_priv <br />Host  Host <br />Db  Db <br />User  User <br />Table_name  Table_name <br />Column_name   <br />权限列 <br />Table_priv  Column_priv <br /><br />授权表的内容有如下用途：<br /><br />user表<br />user表列出可以连接服务器的用户及其口令，并且它指定他们有哪种全局（超级用户）权限。在user表启用的任何权限均是全局权限，并适用于所有数据库。例如，如果你启用了DELETE权限，在这里列出的用户可以从任何表中删除记录，所以在你这样做之前要认真考虑。 <br />db<br />db表列出数据库，而用户有权限访问它们。在这里指定的权限适用于一个数据库中的所有表。 <br />host表<br />host表与db表结合使用在一个较好层次上控制特定主机对数据库的访问权限，这可能比单独使用db好些。这个表不受GRANT和REVOKE语句的影响，所以，你可能发觉你根本不是用它。 <br />tables_priv表<br />tables_priv表指定表级权限，在这里指定的一个权限适用于一个表的所有列。 <br />columns_priv表<br />columns_priv表指定列级权限。这里指定的权限适用于一个表的特定列。 <br />在“不用GRANT设置用户”一节里，我们再讨论GRANT语句如何对修改这些表起作用，和你怎样能通过直接修改授权表达到同样的效果。<br /><br />tables_priv和columns_priv表在MySQL 3.22.11版引进（与GRANT语句同时）。如果你有较早版本的MySQL，你的mysql数据库将只有user、db和host表。如果你从老版本升级到3.22.11或更新，而没有tables_priv和columns_priv表，运行mysql_fix_privileges_tables脚本创建它们。<br /><br />MySQL没有rows_priv表，因为它不提供记录级权限，例如，你不能限制用户于表中包含特定列值的行。如果你确实需要这种能力，你必须用应用编程来提供。如果你想执行建议的记录级锁定，你可用GET_LOCK()函数做到。<br /><br />授权表包含两种列：决定一个权限何时运用的范围列和决定授予哪种权限的权限列。<br /><br />2.1.1 授权表范围列<br />授权表范围列指定表中的权限何时运用。每个授权表条目包含User和Host列来指定权限何时运用于一个给定用户从给定主机的连接。其他表包含附加的范围列，如db表包含一个Db列指出权限运用于哪个数据库。类似地，tables_priv和columns_priv表包含范围字段，缩小范围到一个数据库中的特定表或一个表的特定列。<br /><br />2.1.2 授权表权限列<br />授权表还包含权限列，他们指出在范围列中指定的用户拥有何种权限。由MySQL支持的权限如下表所示。该表使用GRANT语句的权限名称。对于绝大多数在user、db和host表中的权限列的名称与GRANT语句中有明显的联系。如Select_priv对应于SELECT权限。 <br /><br /><div class="content" id="BodyLabel" style="PADDING-RIGHT: 10px; DISPLAY: block; PADDING-LEFT: 10px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px"><p>2.1.3 数据库和表权限<br />下列权限运用于数据库和表上的操作。<br /><br />ALTER<br />允许你使用ALTER TABLE语句，这其实是一个简单的第一级权限，你必须由其他权限，这看你想对数据库实施什么操作。 <br />CREATE<br />允许你创建数据库和表，但不允许创建索引。 <br />DELETE<br />允许你从表中删除现有记录。 <br />DROP<br />允许你删除（抛弃）数据库和表，但不允许删除索引。 <br />INDEX<br />允许你创建并删除索引。 <br />REFERENCES<br />目前不用。 <br />SELECT<br />允许你使用SELECT语句从表中检索数据。对不涉及表的SELECT语句就不必要，如SELECT NOW()或SELECT 4/2。 <br />UPDATE<br />允许你修改表中的已有的记录。 <br />2.1.4 管理权限<br />下列权限运用于控制服务器或用户授权能力的操作的管理性操作。<br /><br />FILE<br />允许你告诉服务器读或写服务器主机上的文件。该权限不应该随便授予，它很危险，见“回避授权表风险”。服务器确实较谨慎地保持在一定范围内使用该权限。你只能读任何人都能读的文件。你正在写的文件必须不是现存的文件，这防止你迫使服务器重写重要文件，如/etc/passwd或属于别人的数据库的数据目录。<br />如果你授权FILE权限，确保你不以UNIX的root用户运行服务器，因为root可在文件系统的任何地方创建新文件。如果你以一个非特权用户运行服务器，服务器只能在给用户能访问的目录中创建文件。<br /><br />GRANT<br />允许你将你自己的权限授予别人，包括GRANT。 <br />PROCESS<br />允许你通过使用SHOW PROCESS语句或mysqladmin process命令查看服务器内正在运行的线程（进程）的信息。这个权限也允许你用KILL语句或mysqladmin kill命令杀死线程。<br />你总是能看到或杀死你自己的线程。PROCESS权限赋予你对任何线程做这些事情的能力。<br /><br />RELOAD<br />允许你执行大量的服务器管理操作。你可以发出FLUSH语句，你也能指性mysqladmin的reload、refresh、flush-hosts、flush-logs、flush-privileges和flush-tables等命令。 <br />SHUTDOWN<br />允许你用mysqladmin shutdown关闭服务器。 <br />在user、db和host表中，每一个权限以一个单独的列指定。这些列全部声明为一个ENUM("N","Y")类型，所以每个权的缺省值是“N”。在tables_priv和columns_priv中的权限以一个SET表示，它允许权限用一个单个列以任何组合指定。这两个表比其他三个表更新，这就是为什么它们使用更有效的表示方式的原因。（有可能在未来，user、db和host表也用一个SET类型表示。）<br /><br />在tables_priv表中的Table_priv列被定义成：<br /><br />SET('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter')<br />在coloums_priv表中的Column_priv列被定义成：　 <br /><br />SET('Select','Insert','Update','References')<br />列权限比表权限少，因为列级较少的权限有意义。例如你能创建一个表，但你不能创建一个孤立的列。<br /><br />user表包含某些在其他授权表不存在的权限的列：File_priv、Process_priv、Reload_priv和Shutdown_priv。这些权限运用于你让服务器执行的与任何特定数据库或表不相关的操作。如允许一个用户根据当前数据库是什么来关闭数据库是毫无意义的。<br /><br />2.2 服务器如何控制客户访问<br />在你使用MySQL时，客户访问控制有两个阶段。第一阶段发生在你试图连接服务器时。服务器查找user表看它是否能找到一个条目匹配你的名字、你正在从那儿连接的主机和你提供的口令。如果没有匹配，你就不能连接。如果有一个匹配，建立连接并继续第二阶段。在这个阶段，对于每一个你发出的查询，服务器检查授权表看你是否有足够的权限执行查询，第二阶段持续到你与服务器对话的结束<br /></p></div><br /><br /><div class="content" id="BodyLabel" style="PADDING-RIGHT: 10px; DISPLAY: block; PADDING-LEFT: 10px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px"><p>本小节详细介绍MySQL服务器用于将授权表条目匹配到来的连接请求或查询的原则，这包括在授权表范围列中合法的值的类型、结合授权表中的权限信息的方式和表中条目被检查的次序。<br /><br />2.2.1 范围列内容<br />一些范围列要求文字值，但它们大多数允许通配符或其他特殊值。<br /><br />Host <br />一个Host列值可以是一个主机名或一个IP地址。值localhost意味着本地主机，但它只在你用一个localhost主机名时才匹配，而不是你在使用主机名时。假如你的本地主机名是pit.snake.net并且在user表中有对你的两条记录，一个有一个Host值或localhost，而另一个有pit.snake.net，有localhost的记录将只当你连接localhost时匹配，其他在只在连接pit.snake.net时才匹配。如果你想让客户能以两种方式连接，你需要在user表中有两条记录。<br /><br />你也可以用通配符指定Host值。可以使用SQL的模式字符“%”和“_”并具有当你在一个查询中使用LIKE算符同样的含义（不允许regex算符）。 SQL模式字符都能用于主机名和IP地址。如%wisc.edu匹配任何wisc.edu域内的主机，而%.edu匹配任何教育学院的主机。类似地，192.168.%匹配任何在192.168 B类子网的主机，而192.168.3.%匹配任何在192.168.3 C类子网的主机。<br /><br />%值匹配所有主机，并可用于允许一个用户从任何地方连接。一个空白的Host值等同于%。（例外：在db表中，一个空白Host值含义是“进一步检查host表”，该过程在“查询访问验证”中介绍。）<br /><br />从MySQL 3.23起，你也可以指定带一个表明那些为用于网络地址的网络掩码的IP地址，如192.168.128.0/17指定一个17位网络地址并匹配其IP地址是192.168128前17位的任何主机。<br /><br />User <br />用户名必须是文字的或空白。一个空白值匹配任何用户。%作为一个User值不意味着空白，相反它匹配一个字面上的%名字，这可能不是你想要的。<br /><br />当一个到来的连接通过user表被验证而匹配的记录包含一个空白的User值，客户被认为是一个匿名用户。 <br /><br />Password <br />口令值可以是空或非空，不允许用通配符。一个空口令不意味着匹配任何口令，它意味着用户必须不指定口令。<br /><br />口令以一个加密过的值存储，不是一个字面上的文本。如果你在Password列中存储一个照字面上的口令，用户将不能连接！GRANT语句和mysqladmin password命令为你自动加密口令，但是如果你用诸如INSERT、REPLACE、UPDATE或SET PASSWORD等命令，一定要用PASSWORD("new_password")而不是简单的"new_password"来指定口令。 <br /><br />Db<br />在columns_priv和tables_priv表中，Db值必须是真正的数据库名（照字面上），不允许模式和空白。在db和host中，Db值可以以字面意义指定或使用SQL模式字符'%'或'_'指定一个通配符。一个'%'或空白匹配任何数据库。 <br />Table_name，Column_name<br />这些列中的值必须是照字面意思的表或列名，不允许模式和空白。<br />某些范围列被服务器视为大小写敏感的，其余不是。这些原则总结在下表中。特别注意Table_name值总是被看作大小写敏感的，即使在查询中的表名的大小写敏感性对待视服务器运行的主机的文件系统而定（UNIX下是大小写敏感，而Windows不是）。<br /><br />表3 授权表范围列的大小写敏感性 <br />列<br />Host<br />User<br />Password<br />Db<br />Table_name<br />Column_name<br />大小写敏感性<br />No<br />Yes<br />Yes<br />Yes<br />Yes<br />No<br /><br /><br />2.2.2 查询访问验证<br />每次你发出一个查询，服务器检查你是否有足够的权限执行它，它以user、db、tables_priv和columns_priv的顺序检查，知道它确定你有适当的访问权限或已搜索所有表而一无所获。更具体的说：<br /><br />服务器检查user表匹配你开始连接的记录以查看你有什么全局权限。如果你有并且它们对查询足够了，服务器则执行它。</p></div><br /><p>如果你的全局权限不够，服务器为你在db表中寻找并将该记录中的权限加到你的全局权限中。如果结果对查询足够，服务器执行它。 <br />如果你的全局和数据库级组合的权限不够，服务器继续查找，首先在tables_priv表，然后columns_priv表。 <br />如果你在检查了所有表之后仍无权限，服务器拒绝你执行查询的企图。 <br />用布尔运算的术语，授权表中的权限被服务器这样使用：<br /><br />user OR tables_priv OR columns_priv<br /><br />你可能疑惑为什么前面的描述只引用4个授权表，而实际上有5个。实际上服务器是这样检查访问权限：<br /><br />user OR (db AND host) OR tables_priv OR columns_priv<br /><br />第一个较简单的表达式是因为host表不受GRANT和REVOKE语句影响。如果你总是用GRANT和REVOKE管理用户权限，你绝不需要考虑host表。但是其工作原理你用该知道：<br /><br />当服务器检查数据库级权限时，它对于客户查找db表。如果Host列是空的，它意味着“检查host表以找出哪一个主机能访问数据库”。 <br />服务器在host表中查找有与来自db表的记录相同的Db列值。如果没有host记录匹配客户主机，则没有授予数据库级权限。如果这些记录的任何一个的确有一个匹配连接的客户主机的Host列值，db表记录和host表记录结合产生客户的数据库级权限。<br />然而，权限用一个逻辑AND（与）结合起来，这意味着除非一个给定的权限在两个表中都有，否则客户就不具备该权限。以这种方式，你可以在db表中授予一个基本的权限集，然后使用host表对特定的主机有选择地禁用它们。如你可以允许从你的域中的所有主机访问数据库，但关闭了那些在较不安全区域的主机的数据库权限。<br /><br />前面的描述毫无疑问使访问检查听起来一个相当复杂的过程，特别是你以为服务器对你发出的每个查询进行权限检查，然而此过程是很快的，因为服务器其实不从授权表对每个查询查找信息，相反，它在启动时将表的内容读入内存，然后验证查询用的是内存中的副本。这大大提高了访问检查操作的性能。但有一个非常明显的副作用。如果你直接修改授权表的内容，服务器将不知道权限的改变。<br /><br />例如，如果你用一条INSERT语句向user表加入一个新记录来增加一个新用户，命名在记录中的用户将不能连接服务器。这对管理员新手（有时对有经验的老手）是很困惑的事情，当时解决方法很简单：在你改变了它们之后告诉服务器重载授权表内容，你可以发一条FLUSH PRIVILEGES或执行mysqladmin flush-privileges（或如果你有一个不支持flush-privileges的老版本，用mysqladmin reload。）。<br /><br />2.2.3 范围列匹配顺序<br />MySQL服务器按一种特定方式排序符授权表中的记录，然后通过按序浏览记录匹配到来的连接。找到的第一个匹配决定了被使用的记录。理解MySQL使用的排序顺序很重要，特别是对user表。<br /><br />当服务器读取user表内容时，它根据在Host和User列中的值排序记录，Host值起决定作用（相同的Host值排在一起，然后再根据User值排序）。然而，排序不是典序（按词排序），它只是部分是。要牢记的是字面上的词优先于模式。这意味着如果你正从client.your.net连接服务器而Host有client.your.net和%.your.net两个值，则第一个先选。类似地，%.your.net优先于%.net，然后是%。IP地址的匹配也是这样的。<br /><br />总之一句话，越具体越优先。可以参见本文附录的实例。<br /><br />2.3 避免授权表风险<br />本届介绍一些在你授权时的一些预防措施，以及不明值的选择带来的风险。一般地，你要很“吝啬”地授予超级用户权限，即不要启用user表中条目中的权限，而使用其它授权表，以将用户权限限制于数据库、表、或列。在user表中的权限允许于影响到你的服务器操作或能访问任何数据库中的任何表。<br /><br />不要授予对mysql数据库的权限。一个拥有包含授权表数据库权限的用户可能会修改表以获取对其他任何数据库的权限。授予允许一个用户修改mysql数据库表的权限也实际上给了用户以一个全局GRANT权限。如果用户能直接修改表，这也等价于能够发出任何你能想象的任何GRANT语句。<br /><br />FILE权限尤其危险，不要轻易授权它。以下是一个拥有FILE权限的人能干除的事情：<br /><br />    CREATE TABLE etc_passwd (pwd_entry TEXT)<br />    LOAD DATA INFILE "/etc/passwd" into TABLE etc_passwd;<br />    SELECT * FROM etc_passwd;<br />在发出这些语句后，用户已经拥有了你的口令文件的内容了。实际上，服务器上任何公开可读文件的内容都可被拥有FILE权限的用户通过网络访问。<br /><br />FILE权限也能被利用来危害没有设置足够权限制的文件权限的系统上的数据库。这就是你为什么应该设置数据目录只能由服务器读取的原因。如果对应于数据库表的文件可被任何人读取，不只是用户服务器账号的用户可读，任何有FILE权限的用户也可通过网络连接并读取它们。下面演示这个过程：<br /><br />创建一个有一个LONGBLOB列的表： <br />USER test;<br />CREATE TABLE tmp (b LONGBLOB);<br /><br />使用该表读取每个对应于你想偷取的数据库表文件的内容，然后将表内容写入你自己数据库的一个文件中：<br /><br />LOAD DATA INFILE "./other_db/x.frm" INTO TABLE tmp<br />     FIELDS ESCAPED BY "" LINES TERMINATED BY "";<br />SELECT * FROM tmp INTO OUTFILE "y.frm"<br />     FIELDS ESCAPED BY "" LINES TERMINATED BY "";<br />DELETE FROM tmp;<br />LOAD DATA INFILE "./other_db/x.ISD" INTO TABLE tmp<br />     FIELDS ESCAPED BY "" LINES TERMINATED BY "";<br />SELECT * FROM tmp INTO OUTFILE "y.ISD"<br />     FIELDS ESCAPED BY "" LINES TERMINATED BY "";<br />DELETE FROM tmp;<br />LOAD DATA INFILE "./other_db/x.ISM" INTO TABLE tmp<br />     FIELDS ESCAPED BY "" LINES TERMINATED BY "";<br />SELECT * FROM tmp INTO OUTFILE "y.ISM"<br />现在你拥有了一个新表y，它包含other_db.x的内容并且你有全权访问它。 <br />为避免让人以同样的方式攻击，根据“第一部分 内部安全性-保护你的数据目录”中的指令设置你的数据目录上的权限。你也可以在你启动服务器时使用--skip-show-database选项限制用户对于他们没用访问权限的数据库使用SHOW DATABASES和SHOW TABLES。这有助于防止用户找到关于它们不能访问的数据库和表的信息。<br /><br />ALTER权限能以不希望的方式使用。假定你想让user1可以访问table1但不能访问tables2。一个拥有ALTER权限的用户可以通过使用ALTER TABLE将table2改名为table1来偷梁换柱。<br /><br />当心GRANT权限。两个由不同权限但都有GRANT权限的用户可以使彼此的权利更强大。 <br /><br />2.4 不用GRANT设置用户<br />如果你有一个早于3.22.11的MySQL版本，你不能使用GRANT（或REVOKE）语句设置用户及其访问权限，但你可以直接修改授权表的内容。如果你理解GRANT语句如何修改授权表，这很容易。那么你通过手工发出INSERT语句就能自己做同样的事情。<br /><br />当你发出一条GRANT语句时，你指定一个用户名和主机名，可能还有口令。对该用户生成一个user表记录，并且这些值记录在User、Host和Password列中。如果你在GRANT语句中指定全局权限，这些权限记录在记录的权限列中。其中要留神的是GRANT语句为你加密口令，而INSERT不是，你需要在INSERT中使用PASSWORD()函数加密口令。<br /><br />如果你指定数据库级权限，用户名和主机名被记录在db表的User和Host列。你为其授权的数据库记录在Db列中，你授予的权限记录在权限列中。<br /><br />对于表级和列级权限，效果是类似的。在tables_priv和columns_priv表中创建记录以记录用户名、主机名和数据库，还有相关的表和列。授予的权限记录在权限列中。<br /><br />如果你还记得前面的介绍，你应该能即使不用GRANT语句也能做GRANT做的事情。记住在你直接修改授权表时，你将通知服务器重载授权表，否则他不知道你的改变。你可以执行一个mysqladmin flush-privileges或mysqladmin reload命令强迫一个重载。如果你忘记做这个，你会疑惑为什么服务器不做你想做的事情。<br /><br />下列GRANT语句创建一个拥有所有权的超级用户。包括授权给别人的能力：<br /><br />GRANT ALL ON *.* TO anyname@localhost IDENTIFIED BY "passwd"<br />    WITH GRANT OPTION<br />该语句将在user表中为anyname@localhost创建一个记录，打开所有权限，因为这里是超级用户（全局）权限存储的地方，要用INSERT语句做同样的事情，语句是： <br /><br />INSERT INTO user  VALUES("localhost","anyname",PASSWORD("passwd"),<br />    "Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y")<br />你可能发现它不工作，这要看你的MySQL版本。授权表的结构已经改变而且你在你的user表可能没有14个权限列。用SHOW COLUMNS找出你的授权表包含的每个权限列，相应地调整你的INSERT语句。 下列GRANT语句也创建一个拥有超级用户身份的用户，但是只有一个单个的权限： <br /><br />GRANT RELOAD ON *.* TO flush@localhost IDENTIFIED BY "flushpass"<br />本例的INSERT语句比前一个简单，它很容易列出列名并只指定一个权限列。所有其它列将设置为缺省的"N"： <br /><br />INSERT INTO user (Host,Password,Reload) VALUES("localhost","flush",PASSWORD("flushpass"),"Y")<br />数据库级权限用一个ON db_name.*子句而不是ON *.*进行授权： <br /><br />GRANT ALL ON sample.* TO boris@localhost IDENTIFIED BY "ruby"<br />这些权限不是全局的，所以它们不存储在user表中，我们仍然需要在user表中创建一条记录（使得用户能连接），但我们也需要创建一个db表记录记录数据库集权限：<br />INSERT INTO user (Host,User,Password) VALUES("localhost","boris",PASSWORD("ruby")) <br /><br />INSERT INTO db VALUES("localhost","sample_db","boris","Y","Y","Y","Y","Y","Y","N","Y","Y","Y")<br /><br />"N"列是为GRANT权限；对末尾的一个数据库级具有WITH GRANT OPTION的GRANT语句，你要设置该列为"Y"。<br /></p><div class="content" id="BodyLabel" style="PADDING-RIGHT: 10px; DISPLAY: block; PADDING-LEFT: 10px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px">要设置表级或列级权限，你对tables_priv或columns_priv使用INSERT语句。当然，如果你没有GRANT语句，你将没有这些表，因为它们在MySQL中同时出现。如果你确实有这些表并且为了某些原因想要手工操作它们，要知道你不能用单独的列启用权限。<br /><br />你设置tables_priv.Table_priv或columns_priv.Column_priv列来设置包含你想启用的权限值。例如，要对一个表启用SELECT和INSERT权限，你要在相关的tables_priv的记录中设置Table_priv为"Select,Insert"。 <br /><br />如果你想对一个拥有MySQL账号的用户修改权限，使用UPDATE而不是INSERT，不管你增加或撤销权限都是这样。要完全删除一个用户，从用户使用的每个表中删除记录。 <br /><br />如果你愿意避免发一个查询来直接修改全权表，你可以看一下MySQL自带的mysqlaccess和mysql_setpermissions脚本。 <br /><br /><br /><br />附录1 小测验<br />在你刚刚新安装了一个MySQL服务器，在你增加了一个允许连接MySQL的用户，用下列语句：<br /><br />GRANT ALL ON samp_db.* TO fred@*.snake.net IDENTIFIED "cocoa"<br /><br />而fred碰巧在服务器主机上有个账号，所以他试图连接服务器：<br /><br />%mysql -u fred -pcocoa samp_db<br />ERROR 1045: Access denied for user: 'fred@localhost' (Using password: YES)<br /><br />为什么？<br /><br />原因是： <br /><br />先考虑一下mysql_install_db如何建立初始权限表和服务器如何使用user表记录匹配客户连接。在你用mysql_install_db初始化你的数据库时，它创建类似这样的user表：<br /><br />Host User <br />localhost<br />pit.snake.net<br />localhost<br />pit.snake.net root<br />root<br /><br /><br /><br />头两个记录允许root指定localhost或主机名连接本地服务器，后两个允许匿名用户从本地连接。当增加fred用户后，<br /><br />Host User <br />localhost<br />pit.snake.net<br />localhost<br />pit.snake.net<br />%.snake.net root<br />root<br /><br /><br />fred <br /><br />在服务器启动时，它读取记录并排序它们（首先按主机，然后按主机上的用户），越具体越排在前面：<br /><br />Host User <br />localhost<br />localhost<br />pit.snake.net<br />pit.snake.net<br />%.snake.net root<br /><br />root<br /><br />fred <br /><br />有localhost的两个记录排在一起，而对root的记录排在第一，因为它比空值更具体。pit.snake.net的记录也类似。所有这些均是没有任何通配符的字面上的Host值，所以它们排在对fred记录的前面，特别是匿名用户排在fred之前<br />结果是在fred试图从localhost连接时，Host列中的一个空用户名的记录在包含%.snake.net的记录前匹配。该记录的口令是空的，因为缺省的匿名用户没有口令。因为在fred连接时指定了一个口令，由一个错配且连接失败。<br /><br />这里要记住的是，虽然用通配符指定用户可以从其连接的主机是很方便。但你从本地主机连接时会有问题，只要你在table表中保留匿名用户记录。<br /><div class="content" id="BodyLabel" style="PADDING-RIGHT: 10px; DISPLAY: block; PADDING-LEFT: 10px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px">一般地，建议你删除匿名用户记录：<br /><br />mysql&gt; DELETE FROM user WHERE User="";<br /><br />更进一步，同时删除其他授权表中的任何匿名用户，有User列的表有db、tables_priv和columns_priv。<br /><br />附录2 使一个新的MySQL安装更安全<br />在你自己安装了一个新的MySQL服务器后，你需要为MySQL的root用户指定一个目录（缺省无口令），否则如果你忘记这点，你将你的MySQL处于极不安全的状态（至少在一段时间内）。<br /><br />在Unix（Linux）上，在按照手册的指令安装好MySQL后，你必须运行mysql_install_db脚本建立包含授权表的mysql数据库和初始权限。在Windows上，运行分发中的Setup程序初始化数据目录和mysql数据库。假定服务器也在运行。<br /><br />当你第一次在机器上安装MySQL时，mysql数据库中的授权表是这样初始化的：<br /><br />你可以从本地主机（localhost）上以root连接而不指定口令。root用户拥有所有权限（包括管理权限）并可做任何事情。（顺便说明，MySQL超级用户与Unix超级用户有相同的名字，他们彼此毫无关系。） <br />匿名访问被授予用户可从本地连接名为test和任何名字以test_开始的数据库。匿名用户可对数据库做任何事情，但无管理权限。 <br />从本地主机多服务器的连接是允许的，不管连接的用户使用一个localhost主机名或真实主机名。如：<br /><br />% mysql -h localhost test<br /><br />% mysql -h pit.snake.net test<br /><br />你以root连接MySQL甚至不指定口令的事实只是意味着初始安装不安全，所以作为管理员的你首先要做的应该是设置root口令，然后根据你设置口令使用的方法，你也可以告诉服务器重载授权表是它知道这个改变。（在服务器启动时，它重载表到内存中而可能不知道你已经修改了它们。）<br /><br />对MySQL 3.22和以上版本，你可以用mysqladmin设置口令：<br /><br />% mysqladmin -u root password yourpassword<br /><br />对于MySQL的任何版本，你可以用mysql程序并直接修改mysql数据库中的user授权表：<br /><br />% mysql -u root mysql<br />mysql&gt;UPDATE user SET password=PASSWORD("yourpassword") WHERE User="root";<br /><br />如果你有MySQL的老版本，使用mysql和UPDATE。<br /><br />在你设置完口令后，通过运行下列命令检查你是否需要告诉服务器重载授权表：<br /><br />% mysqladmin -u root status<br /><br />如果服务器仍然让你以root而不指定口令而连接服务器，重载授权表：<br /><br />% mysqladmin -u root reload<br /><br />在你设置了root的口令后（并且如果需要重载了授权表），你将需要在任何时候以root连接服务器时指定口令。</div></div></div><img src ="http://www.blogjava.net/WshmAndLily/aggbug/51382.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2006-06-08 16:03 <a href="http://www.blogjava.net/WshmAndLily/articles/51382.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MySQL数据库SQL语法参考</title><link>http://www.blogjava.net/WshmAndLily/articles/51374.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Thu, 08 Jun 2006 07:45:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/51374.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/51374.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/51374.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/51374.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/51374.html</trackback:ping><description><![CDATA[一、资料定义 ｄｄｌ（data definition language) <br /><br />　　资料定语言是指对资料的格式和形态下定义的语言，他是每个资料库要建立时候时首先要面对的，举凡资料分哪些表格关系、表格内的有什麽栏位主键、表格和表格之间互相参考的关系等等，都是在开始的时候所必须规划好的。 
<p>　　１、建表格： <br /><br />create table table_name( <br />column1 datatype [not null] [not null primary key], <br />column2 datatype [not null], <br />...);<br /><br />　　说明：　 <br /><br />datatype --是资料的格式，详见表。 <br />nut null --可不可以允许资料有空的（尚未有资料填入）。 <br />primary key --是本表的主键。 </p><p>　　２、更改表格　 <br /><br />alter table table_name <br />add column column_name datatype <br /><br />　　说明：增加一个栏位（没有删除某个栏位的语法。 <br /><br />alter table table_name <br />add primary key (column_name) <br /><br />　　说明：更改表得的定义把某个栏位设为主键。 <br /><br />alter table table_name <br />drop primary key (column_name) <br /><br />　　说明：把主键的定义删除。 </p><p>　　３、建立索引　 <br /><br />create index index_name on table_name (column_name) <br /><br />　　说明：对某个表格的栏位建立索引以增加查询时的速度。 </p><p>　　４、删除　 <br /><br />drop table_name <br />drop index_name </p><p>　　二、资料操作 ｄｍｌ （data manipulation language) <br /><br />　　资料定义好之後接下来的就是资料的操作。资料的操作不外乎增加资料（insert)、查询资料（query）、更改资料（update) 、删除资料（delete）四种模式，以下分 别介绍他们的语法： </p><p>　　１、增加资料： <br /><br />insert into table_name (column1,column2,...) <br />values ( value1,value2, ...) <br /><br />　　说明： <br /><br />　　1.若没有指定column 系统则会按表格内的栏位顺序填入资料。 <br /><br />　　2.栏位的资料形态和所填入的资料必须吻合。 <br /><br />　　3.table_name 也可以是景观 view_name。 </p><p>insert into table_name (column1,column2,...) <br />select columnx,columny,... from another_table <br /><br />　　说明：也可以经过一个子查询（subquery）把别的表格的资料填入。 </p><p>　　２、查询资料： <br /><br />　　基本查询 <br /><br />select column1,columns2,... <br />from table_name <br /><br />　　说明：把table_name 的特定栏位资料全部列出来 <br /><br />select * <br />from table_name <br />where column1 = xxx <br />[and column2 &gt; yyy] [or column3 &lt;&gt; zzz] <br /><br />　　说明： <br /><br />　　1.'*'表示全部的栏位都列出来。 <br /><br />　　2.where 之後是接条件式，把符合条件的资料列出来。 </p><p>select column1,column2 <br />from table_name <br />order by column2 [desc] <br /><br />　　说明：order by 是指定以某个栏位做排序，[desc]是指从大到小排列，若没有指明，则是从小到大 <br /><br />　　排列 </p><p>　　组合查询 <br /><br />　　组合查询是指所查询得资料来源并不只有单一的表格，而是联合一个以上的表格才能够得到结果的。 <br /><br />select * <br />from table1,table2 <br />where table1.colum1=table2.column1 <br /><br />　　说明： <br /><br />　　1.查询两个表格中其中 column1 值相同的资料。 <br /><br />　　2.当然两个表格相互比较的栏位，其资料形态必须相同。 <br /><br />　　3.一个复杂的查询其动用到的表格可能会很多个。 </p><p>　　整合性的查询： <br /><br />select count (*) <br />from table_name <br />where column_name = xxx <br /><br />　　说明： <br /><br />　　查询符合条件的资料共有几笔。 <br /><br />select sum(column1) <br />from table_name <br /><br />　　说明： <br /><br />　　1.计算出总和，所选的栏位必须是可数的数字形态。 <br /><br />　　2.除此以外还有 avg() 是计算平均、max()、min()计算最大最小值的整合性查询。 <br /><br />select column1,avg(column2) <br />from table_name <br />group by column1 <br />having avg(column2) &gt; xxx <br /><br />　　说明： <br /><br />　　1.group by: 以column1 为一组计算 column2 的平均值必须和 avg、sum等整合性查询的关键字一起使用。 <br /><br />　　2.having : 必须和 group by 一起使用作为整合性的限制。 </p><p>　　复合性的查询 <br /><br />select * <br />from table_name1 <br />where exists ( <br />select * <br />from table_name2 <br />where conditions ) <br /><br />　　说明： <br /><br />　　1.where 的 conditions 可以是另外一个的 query。 <br /><br />　　2.exists 在此是指存在与否。 <br /><br />select * <br />from table_name1 <br />where column1 in ( <br />select column1 <br />from table_name2 <br />where conditions ) <br /><br />　　说明：　 <br /><br />　　1. in 後面接的是一个集合，表示column1 存在集合里面。 <br /><br />　　2. select 出来的资料形态必须符合 column1。 </p><p>　　其他查询 <br /><br />select * <br />from table_name1 <br />where column1 like 'x%' <br /><br />　　说明：like 必须和後面的'x%' 相呼应表示以 x为开头的字串。 <br /><br />select * <br />from table_name1 <br />where column1 in ('xxx','yyy',..) <br /><br />　　说明：in 後面接的是一个集合，表示column1 存在集合里面。 <br /><br />select * <br />from table_name1 <br />where column1 between xx and yy <br /><br />　　说明：between 表示 column1 的值介於 xx 和 yy 之间。 </p><p>　　３、更改资料： <br /><br />update table_name <br />set column1='xxx' <br />where conditoins <br /><br />　　说明： <br /><br />　　1.更改某个栏位设定其值为'xxx'。 <br /><br />　　2.conditions 是所要符合的条件、若没有 where 则整个 table 的那个栏位都会全部被更改。 </p><p>　　４、删除资料： <br /><br />delete from table_name <br />where conditions <br /><br />　　说明：删除符合条件的资料。 </p><p>　　说明：关于where条件后面如果包含有日期的比较，不同<a href="http://dev.21tx.com/database/" target="_blank"><font color="#3366cc">数据库</font></a>有不同的表达式。具体如下： <br /><br />　　(1)如果是<a href="http://dev.21tx.com/database/access/" target="_blank"><font color="#3366cc">Access</font></a>数据库，则为：where mydate&gt;#2000-01-01# <br /><br />　　(2)如果是<a href="http://dev.21tx.com/database/oracle/" target="_blank"><font color="#3366cc">Oracle</font></a>数据库，则为：where mydate&gt;cast('2000-01-01' as date) 或：where mydate&gt;to_date('2000-01-01','yyyy-mm-dd') <br />在<a href="http://dev.21tx.com/language/delphi/" target="_blank"><font color="#3366cc">Delphi</font></a>中写成： <br /><br />thedate='2000-01-01'; <br />query1.sql.add('select * from abc where mydate&gt;cast('+''''+thedate+''''+' as date)'); </p><p>　　如果比较日期时间型，则为： <br /><br />where mydatetime&gt;to_date('2000-01-01 10:00:01','yyyy-mm-dd hh24:mi:ss'); </p><img src ="http://www.blogjava.net/WshmAndLily/aggbug/51374.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2006-06-08 15:45 <a href="http://www.blogjava.net/WshmAndLily/articles/51374.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>mysql数据库优化五步走</title><link>http://www.blogjava.net/WshmAndLily/articles/51373.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Thu, 08 Jun 2006 07:42:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/51373.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/51373.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/51373.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/51373.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/51373.html</trackback:ping><description><![CDATA[1:磁盘寻道能力,以高速硬盘(7200转/秒),理论上每秒寻道7200次.这是没有办法改变的,优化的方法是----用多个硬盘,或者把数据分散存储.<br />　　<br />　　2:硬盘的读写速度,这个速度非常的快,这个更容易解决--可以从多个硬盘上并行读写.<br />　　<br />　　3:cpu.cpu处理内存中的数据,当有相对内存较小的表时,这是最常见的限制因素.<br />　　<br />　　4:内存的限制.当cpu需要超出适合cpu缓存的数据时,缓存的带宽就成了内存的一个瓶颈---不过现在内存大的惊人,一般不会出现这个问题.<br />　　<br />　　<b>第二步: (本人使用的是学校网站的linux平台(Linux ADVX.Mandrakesoft.com 2.4.3-19mdk ))<br />　　</b><br />　　1:调节服务器参数<br />　　<br />　　用shell&gt;mysqld-help这个命令声厂一张所有mysql选项和可配置变量的表.输出以下信息:<br />　　<br />　　possible variables for option--set-variable(-o) are:<br />　　<br />　　back_log current value:5 //要求mysql能有的连接数量.back_log指出在mysql暂停接受连接的时间内有多少个连接请求可以被存在堆栈中<br />　　<br />　　connect_timeout current value:5 //mysql服务器在用bad handshake(不好翻译)应答前等待一个连接的时间<br />　　<br />　　delayed_insert_timeout current value:200 //一个insert delayed在终止前等待insert的时间<br />　　<br />　　delayed_insert_limit current value:50 //insert delayed处理器将检查是否有任何select语句未执行,如果有,继续前执行这些语句<br />　　<br />　　delayed_queue_size current value:1000 //为insert delayed分配多大的队<br />　　<br />　　flush_time current value:0 //如果被设置为非0,那么每个flush_time 时间,所有表都被关闭<br />　　<br />　　interactive_timeout current value:28800 //服务器在关上它之前在洋交互连接上等待的时间<br />　　<br />　　join_buffer_size current value:131072 //用与全部连接的缓冲区大小<br />　　<br />　　key_buffer_size current value:1048540 //用语索引块的缓冲区的大小,增加它可以更好的处理索引<br />　　<br />　　lower_case_table_names current value:0 //<br />　　<br />　　long_query_time current value:10 //如果一个查询所用时间大于此时间,slow_queried计数将增加<br />　　<br />　　max_allowed_packet current value:1048576 //一个包的大小<br />　　<br />　　max_connections current value:300 //允许同时连接的数量<br />　　<br />　　max_connect_errors current value:10 //如果有多于该数量的中断连接,将阻止进一步的连接,可以用flush hosts来解决<br />　　<br />　　max_delayed_threads current value:15 //可以启动的处理insert delayed的数量<br />　　<br />　　max_heap_table_size current value:16777216 //<br />　　<br />　　max_join_size current value:4294967295 //允许读取的连接的数量<br />　　<br />　　max_sort_length current value:1024 //在排序blob或者text时使用的字节数量<br />　　<br />　　max_tmp_tables current value:32 //一个连接同时打开的临时表的数量<br />　　<br />　　max_write_lock_count current value:4294967295 //指定一个值(通常很小)来启动mysqld,使得在一定数量的write锁定之后出现read锁定<br />　　<br />　　net_buffer_length current value:16384 //通信缓冲区的大小--在查询时被重置为该大小<br />　　<br />　　query_buffer_size current value:0 //查询时缓冲区大小<br />　　<br />　　record_buffer current value:131072 //每个顺序扫描的连接为其扫描的每张表分配的缓冲区的大小<br />　　<br />　　sort_buffer current value:2097116 //每个进行排序的连接分配的缓冲区的大小<br />　　<br />　　table_cache current value:64 //为所有连接打开的表的数量<br />　　<br />　　thread_concurrency current value:10 //<br />　　<br />　　tmp_table_size current value:1048576 //临时表的大小<br />　　<br />　　thread_stack current value:131072 //每个线程的大小<br />　　<br />　　wait_timeout current value:28800 //服务器在关闭它3之前的一个连接上等待的时间<br />　　<br />　　根据自己的需要配置以上信息会对你帮助.<br />　　<strong>第三:<br /></strong>　　<br />　　1:如果你在一个数据库中创建大量的表,那么执行打开,关闭，创建(表)的操作就会很慢. 2:mysql使用内存<br />　　<br />　　a: 关键字缓存区(key_buffer_size)由所有线程共享<br />　　<br />　　b: 每个连接使用一些特定的线程空间.一个栈(默认为64k,变量thread_stack),一个连接缓冲区(变量net_buffer_length)和一个结果缓冲区(net_buffer_length).特定情况下,连接缓冲区和结果缓冲区被动态扩大到max_allowed_packet.<br />　　<br />　　c:所有线程共享一个基存储器<br />　　<br />　　d:没有内存影射<br />　　<br />　　e:每个做顺序扫描的请求分配一个读缓冲区(record_buffer)<br />　　<br />　　f:所有联结均有一遍完成并且大多数联结甚至可以不用一个临时表完成.最临时的表是基于内存的(heap)表<br />　　<br />　　g:排序请求分配一个排序缓冲区和2个临时表<br />　　<br />　　h:所有语法分析和计算都在一个本地存储器完成<br />　　<br />　　i:每个索引文件只被打开一次,并且数据文件为每个并发运行的线程打开一次<br />　　<br />　　j:对每个blob列的表，一个缓冲区动态的被扩大以便读入blob值<br />　　<br />　　k:所有正在使用的表的表处理器被保存在一个缓冲器中并且作为一个fifo管理.<br />　　<br />　　l:一个mysqladmin flush-tables命令关闭所有不在使用的表并且在当前执行的线程结束时标记所有在使用的表准备关闭<br />　　<br />　　3:mysql锁定表<br />　　<br />　　mysql中所有锁定不会成为死锁. wirte锁定: mysql的锁定原理:a:如果表没有锁定,那么锁定;b否则,把锁定请求放入写锁定队列中<br />　　<br />　　read锁定: mysql的锁定原理:a:如果表没有锁定,那么锁定;b否则,把锁定请求放入读锁定队列中<br />　　<br />　　有时候会在一个表中进行很多的select,insert操作,可以在一个临时表中插入行并且偶尔用临时表的记录更新真正的表<br />　　<br />　　a:用low_priority属性给一个特定的insert,update或者delete较低的优先级<br />　　<br />　　b:max_write_lock_count指定一个值(通常很小)来启动mysqld,使得在一定数量的write锁定之后出现read锁定<br />　　<br />　　c:通过使用set sql_low_priority_updates=1可以从一个特定的线程指定所有的更改应该由较低的优先级完成<br />　　<br />　　d:用high_priority指定一个select<br />　　<br />　　e:如果使用insert....select....出现问题,使用myisam表------因为它支持因为它支持并发的select和insert<br />　　<br />　　4:最基本的优化是使数据在硬盘上占据的空间最小.如果索引做在最小的列上,那么索引也最小.实现方法:<br />　　<br />　　a:使用尽可能小的数据类型<br />　　<br />　　b:如果可能，声明表列为NOT NULL.<br />　　<br />　　c:如果有可能使用变成的数据类型,如varchar(但是速度会受一定的影响)<br />　　<br />　　d:每个表应该有尽可能短的主索引 e:创建确实需要的索引<br />　　<br />　　f:如果一个索引在头几个字符上有唯一的前缀,那么仅仅索引这个前缀----mysql支持在一个字符列的一部分上的索引<br />　　<br />　　g:如果一个表经常被扫描,那么试图拆分它为更多的表<br />　　<br />　　<b>第四步</b><br />　　<br />　　1:索引的使用,索引的重要性就不说了,功能也不说了,只说怎么做. 首先要明确所有的mysql索引(primary,unique,index)在b树中有存储.索引主要用语:<br />　　<br />　　a:快速找到where指定条件的记录 b:执行联结时,从其他表检索行 c:对特定的索引列找出max()和min()值<br />　　<br />　　d：如果排序或者分组在一个可用键的最前面加前缀，排序或分组一个表<br />　　<br />　　e：一个查询可能被用来优化检索值，而不用访问数据文件．如果某些表的列是数字型并且正好是某个列的前缀，为了更快，值可以从索引树中取出<br />　　<br />　　２：存储或者更新数据的查询速度 　grant的执行会稍稍的减低效率．<br />　　<br />　　mysql的函数应该被高度的优化．可以用benchmark（loop_count,expression)来找出是否查询有问题<br />　　<br />　　select的查询速度：如果想要让一个select．．．where．．．更快，我能想到的只有建立索引．可以在一个表上运行myisamchk－－analyze来更好的优化查询．可以用myisamchk－－sort－index－－sort－records＝１来设置用一个索引排序一个索引和数据．<br />　　<br />　　３：mysql优化where子句<br />　　<br />　　3.１：删除不必要的括号：<br />　　<br />　　（（a AND b) AND c OR (((a AND b) AND (a AND d))))&gt;(a AND b AND c) OR (a AND b AND c AND d)<br />　　<br />　　3.2:使用常数<br />　　<br />　　（ab&gt;5 AND b=c AND a=5<br />　　<br />　　3.3:删除常数条件<br />　　<br />　　（b&gt;=5 AND b=5) OR (b=6 AND 5=5) OR (b=100 AND 2=3) &gt;b=5 OR b=6<br />　　<br />　　3.4:索引使用的常数表达式仅计算一次<br />　　<br />　　3.5：在一个表中，没有一个where的count(*)直接从表中检索信息<br />　　<br />　　3.6:所有常数的表在查询中在任何其他表之前读出<br />　　<br />　　3.7:对外联结表最好联结组合是尝试了所有可能性找到的<br />　　<br />　　3.8：如果有一个order　by字句和一个不同的group　by子句或者order　by或者group　by包含不是来自联结的第一个表的列，那么创建一个临时表<br />　　<br />　　3.9:如果使用了sql_small_result，那么msyql使用在内存中的一个表<br />　　<br />　　3.10:每个表的索引给查询并且使用跨越少于３０％的行的索引．<br />　　<br />　　3.11在每个记录输出前，跳过不匹配having子句的行<br />４：优化left　join<br />　　<br />　　在mysql中　a left join b按以下方式实现<br />　　<br />　　a：表b依赖于表a　<br />　　<br />　　b：表a依赖于所有用在left　join条件的表（除了b）<br />　　<br />　　c：所有left　join条件被移到where子句中<br />　　<br />　　d：进行所有的联结优化，除了一个表总是在所有他依赖的表后读取．如果有一个循环依赖，那么将发生错误<br />　　<br />　　e：进行所有的标准的where优化 f：如果在a中有一行匹配where子句，但是在b中没有任何匹配left　join条件，那么，在b中生成的所有设置为ＮＵＬＬ的一行<br />　　<br />　　g：如果使用left　join来找出某些表中不存在的行并且在where部分有column_name IS NULL测试(column_name为NOT NULL列)．那么，mysql在它已经找到了匹配left　join条件的一行后，将停止在更多的行后寻找<br />　　<br />　　５：优化limit<br />　　<br />　　a：如果用limit只选择一行，当mysql需要扫描整个表时，它的作用相当于索引<br />　　<br />　　b：如果使用limit＃与order　by，mysql如果找到了第＃行，将结束排序，而不会排序正个表<br />　　<br />　　c：当结合limit＃和distinct时，mysql如果找到了第＃行，将停止<br />　　<br />　　d：只要mysql已经发送了第一个＃行到客户，mysql将放弃查询<br />　　<br />　　e：limit 0一直会很快的返回一个空集合．<br />　　<br />　　f：临时表的大小使用limit＃计算需要多少空间来解决查询<br />　　<br />　　６：优化insert<br />　　<br />　　插入一条记录的是由以下构成：<br />　　<br />　　a:连接（３）<br />　　<br />　　b:发送查询给服务器（２）<br />　　<br />　　c:分析查询（２）<br />　　<br />　　d:插入记录（１*记录大小）<br />　　<br />　　e：插入索引（１*索引）<br />　　<br />　　f：关闭（１）<br />　　<br />　　以上数字可以看成和总时间成比例<br />　　<br />　　改善插入速度的一些方法：<br />　　<br />　　6.1：如果同时从一个连接插入许多行，使用多个值的insert，这比用多个语句要快<br />　　<br />　　6.2：如果从不同连接插入很多行，使用insert　delayed语句速度更快<br />　　<br />　　6.3: 用myisam，如果在表中没有删除的行，能在select：s正在运行的同时插入行<br />　　<br />　　6.4: 当从一个文本文件装载一个表时，用load　data　infile．这个通常比insert快20 倍<br />　　<br />　　6.5:可以锁定表然后插入－－主要的速度差别是在所有insert语句完成后，索引缓冲区仅被存入到硬盘一次．一般与有不同的insert语句那样多次存入要快．如果能用一个单个语句插入所有的行，锁定就不需要．锁定也降低连接的整体时间．但是对某些线程最大等待时间将上升．例如：<br />　　<br />　　thread 1 does 1000 inserts<br />　　<br />　　thread 2,3 and 4 does 1 insert<br />　　<br />　　thread 5 does 1000 inserts<br />　　<br />　　如果不使用锁定，２，３，４将在１和５之前完成．如果使用锁定，２，３，４，将可能在１和５之后完成．但是整体时间应该快４０％．因为insert，update，delete操作在mysql中是很快的，通过为多于大约５次连续不断的插入或更新一行的东西加锁，将获得更好的整体性能．如果做很多一行的插入，可以做一个lock　tables，偶尔随后做一个unlock　tables（大约每１０００行）以允许另外的线程存取表．这仍然将导致获得好的性能．load　data　infile对装载数据仍然是很快的．<br />　　<br />　　为了对load　data　infile和insert得到一些更快的速度，扩大关键字缓冲区．<br />　　<br />　　７优化update的速度<br />　　<br />　　它的速度依赖于被更新数据的大小和被更新索引的数量<br />　　<br />　　使update更快的另一个方法是推迟修改，然后一行一行的做很多修改．如果锁定表，做一行一行的很多修改比一次做一个快<br />　　<br />　　８优化delete速度<br />　　<br />　　删除一个记录的时间与索引数量成正比．为了更快的删除记录，可以增加索引缓存的大小 从一个表删除所有行比删除这个表的大部分要快的多<br />　　<br />　　<b>第五步</b><br />　　<br />　　１：选择一种表类型 1.1静态myisam<br />　　<br />　　这种格式是最简单且最安全的格式，它是磁盘格式中最快的．速度来自于数据能在磁盘上被找到的难易程度．当锁定有一个索引和静态格式的东西是，它很简单，只是行长度乘以数量．而且在扫描一张表时，每次用磁盘读取来读入常数个记录是很容易的．安全性来源于如果当写入一个静态myisam文件时导致计算机down掉，myisamchk很容易指出每行在哪里开始和结束，因此，它通常能收回所有记录，除了部分被写入的记录．在mysql中所有索引总能被重建<br />　　<br />　　1.2动态myisam<br />　　<br />　　这种格式每一行必须有一个头说明它有多长．当一个记录在更改期间变长时，它可以在多于一个位置上结束．能使用optimize　tablename或myisamchk整理一张表．如果在同一个表中有像某些varchar或者blob列那样存取／改变的静态数据，将动态列移入另外一个表以避免碎片．<br />　　<br />　　1.2.1压缩myisam，用可选的myisampack工具生成<br />1.2.2内存<br />　　<br />　　这种格式对小型／中型表很有用．对拷贝／创建一个常用的查找表到洋heap表有可能加快多个表联结，用同样数据可能要快好几倍时间．<br />　　<br />　　select tablename.a,tablename2.a from tablename,tablanem2,tablename3 where<br />　　<br />　　tablaneme.a=tablename2.a and tablename2.a=tablename3.a and tablename2.c!=0;<br />　　<br />　　为了加速它，可以用tablename2和tablename3的联结创建一个临时表，因为用相同列（tablename1.a）查找．<br />　　<br />　　ＣＲＥＡＴＥ　ＴＥＭＰＯＲＡＲＹ　ＴＡＢＬＥ　test TYPE=HEAP<br />　　<br />　　SELECT<br />　　<br />　　tablename2.a as a2,tablename3.a as a3<br />　　<br />　　FROM<br />　　<br />　　tablenam2,tablename3<br />　　<br />　　WHERE<br />　　<br />　　tablename2.a=tablename3.a and c=0;<br />　　<br />　　SELECT tablename.a,test.a3 from tablename,test where tablename.a=test.a1;<br />　　<br />　　SELECT tablename.a,test,a3,from tablename,test where tablename.a=test.a1 and ....;<br />　　<br />　　1.3静态表的特点<br />　　<br />　　1.3.1默认格式．用在表不包含varchar，blob，text列的时候<br />　　<br />　　1.3.2所有的char，numeric和decimal列填充到列宽度<br />　　<br />　　1.3.3非常快<br />　　<br />　　1.3.4容易缓冲<br />　　<br />　　1.3.5容易在down后重建，因为记录位于固定的位置<br />　　<br />　　1.3.6不必被重新组织（用myisamchk），除非是一个巨量的记录被删除并且优化存储大小<br />　　<br />　　1.3.7通常比动态表需要更多的存储空间<br />　　<br />　　1.4动态表的特点<br />　　<br />　　1.4.1如果表包含任何varchar，blob，text列，使用该格式<br />　　<br />　　1.4.2所有字符串列是动态的<br />　　<br />　　1.4.3每个记录前置一个位．<br />　　<br />　　1.4.4通常比定长表需要更多的磁盘空间<br />　　<br />　　1.4.5每个记录仅仅使用所需要的空间，如果一个记录变的很大，它按需要被分成很多段，这导致了记录碎片<br />　　<br />　　1.4.6如果用超过行长度的信息更新行，行被分段．<br />　　<br />　　1.4.7在系统down掉以后不好重建表，因为一个记录可以是多段<br />　　<br />　　1.4.8对动态尺寸记录的期望行长度是３＋（number　of　columns＋７）／８＋(number of char columns)+packed size of numeric columns+length of strings +(number of NULL columns+7)/8<br />　　<br />　　对每个连接有６个字节的惩罚．无论何时更改引起记录的变大，都有一个动态记录被连接．每个新连接至少有２０个字节，因此下一个变大将可能在同一个连接中．如果不是，将有另外一个连接．可以用myisamchk　－恶毒检查有多少连接．所有连接可以用myisamchk -r删除．<br />　　<br />　　1.5压缩表的特点<br />　　<br />　　1.5.1一张用myisampack实用程序制作的只读表．<br />　　<br />　　1.5.2解压缩代码存在于所有mysql分发中，以便使没有myisampack的连接也能读取用myisampack压缩的表<br />　　<br />　　1.5.3占据很小的磁盘空间<br />　　<br />　　1.5.4每个记录被单独压缩．一个记录的头是一个定长的（１～～３个字节）这取决于表的最大记录．每列以不同的方式被压缩．一些常用的压缩类型是：<br />　　<br />　　a:通常对每列有一张不同的哈夫曼表 　b:后缀空白压缩 　c:前缀空白压缩 d:用值０的数字使用１位存储<br />　　<br />　　e:如果整数列的值有一个小范围，列使用最小的可能类型来存储．例如：如果所有的值在０到２５５之间，一个bigint可以作为一个tinyint存储<br />　　<br />　　g:如果列仅有可能值的一个小集合，列类型被转换到enum 　h:列可以使用上面的压缩方法的组合<br />　　<br />　　1.5.5能处理定长或动态长度的记录，去不能处理blob或者text列 1.5.6能用myisamchk解压缩<br />　　<br />　　mysql能支持不同的索引类型，但一般的类型是isam，这是一个Ｂ树索引并且能粗略的为索引文件计算大小为(key_length+4)*0.67，在所有的键上的总和．<br />　　<br />　　字符串索引是空白压缩的。如果第一个索引是一个字符串，它可将压缩前缀如果字符串列有很多尾部空白或是一个总部能甬道全长的varchar列，空白压缩使索引文件更小．如果很多字符串有相同的前缀．<br />　　<br />　　1.6内存表的特点<br />　　<br />　　mysql内部的heap表使用每偶溢出去的１００％动态哈希并且没有与删除有关的问题．只能通过使用在堆表中的一个索引来用等式存取东西（通常用＇＝＇操作符）<br />　　<br />　　堆表的缺点是：<br />　　<br />　　1.6.1想要同时使用的所有堆表需要足够的额外内存<br />　　<br />　　1.6.2不能在索引的一个部分搜索<br />　　<br />　　1.6.3不能按顺序搜索下一个条目（即，使用这个索引做一个order　by）<br />　　<br />　　1.6.4mysql不能算出在２个值之间大概有多少行．这被优化器使用是用来决定使用哪个索引的，但是在另一个方面甚至不需要磁盘寻道<img src ="http://www.blogjava.net/WshmAndLily/aggbug/51373.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2006-06-08 15:42 <a href="http://www.blogjava.net/WshmAndLily/articles/51373.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数据库人员手边系列：Mysql字段长度</title><link>http://www.blogjava.net/WshmAndLily/articles/51370.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Thu, 08 Jun 2006 07:37:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/51370.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/51370.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/51370.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/51370.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/51370.html</trackback:ping><description><![CDATA[
		<div class="content" id="BodyLabel" style="PADDING-RIGHT: 10px; DISPLAY: block; PADDING-LEFT: 10px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px">列类型 需要的存储量<br />　　<br />　　TINYINT 1 字节<br />　　<br />　　SMALLINT 2 个字节<br />　　<br />　　MEDIUMINT 3 个字节<br />　　<br />　　INT 4 个字节<br />　　<br />　　INTEGER 4 个字节<br />　　<br />　　BIGINT 8 个字节<br />　　<br />　　FLOAT(X) 4 如果 X &lt; = 24 或 8 如果 25 &lt; = X &lt; = 53<br />　　<br />　　FLOAT 4 个字节<br />　　<br />　　DOUBLE 8 个字节<br />　　<br />　　DOUBLE PRECISION 8 个字节<br />　　<br />　　REAL 8 个字节<br />　　<br />　　DECIMAL(M,D) M字节(D+2 , 如果M &lt; D)<br />　　<br />　　NUMERIC(M,D) M字节(D+2 , 如果M &lt; D)<br />　　<br />　　日期和时间类型<br />　　<br />　　列类型 需要的存储量<br />　　<br />　　DATE 3 个字节<br />　　<br />　　DATETIME 8 个字节<br />　　<br />　　TIMESTAMP 4 个字节<br />　　<br />　　TIME 3 个字节<br />　　<br />　　YEAR 1 字节<br />　　<br />　　串类型<br />　　<br />　　列类型 需要的存储量<br />　　<br />　　CHAR(M) M字节，1 &lt;= M &lt;= 255<br />　　<br />　　VARCHAR(M) L+1 字节, 在此L &lt;= M和1 &lt;= M &lt;= 255<br />　　<br />　　TINYBLOB, TINYTEXT L+1 字节, 在此L&lt; 2 ^ 8<br />　　<br />　　BLOB, TEXT L+2 字节, 在此L&lt; 2 ^ 16<br />　　<br />　　MEDIUMBLOB, MEDIUMTEXT L+3 字节, 在此L&lt; 2 ^ 24<br />　　<br />　　LONGBLOB, LONGTEXT L+4 字节, 在此L&lt; 2 ^ 32<br />　　<br />　　ENUM('value1','value2',...) 1 或 2 个字节, 取决于枚举值的数目(最大值65535)<br />　　<br />　　SET('value1','value2',...) 1，2，3，4或8个字节, 取决于集合成员的数量(最多64个成员)</div>
<img src ="http://www.blogjava.net/WshmAndLily/aggbug/51370.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2006-06-08 15:37 <a href="http://www.blogjava.net/WshmAndLily/articles/51370.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于Mysql 4.1语言问题的完美解决方法</title><link>http://www.blogjava.net/WshmAndLily/articles/51369.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Thu, 08 Jun 2006 07:34:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/51369.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/51369.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/51369.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/51369.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/51369.html</trackback:ping><description><![CDATA[
		<div class="content" id="BodyLabel" style="PADDING-RIGHT: 10px; DISPLAY: block; PADDING-LEFT: 10px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px">可以不需要修改my.ini。在建立数据库的时候，对库和表的字符集设置不太重要，但是对文本类型的字段最好都设置为GBK字符集。 
<p>    对于已有的数据库可以用以下方法转换字段编码：</p><p>    ALTER TABLE t MODIFY hoverfly BINARY(100);</p><p>    ALTER TABLE t MODIFY hoverfly CHAR(100) CHARACTER SET gbk;</p><p>    注意用此方法如果不修改程序，会发现查询出的结果都是乱码，可以通过在my.ini的[mysqld]段内加default-character-set=gbk来纠正。但是这样你会发现那些没有转换编码的文本字段里的中文都是乱码。</p><p>    其实有更简单的办法，在进行查询前，只要执行SET character_set_results = NULL就可以。而且这是不管是转换了的还是没转换的字段都不会出现乱码。而转换了的字段可以正常的对中文进行排序。</p></div>
<img src ="http://www.blogjava.net/WshmAndLily/aggbug/51369.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2006-06-08 15:34 <a href="http://www.blogjava.net/WshmAndLily/articles/51369.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>