Currently Browsing
数据库
linux下超大文件删除结尾若干行的方法
- 25 八月 //
- Posted in 数据库 //
- Tags :
- No Comment
标题很唬人,超大是多大呢?今天我碰到的是4G。
在恢复一个MySQL的备份文件(db_backup.sql)的时候,老提示字符串有错误,开始以为是字符集的问题,于是在还原命令里强行写–default-character-set=gbk,也没有效果。
看到错误提示里有关键字“abcd.pdf”,于是想打开这个备份文件来看看是错在哪个表。
问题来了,这个文件有4G,估计没有哪个编辑器能顺溜溜地打开。好吧,先把它分割
#split -b 100m db_backup.sql
于是产生了若干个100M大小的文件 如xaa xab….xbg等等….
MySQL还原时出现超时“gone away”的问题解决方法
- 25 八月 //
- Posted in 数据库 //
- Tags :
- No Comment
在还原比较大的mysql备份文件的时候,经常出现“gone away”的提示,这是由于MySQL的默认配置中相关参数没有设置好的原因。
要解决这个问题,我们需要先打开你的MySQL安装目录的 my.ini(linux下为my.cnf)文件,找到[mysqld]这一节(注意,这很重要,我试过如果放在其他地方,是不会起作用的),然后在里面加上如下的三行,这三行就随便放哪里都行的,如下是一个例子:

sql语句中COUNT与DISTINCT一起使用的方法
- 21 八月 //
- Posted in 数据库 //
- Tags :
- No Comment
来自于http://pavel.javaeye.com/622382
SELECT COUNT(DISTINCT column(s)) FROM table
linux下mysql(非编译版)的重启操作
- 16 八月 //
- Posted in 数据库 //
- Tags :
- No Comment
停止:/usr/local/mysql/bin/mysqladmin –uroot -p123456 shutdown
启动:/usr/local/mysql/bin/mysqld_safe –user=mysql &
还原mysql数据库时出现”data too long for column”错误的解决办法
- 20 六月 //
- Posted in 数据库 //
- Tags : mysql 错误
- No Comment
在还原一个wordpress的数据库备份文件 wp.sql 的时候,不管在GUI的管理器里运行sql还是在命令行里运行还原语句,都提示“data too long for column ‘name’”。
在GUI工具里将数据库修改为utf8编码后再粘贴sql运行,无果。
查看wp.sql文件,确实是utf8的编码,不知问题出在哪。
百度了一下,终于解决,原来在命令行下还原时,要强制指定默认的字符集,如下:
>mysql –uroot –p123456 –default-character-set=utf8 wordpress<D:\wp.sql
顺利解决。更详细的参考文章及原因分析见以下博文:http://linuxbai.javaeye.com/616720
[转] mysql group by与order by排序问题
- 1 三月 //
- Posted in 数据库 //
- Tags :
- No Comment
原文链接:http://www.offid.cn/i/2008/note/89060.html
在使用mysql排序的时候会想到按照降序分组来获得一组数据,而使用order by往往得到的不是理想中的结果,那么怎么才能使用group by 和order by得到理想中的数据结果呢?
例如 有一个 帖子的回复表,posts( id , tid , subject , message , dateline ) ,
id为 自动增长字段, tid为该回复的主题帖子的id(外键关联), subject 为回复标题, message 为回复内容, dateline 为回复时间,用UNIX 时间戳表示,
现在要求 选出 前十个来自不同主题的最新回复
SELECT * FROM posts GROUP BY tid LIMIT 10
这样一个sql语句选出来的并非你想要的 最新的回复,而是最早的回复,实际上是某篇主题的第一条回复记录!
也就是说 GROUP BY 语句没有排序,那么怎么才能让 GROUP 按照 dateline 倒序排列呢?加上 order by 子句?
看下面:
SELECT * FROM posts GROUP BY tid ORDER BY dateline DESC LIMIT 10
这条语句选出来的结果和上面的完全一样,不过把结果倒序排列了,而选择出来的每一条记录仍然是上面的记录,原因是 group by 会比 order by 先执行,这样也就没有办法将 group by 之前,也就是在分组之前进行排序了, 有网友会写出下面的sql 语句:
SELECT * FROM posts GROUP BY tid DESC ORDER BY dateline DESC LIMIT 10
也就是说 在 GROUP BY 的字段 tid 后面加上递减顺序,这样不就可以取得分组时的最后回复了吗?这个语句执行结果会和上面的一模一样,这里加上 DESC 和ASC对执行结果没有任何影响!其实这是一个错误的语句,原因是GROUP BY 之前并没有排序功能,mysql 手册上面说,GROUP BY 时是按照某种顺序排序的,某种顺序到底是什么顺序?其实根本没有顺序,因为按照tid分组,其实也就是说,把tid相等的归纳到一个组,这样想的话,GROUP BY tid DESC 可以认为是在按照 tid 分组的时候,按照tid进行倒序排列,这不扯吗,既然是按照tid分组,当然是tid相等的归到一组,而这时候按照tid倒叙还是升序有个P用!
于是有网友发明下面的语句:
SELECT * FROM posts GROUP BY tid , dateline DESC ORDER BY dateline DESC LIMIT 10
心想这样我就可以在分组前按照 dateline 倒序排列了,其实这个语句并没有起到按照tid分组的作用,原因还是上面的,在group by 字段后加 desc 还是 asc 是错误的写法,而这种写法 网友本意是想 按照 tid 分组,并且在分组的时候按照 dateline排倒序!而实际这句相当于下面的写法:(去掉 GROUP BY 字段后面的 DESC)
SELECT * FROM posts GROUP BY tid , dateline ORDER BY dateline DESC LIMIT 10
也就是说,按照 tid 和 dateline 联合分组,只有在记录tid和dateline 同时相等的时候才归纳到一组,这显然不可能, 因为 dateline 时间线基本上是唯一的!
有人写出下面的语句:
SELECT *,max(dateline) as max_line FROM posts GROUP BY tid ORDER BY dateline DESC LIMIT 10
这条语句的没错是选出了最大发布时间,但是你可以对比一下 dateline 和 max_dateline 并不相等!(可能有相当的情况,就是分组的目标记录只有一条的时候!)
为什么呢?原因很简单,这条语句相当于是 在group by 以后选出 本组的最大的 发布时间!对分组没有起到任何影响!因为SELECT子句是最后执行的!
后来更有网友发明了下面的写法!
SELECT *,max(dateline) as max_line FROM posts GROUP BY tid HAVING dateline=max(dateline) ORDER BY dateline DESC LIMIT 10
这条语句的预期结果和想象中的并不相同!因为你会发现,分组的结果中大量的记录没有了!为什么?因为 HAVING 是在分组的时候执行的,也就说:在分组的时候加上一个这样的条件:选择出来的 dateline 要和 本组最大的dateline 相等,执行的结果和下面的语句相同:
SELECT *,max(dateline) as max_line FROM posts GROUP BY tid HAVING count(*)=1 ORDER BY dateline DESC LIMIT 10
看了这条sql语句是不是明白了呢?
dateline=max(dateline) 只有在分组中的记录只有一条的时候才成立,原因很明白吧!只有一条他才会和本组的最大发布时间相等阿,(默认dateline为不重复的值)
原因还是因为 group by 并没有排序功能,所有的这些排序功能只是错觉,所以你最终选出的 dateline 和max(dateline) 永远不可能相等,除非本组的记录只有一条!GROUP BY 在分组的时候,可能是一个一个来找的,发现有相等的tid,去掉,保留第一个发现的那一条记录,所以找出来的 记录永远只是按照默认索引顺序排列的!
那么说了这么多,到底有没有办法让 group by 执行前分组阿?有的 ,子查询阿!
最简单的 :
SELECT * FROM (SELECT * FROM posts ORDER BY dateline DESC) GROUP BY tid ORDER BY dateline DESC LIMIT 10
也有网友利用自连接实现的 ,这样的效率应该比上面的子查询效率高,不过,为了简单明了,就只用这样一种了,GROUP BY没有排序功能,可能是mysql弱智的地方,也许是我还没有发现,
期待高人拍砖!
=============我是分割线啊 我是分割线==========
补充,使用子查询后,mysql提示出错 于是修改了一下最后的那句sql 给了个别名就可以了,aliasposts用于区别子查询里面的posts
SELECT * FROM (SELECT * FROM posts ORDER BY dateline DESC) alisaposts GROUP BY alisaposts .tid ORDER BY alisaposts .dateline DESC LIMIT 10
另外提醒原作者 子查询里面的 posts表 如果帖子数过多 可能会有连接超时 最好给个LIMIT
mysql中内存表的使用
- 3 十二月 //
- Posted in 数据库 //
- Tags : 内存表, 数据库
- No Comment
一句话概括内存表的概念和特性“内存表使用哈希散列索引把数据保存在内存中,因此具有极快的速度,适合缓存中小型数据库,但是使用上受到一些限制”
具体特征如下:(转载自http://hi.baidu.com/netcoffeehuang/item/97f570193d539a7ddab4bd9c.html)
1、heap对所有用户的连接是可见的,这使得它非常适合做缓存。
2、仅适合使用的场合。heap不允许使用xxxTEXT和xxxBLOB数据类型;只允许使用=和<=>操作符来搜索记录(不允许& amp; lt;、>、<=或>=);不支持auto_increment;只允许对非空数据列进行索引(not null)。
注:操作符 “<=>” 说明:NULL-safe equal.这个操作符和“=”操作符执行相同的比较操作,不过在两个操作码均为NULL时,其所得值为1而不为NULL,而当一个操作码为NULL时,其所得值为0而不为NULL。
3、一旦服务器重启,所有heap表数据丢失,但是heap表结构仍然存在,因为heap表结构是存放在实际数据库路径下的,不会自动删除。重启之后,heap将被清空,这时候对heap的查询结果都是空的。
4、如果heap是复制的某数据表,则复制之后所有主键、索引、自增等格式将不复存在,需要重新添加主键和索引,如果需要的话。
5、对于重启造成的数据丢失,有以下的解决办法:
a、在任何查询之前,执行一次简单的查询,判断heap表是否存在数据,如果不存在,则把数据重新写入,或者DROP表重新复制某张表。这需要多做一次查询。不过可以写成include文件,在需要用该heap表的页面随时调用,比较方便。
b、对于需要该heap表的页面,在该页面第一次且仅在第一次查询该表时,对数据集结果进行判断,如果结果为空,则需要重新写入数据。这样可以节省一次查询。
c、更好的办法是在mysql每次重新启动时自动写入数据到heap,但是需要配置服务器,过程比较复杂,通用性受到限制。
6、实例:复制一个内存表
//如果表存在,则删除
DROP TABLE IF EXISTS `abc`;
//复制整张表xyz为heap表abc(包含所有数据)
CREATE TABLE `abc` type=heap select * from `xyz`;
//添加主键id
ALTER TABLE `abc` ADD PRIMARY KEY (`id`);
//添加索引username
ALTER TABLE `abc` ADD INDEX `abc` (`username`);
7.建表实例
CREATE TABLE `DB` (
`id` int(11) default NULL,
`songname` varchar(255) NOT NULL default ”,
`singer` varchar(255) NOT NULL default ”,
KEY `songname` (`songname`,`singer`)
) TYPE=HEAP
建表时TABLE TYPE 选项也有
这个表结构就是建立了内存表。
如果MYSQL重启 那内存表的数据 将会消失。
但访问速度会很快!
mysql的备份和还原的编码问题解决
- 1 十二月 //
- Posted in 数据库 //
- Tags : mysql 备份 还原 编码
- No Comment
今天需要从远程服务器down一个uchome的数据库下来,在本地还原。
发现一个很不爽的事情:远程8G,N核的linux机器,备份还原操作顺溜溜的,可是在本地的windows,2G普通PC上,才100M的文件,用uchome自带的分卷备份还原,基本上中间都会断掉,要么提示“执行时间过长”(改成200秒,分卷为20M都不行),要么就是中途白屏。
得了,用mysqldump备份的一个独立文件来运行命令行还原吧。
首先运行还原语句:
mysql -uroot -p123456 mydatabase < d:\backupdatabase.sql
时间缓慢地逝去,一口水喝完,上个厕所,再溜达一下,终于完成了(在远程linux服务器上也就20秒的功夫!)
然后更新缓存,发现数据乱码了,咦,我备份的时候是强制的gbk编码啊!看看备份的语句:
mysqldump -uroot -p123456 –default-character-set=gbk mydatabase > /usr/local/mysql/backup/backup20091026.sql
没错啊!已经设置了默认字符集为gbk了,看来可能是在还原的时候也要设置吧,于是修改还原语句,手工指定字符编码
mysql -uroot -p123456 font –default-character-set=gbk mydatabase < d:\backupdatabase.sql
又是漫长的等待…刷新页面一看,现在乱码解决了。
总结:在不同的操作系统和数据库环境之间备份与还原时,还是两边都强制制定一个字符集最保险。
mysql字符串连接操作
- 1 十二月 //
- Posted in 数据库 //
- Tags : mysql 字符串 concat
- No Comment
今天需要将某个表中的schoolname字段(char 255)所有值(例如有个“中山大学”)的前面加上一个字符串”广东省”,变成“广东省中山大学”。
大概有几千条记录,手工是不现实了,于是寻求mysql的字符串连接函数,还真找到一个——“CONCAT”
咱们先把手册里的说明和相关函数看看吧,举一反三嘛。
- CONCAT(str1,str2,…)
返回结果为连接参数产生的字符串。如有任何一个参数为NULL ,则返回值为 NULL。或许有一个或多个参数。如果所有参数均为非二进制字符串,则结果为非二进制字符串。如果自变量中含有任一二进制字符串,则结果为一个二进制字符串。一个数字参数被转化为与之相等的二进制字符串格式;若要避免这种情况,可使用显式类型 cast, 例如: SELECTCONCAT(CAST(int_col AS CHAR), char_col)
mysql> SELECT CONCAT(’My’, ‘S’, ‘QL’);
-> ‘MySQL’
mysql> SELECT CONCAT(’My’, NULL, ‘QL’);
-> NULL
mysql> SELECT CONCAT(14.3);
-> ‘14.3′
- CONCAT_WS(separator,str1,str2,…)
CONCAT_WS() 代表 CONCAT With Separator ,是CONCAT()的特殊形式。第一个参数是其它参数的分隔符。分隔符的位置放在要连接的两个字符串之间。分隔符可以是一个字符串,也可以是其它参数。如果分隔符为 NULL,则结果为NULL。函数会忽略任何分隔符参数后的 NULL 值。
mysql> SELECT CONCAT_WS(’,’,’First name’,’Second name’,’Last Name’);
-> ‘First name,Second name,Last Name’
mysql> SELECT CONCAT_WS(’,’,’First name’,NULL,’Last Name’);
-> ‘First name,Last Name’
CONCAT_WS()不会忽略任何空字符串。 (然而会忽略所有的 NULL)。
好了,我们的sql语句就是
UPDATE schooltable SET schoolname=CONCAT(‘广东省’,schoolname) WHERE schoolid>3233
mysql-服务无法启动-1067错误-进程意外终止解决方法
- 1 十二月 //
- Posted in 数据库 //
- Tags : mysql 服务 启动 1067
- No Comment
今天快崩溃了,本来运行得好的mysql突然就无法启动了,系统环境是windows2003+apache+mysql+php。
从下午四点一直到晚上11点,翻遍了网上的资料,全部都试过了,还是那万恶的“进程意外终止”。
我之前是使用的msi安装版,后来下载了noinstall免安装版,两者都出现同样的错误,通过修改端口,修改服务名,都不行。
终于在某个兄弟的blog里看到几句看似漫不经心的话,却解决了我的问题。
具体步骤如下:
1.使用noinstall版本的,解压zip到D:\mysql下,之所以不用安装版的,是因为实在对那个配置工具没信心了,excute步骤第三步永远也通不过,所以放弃。
2.复制my-large.ini为my.ini
3.找到[mysqld]一行,在下面添加两行
basedir=D:/mysql
datadir=D:/mysql/data
4.然后在[mysqld]这一节结束的地方添加
[WinMySQLadmin]
Server=D:/mysql/bin/mysqld.exe
5.保存my.ini,然后将它复制到系统文件夹下(winxp、2003为C:\windows;win2000为C:\winnt)
6.然后到D:\mysql\bin目录下运行mysqld.exe –install”命令,这样就会把服务安装起来(新版的mysql好像就是这个mysqld.exe,而不是网上很多资料说的 mysqld-nt.exe)
7.运行
net stop mysql
net start mysql
把mysql服务重启一下
8.一般可以正常启动了——兴奋啊!可以安心睡觉了!
9.还要给root用户设置初始密码:
在bin目录下运行mysql -uroot -p
因为初始密码为空,直接回车
use mysql;
grant all on *.* to root@’localhost’ identified by ‘123456′ with grant option;
commit;
好了,现在再次重启mysql服务,重新使用 mysql -uroot -p登陆,会提示你输入密码了
打完收工!


