MySQL使用rand随机查询记录效率测试

一直以为mysql随机查询几条数据,就用

SELECT * FROM `table` ORDER BY RAND() LIMIT 5
就可以了。
但是真正测试一下才发现这样效率非常低。一个15万余条的库,查询5条数据,居然要8秒以上

查看官方手册,也说rand()放在ORDER BY 子句中会被执行多次,自然效率及很低。

You cannot use a column with RAND() values in an ORDER BY clause, because ORDER BY would evaluate the column multiple times.
搜索Google,网上基本上都是查询max(id) * rand()来随机获取数据。

SELECT *
FROM `table` AS t1 JOIN (SELECT ROUND(RAND() * (SELECT MAX(id) FROM `table`)) AS id) AS t2
WHERE t1.id >= t2.id
ORDER BY t1.id ASC LIMIT 5;
但是这样会产生连续的5条记录。解决办法只能是每次查询一条,查询5次。即便如此也值得,因为15万条的表,查询只需要0.01秒不到。

上面的语句采用的是JOIN,mysql的论坛上有人使用

SELECT *
FROM `table`
WHERE id >= (SELECT FLOOR( MAX(id) * RAND()) FROM `table` )
ORDER BY id LIMIT 1;
我测试了一下,需要0.5秒,速度也不错,但是跟上面的语句还是有很大差距。总觉有什么地方不正常。

于是我把语句改写了一下。

SELECT * FROM `table`
WHERE id >= (SELECT floor(RAND() * (SELECT MAX(id) FROM `table`)))�
ORDER BY id LIMIT 1;
这下,效率又提高了,查询时间只有0.01秒

最后,再把语句完善一下,加上MIN(id)的判断。我在最开始测试的时候,就是因为没有加上MIN(id)的判断,结果有一半的时间总是查询到表中的前面几行。
完整查询语句是:

SELECT * FROM `table`
WHERE id >= (SELECT floor( RAND() * ((SELECT MAX(id) FROM `table`)-(SELECT MIN(id) FROM `table`)) + (SELECT MIN(id) FROM `table`)))�
ORDER BY id LIMIT 1;
SELECT *
FROM `table` AS t1 JOIN (SELECT ROUND(RAND() * ((SELECT MAX(id) FROM `table`)-(SELECT MIN(id) FROM `table`))+(SELECT MIN(id) FROM `table`)) AS id) AS t2
WHERE t1.id >= t2.id
ORDER BY t1.id LIMIT 1;
最后在php中对这两个语句进行分别查询10次,
前者花费时间 0.147433 秒
后者花费时间 0.015130 秒
看来采用JOIN的语法比直接在WHERE中使用函数效率还要高很多。

MySQL的联结(Join)语法

1.内联结、外联结、左联结、右联结的含义及区别:

在SQL标准中规划的(Join)联结大致分为下面四种:

1. 内联结:将两个表中存在联结关系的字段符合联结关系的那些记录形成记录集的联结。

2. 外联结:分为外左联结和外右联结。

左联结A、B表的意思就是将表A中的全部记录和表B中联结的字段与表A的联结字段符合联结条件的那些记录形成的记录集的联结,这里注意的是最后出来的记录集会包括表A的全部记录。

右联结A、B表的结果和左联结B、A的结果是一样的,也就是说:

Select A.name B.name From A Left Join B On A.id=B.id

和Select A.name B.name From B Right Join A on B.id=A.id执行后的结果是一样的。

3.全联结:将两个表中存在联结关系的字段的所有记录取出形成记录集的联结(这个不需要记忆,只要是查询中提到了的表的字段都会取出,无论是否符合联结条件,因此意义不大)。

4.无联结:不用解释了吧,就是没有使用联结功能呗,也有自联结的说法。

这里有个比较简便的记忆方法,内外联结的区别是内联结将去除所有不符合条件的记录,而外联结则保留其中部分。外左联结与外右联结的区别在于如果用A左联结B则A中所有记录都会保留在结果中,此时B中只有符合联结条件的记录,而右联结相反,这样也就不会混淆了。其实大家回忆高等教育出版社出版的《数据库系统概论》书中讲到关系代数那章(就是将笛卡儿积和投影那章)的内容,相信不难理解这些联结功能的内涵。

2. MySQL联结(Join)的语法

MySQL支持Select和某些Update和Delete情况下的Join语法,具体语法上的细节有:

table_references:

    table_reference [, table_reference] …

table_reference:

    table_factor

 | join_table

table_factor:

    tbl_name [[AS] alias]

        [{USE|IGNORE|FORCE} INDEX (key_list)]

 | ( table_references )

 | { OJ table_reference LEFT OUTER JOIN table_reference

        ON conditional_expr }

join_table:

    table_reference [INNER | CROSS] JOIN table_factor [join_condition]

 | table_reference STRAIGHT_JOIN table_factor

 | table_reference STRAIGHT_JOIN table_factor ON condition

 | table_reference LEFT [OUTER] JOIN table_reference join_condition

 | table_reference NATURAL [LEFT [OUTER]] JOIN table_factor

 | table_reference RIGHT [OUTER] JOIN table_reference join_condition

 | table_reference NATURAL [RIGHT [OUTER]] JOIN table_factor

join_condition:

    ON conditional_expr | USING (column_list)

上面的用法摘自权威资料,不过大家看了是否有点晕呢?呵呵,应该问题主要还在于table_reference是什么,table_factor又是什么?这里的table_reference其实就是表的引用的意思,因为在MySQL看来,联结就是一种对表的引用,因此把需要联结的表定义为table_reference,同时在SQL Standard中也是如此看待的。而table_factor则是MySQL对这个引用的功能上的增强和扩充,使得引用的表可以是括号内的一系列表,如下面例子中的JOIN后面括号:

SELECT * FROM t1 LEFT JOIN (t2, t3, t4) ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)

这个语句的执行结果和下面语句其实是一样的:

SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4)

                 ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)

这两个例子不仅让我们了解了MySQL中table_factor和table_reference含义,同时能理解一点CROSS JOIN的用法,我要补充的是在MySQL现有版本中CROSS JOIN的作用和INNER JOIN是一样的(虽然在SQL Standard中是不一样的,然而在MySQL中他们的区别仅仅是INNER JOIN需要附加ON参数的语句,而CROSS JOIN不需要)。

既然说到了ON语句,那就解释一下吧,ON语句其实和WHERE语句功能大致相当,只是这里的ON语句是专门针对联结表的,ON语句后面的条件的要求和书写方式和WHERE语句的要求是一样的,大家基本上可以把ON当作WHERE用。

大家也许也看到了OJ table_reference LEFT OUTER JOIN table_reference这个句子,这不是MySQL的标准写法,只是为了和ODBC的SQL语法兼容而设定的,我很少用,Java的人更是不会用,所以也不多解释了。

那下面就具体讲讲简单的JOIN的用法了。首先我们假设有2个表A和B,他们的表结构和字段分别为:

表A:

ID Name
1 Tim
2 Jimmy
3 John
4 Tom

表B:

ID Hobby
1 Football
2 Basketball
2 Tennis
4 Soccer

1. 内联结:

Select A.Name B.Hobby from A, B where A.id = B.id,这是隐式的内联结,查询的结果是:

Name Hobby
Tim Football
Jimmy Basketball
Jimmy Tennis
Tom Soccer

它的作用和 Select A.Name from A INNER JOIN B ON A.id = B.id是一样的。这里的INNER JOIN换成CROSS JOIN也是可以的。

2. 外左联结

Select A.Name from A Left JOIN B ON A.id = B.id,典型的外左联结,这样查询得到的结果将会是保留所有A表中联结字段的记录,若无与其相对应的B表中的字段记录则留空,结果如下:

Name Hobby
Tim Football
Jimmy Basketball,Tennis
John  
Tom Soccer

所以从上面结果看出,因为A表中的John记录的ID没有在B表中有对应ID,因此为空,但Name栏仍有John记录。

3. 外右联结

如果把上面查询改成外右联结:Select A.Name from A Right JOIN B ON A.id = B.id,则结果将会是:

Name Hobby
Tim Football
Jimmy Basketball
Jimmy Tennis
Tom Soccer

这样的结果都是我们可以从外左联结的结果中猜到的了。

说到这里大家是否对联结查询了解多了?这个原本看来高深的概念一下子就理解了,恍然大悟了吧(呵呵,开玩笑了)?最后给大家讲讲MySQL联结查询中的某些参数的作用:

1.USING (column_list):其作用是为了方便书写联结的多对应关系,大部分情况下USING语句可以用ON语句来代替,如下面例子:

a LEFT JOIN b USING (c1,c2,c3),其作用相当于下面语句

a LEFT JOIN b ON a.c1=b.c1 AND a.c2=b.c2 AND a.c3=b.c3

只是用ON来代替会书写比较麻烦而已。

2.NATURAL [LEFT] JOIN:这个句子的作用相当于INNER JOIN,或者是在USING子句中包含了联结的表中所有字段的Left JOIN(左联结)。

3.STRAIGHT_JOIN:由于默认情况下MySQL在进行表的联结的时候会先读入左表,当使用了这个参数后MySQL将会先读入右表,这是个MySQL的内置优化参数,大家应该在特定情况下使用,譬如已经确认右表中的记录数量少,在筛选后能大大提高查询速度。

最后要说的就是,在MySQL5.0以后,运算顺序得到了重视,所以对多表的联结查询可能会错误以子联结查询的方式进行。譬如你需要进行多表联结,因此你输入了下面的联结查询:

SELECT t1.id,t2.id,t3.id

    FROM t1,t2

    LEFT JOIN t3 ON (t3.id=t1.id)

    WHERE t1.id=t2.id;

但是MySQL并不是这样执行的,其后台的真正执行方式是下面的语句:

SELECT t1.id,t2.id,t3.id

    FROM t1,( t2 LEFT JOIN t3 ON (t3.id=t1.id) )

    WHERE t1.id=t2.id;

这并不是我们想要的效果,所以我们需要这样输入:

SELECT t1.id,t2.id,t3.id

    FROM (t1,t2)

    LEFT JOIN t3 ON (t3.id=t1.id)

    WHERE t1.id=t2.id;

在这里括号是相当重要的,因此以后在写这样的查询的时候我们不要忘记了多写几个括号,至少这样能避免很多错误(因为这样的错误是很难被开发人员发现的)。

做人做事是一门艺术,更是一门学问

一个人不管有多聪明,多能干,背景条件有多好,如果不懂得如何去做人、做事,那么他最终的结局肯定是失败。
做人做事是一门艺术,更是一门学问。很多人之所以一辈子都碌碌无为,那是因为他活了一辈子都没有弄明白该怎样去做人做事。
每一个人生活在现实社会中,都渴望着成功,而且很多有志之士为了心中的梦想,付出了很多,然而得到的却很少,这个问题不能不引起人们的深思:你不能说他们不够努力,不够勤劳,可为什么偏偏落得个一事无成的结局呢?这值得我们每一个人去认真思考。
从表面上看,做人做事似乎很简单,有谁不会呢?其实不然,比如说你当一名教师,你的主观愿望是当好教师,但事实上却不受学生欢迎;你去做生意,你的主 观愿望是赚大钱,可偏偏就赔了本。抛开这些表层现象,去发掘问题的症结,你就会发现做人做事的确是一门很难掌握的学问。
可以这么说,做人做事是一门涉及现实生活中各个方面的学问,单从任何一个方面入手研究,都不可能窥其全貌。要掌握这门学问,抓住其本质,就必须对现实 生活加以提炼总结,得出一些具有普遍意义的规律来,人们才能有章可循,而不至于迷然无绪。读懂一个字诀,受用你一生!

一、社会交往字诀——教你建功立业

(一)“谦”字诀

处世唯“谦”字了得,若一味狂妄自负、骄傲自大,只会失去处世的根本,落得个孤苦伶仃、千夫所指的骂名下场。

1、不可目中无人

2、得意不要忘形

3、有本事不必自夸

4、请教不择人

(二)“淡”字诀

为人处世,交朋待友,对势利纷华,似乎不必太过于苛求,当以“淡”字当头。看淡些,看开些,人生也就豁然开朗,有滋有味了。
正如“平平淡淡才是真”。

1、君子之交淡如水

2、淡看人生,善待生命

3、淡泊明志,莫为名利遮望眼

4、减少心欲,满足心灵

(三)“俭”字诀

不懂得“俭”字的人,不知道如何成功,任何成功的事业都在于点滴的积累;不懂得“俭”字的人,只会丧失成功,过分的骄奢多败人品质。
“俭以养德”,为人做事之良训。

1、从节省生活费开始

2、“穷大方”不可取

3、谨防变态的节俭:吝啬

4、欲路勿染,俭以养德

(四)“自”字诀

做一个有个性的人,给自己一点自信!成功的道路靠自己闯,美好的前途来自于自强自立,不屈服于任何权威,用自我的努力找到属于你的自尊。
男儿立世,自己拍板!

1、自强自立,与成功有约

2、独品人生百态

3、用自我来挑战权威

4、自信——任你东南西北风

(五)“礼”字诀

生在礼仪之邦,做一个彬彬有礼之人。有礼之人会做人,有人缘,多朋友。有礼之人会做事,注重形象,有教养,不树敌,成功路上事事顺。

1、以礼待人

2、彬彬有礼,礼多人不怪

3、注重礼仪着装,给人良好印象

(六)“正”字诀

做一个正直的人,做一个人格健全完善的人,受人崇敬。做一个自私的人,做欺心的事,疾贤防能,与成功无缘。

1、己所不欲,勿施于人

2、嫉妒乃方正之人之大忌

3、不做欺心事,本身是一种愉悦

二、形象塑造字诀——教你品格高雅

(七)“志”字诀

给自己一根足够长的杠杆,希望转动地球。
给自己的人生立个志愿,树个目标,树个偶像,脚踏实地,成功的意识需要培养,先立志,再与成功约会。

1、度德量力,以志立身

2、先立志,有志就有希望

3、培养成功意识:立志为王

4、树立偶像,改变自己

(八)“时”字诀

做人要惜时,做事要守时。塑造自己的形象,现代人离不开时间观念。合理安排自己的时间,有效利用自己的时间,守时、惜时、不拖延。

1、一秒值万金

2、别漠视业余时间

3、盗窃他人时间,等于谋财害命

4、按重要性办事,更能有效利用时间

(九)“勤”字诀

多一些努力,便多一些成功的机会。无数事实证明:成功的最短途径是勤奋。不要光耍嘴皮子,不要好逸恶劳,勤字当头,苍天不负有心人,天道酬勤!

1、成功的最短途径:勤奋

2、多一些努力,多一些机会

3、勤于行动,胜于勤说

(十)“实”字诀

踏踏实实做人,实实在在办事。任何一个双手插在口袋里的人,都爬不上成功的梯子。给人留下一个实在的形象,给自己的成功增添一份夯实的基础,从实际出发,对自己负责。

1、敬业,实干家的成功保障

2、把每一份工作都做好

3、双手插在口袋里的人,爬不上成功的梯子

(十一)“专”字诀

有专才有恒,有恒才有我。
你生活在一个知识大爆炸的时代,如果你是一个天才,不专心就成了你的不幸;如果你资质平凡,请不要悲观,只要你下定决心一辈子做好一件事,你就能成功。年轻人,千万别给人留下一个朝三暮四的形象。

1、把所有的鸡蛋放入一个篮子

2、多才多艺,莫如练就“独门暗器”

3、专一,让劣势变成优势

(十二)“慎”字诀

人生漫长,又短暂,关键的就几步。人性丛林,职场事业,利益多多、诱惑多多。老成不怕多,凡事应多三思,不怕一万,就怕万一。一旦伸错手,入错行,做错事,于名誉,于事业,于形象皆有不救之危。慎”之!

1、千万别入错行

2、想好了你再“跳”

3、不要草率行事

三、自我提升字诀——教你拯救命运

(十三)“硬”字诀

做人难,做事难,面对千难万阻,要提升自我,不来点“硬”的怎么行?如果事有勉强,应该敢于说“不”;如果是正当利益,则应当仁不让;甚至,有时还得来点霸王硬上弓,要有“脸皮厚”的时候,也要有“头皮硬”的时候。

1、拒绝是一门艺术

2、该我的,就不要客气

3、怒发冲冠之功

4、厚脸皮做人,硬头皮做事

(十四)“小”字诀

一家海鲜连锁餐厅的老板很可能当初是水产市场练滩儿的,而一家皮鞋连锁店的老板当初可能是擦鞋的。欲做大事,赚大钱,必先做小事,赚小钱,放下架子,舍得小利。从细微处入手,先扫一屋,再扫天下!

1、一屋不扫,何以扫天下

2、先做小事,赚小钱

3、一枚钉子改变一个人的一生

(十五)“锐”字诀

小小麻雀,飞飞跳跳、争分夺秒,不停地寻觅食物。人生亦如此,面对残酷竞争,惟有锐意进取,做一个好先锋,把下一个进球当目标,敢于冒险,敢于闯荡,守株待兔的事情毕竟很渺茫。

1、不以现有成就为满足

2、锐意追求,绝不退缩

3、锐气不可抛,成功是迟早

(十六)“创”字诀

提升自我,就要有胆有识去超越自我。何谓超越?超越就是吃螃蟹,就是创新。同时创新就意味着冒险,所谓富贵险中求。想人家想不到的,做别人不敢做的,敢为天下先,在于思维的转换。

1、敢为天下先

2、打破规则的创意

3、人弃我取也能创奇迹

4、逆向思维的攻守之道

(十七)“通”字诀

穷则思变,变则通。识时务者为俊杰,通机变者为英豪。通往成功的道路不是一条,又何必在一棵树上吊死呢?抓住成功的关键,东方不亮西方亮,不管它是黑猫白猫,重要的是它能否逮“耗子”。

1、巧妙地以变应变

2、条条大道通罗马

3、成功在于通,有通才有赢

(十八)“言”字诀

把赞扬送给别人,就像把食物施舍给饥饿的乞丐一样。古往今来,不知有多少人,凭着三寸不烂之舌,改变了自己平凡的命运。说话幽默,找共同语言……一个“言”字,一生受用。

1、投其所好找话题

2、恭维是最好的“润滑剂”

3、成功人生,幽默机智

4、“流行语”为你添姿着色

四、人际互动字诀——教你赢得朋友

(十九)“宽”字诀

人际互动,应着眼于未来,不念旧恶。原谅别人,是对待自己的最好方式——为你的仇敌而怒火中烧,烧伤的是你自己。做人做事,心胸不可太狭隘。海纳百川,靠一棵宽容的心!
1、宽恕你的敌人
2、宽容做人,宽容成事
3、乐于忘记,不念旧恶

(二十)“和”字诀

在人海中,如果我们不想孤立,那么就学会如何与人相处吧!林子大了,什么鸟都有,不要求你喜欢所有的人,但同时世上也没有什么最牛的人。
和为贵嘛,就要互相留台阶,大家给面子。
1、为他人着想,为自己铺路
2、你给别人留面子,别人给你做好事
3、夫妻之道,亦和亦智

(二十一)“信”字诀

有多少人信任你,你就拥有多少次成功的机会,“信”是什么东西?信是一种人格的力量,是超越金钱的友情,是了解、是欣赏、是覆水,具有不可逆转性。所以,言必行,行必果,能帮的忙则帮,但不可轻易许诺!
1、能帮则帮,不轻易许诺
2、言而有信,做人讲原则
3、做事先做人,做人先取信
4、信誉基石,生死友情

(二十二)“帮”字诀

“好风凭借力,送我上青天”。人际交往,互利互惠。帮助别人,就是在为自己的人情信用卡储蓄,特别是在人患难之际施于援手,救落难英雄于困顿。真心助人,其回报不言而喻。
1、助人发财,自己沾光
2、好风凭借力,借梯能登天
3、掌握时机,拉人一把

(二十三)“敬”字诀

人要面子树要皮。人存在于社会上,要扮演各种各样角色,特别是在互相的交往中,需要一定的尊严来支撑,这是人性的弱点。明白了这点,才能体会到“敬”字的必要性。
1、为尊者讳,为上司讳
2、在失意者面前不谈你的得意
3、尊敬对方的“闪光点”

(二十四)“交”字诀

人情冷暖、世态炎凉,平常朋友平常过。交朋接友,不可急功近利,友情投资,宜走长线,拜拜冷庙,烧烧冷灶,平时多烧香,哪怕是只言片语的问候,亦是交友之道。
1、闲时多烧香,急时有人帮
2、友情投资,宜走长线
3、拜冷庙,烧冷灶,交落难英雄

五、解困渡厄字诀——教你轻松快乐

(二十五)“坚”字诀

面对挫折与困难,铭记丘吉尔的名言:“永远,永远,永远不要放弃!”其实世界上并没有什么幸运的事,就是有,也是坚持的结果。为了最后的胜利,应以坚毅不拔之志,面对种种暂时之屈辱,执着追求,不到黄河心不死!
1、厚积薄发,耐得寂寞
2、谁笑到最后,谁笑得最甜
3、执着追求,永不放弃
4、不到黄河心不死

(二十六)“谋”字诀

做人有困惑,做事有困境,面对“山重水复”之关卡,光有坚强的毅志不行,硬闯也不行。解决难题靠的是脑袋,脑袋产生思考,让思考发威,在出人意料之处轻松解决问题。
1、巧妇能为无米之炊
2、从“山重水复”到“柳暗花明”
3、思考的威力

(二十七)“屈”字诀

要摆脱人与事的困境,就难免要求人,求人就难免要低三下四,但着眼于未来的成功,即使像蟑螂一样的生活也应在所不惜,风水毕竟轮流转。放下架子,该屈就屈,能屈能伸,以屈为伸方为英雄!
1、像蟑螂一样生活
2、放下身段,前方是大道
3、你敬我一尺,我敬你一丈
4、低人一级“屈”不死人

(二十八)“静”字诀

“不在沉默中爆发,就在沉默中灭亡!”凡遇大事需静气,平心静气是一种境界,一种气度,一种修养。冷静之中的决定往往是摆脱困境的最佳方案,同时冷静也是一种智慧,以静待变,乱中取胜!
1、把冷板凳坐成经理椅
2、心宁智生,智生事成
3、沉着冷静心自怡
4、沉得住气方为人杰

(二十九)“乐”字诀

世上没有绝对幸福的人,只有不肯快乐的心。人生苦短,与其事事张弓拔弩,不如“幽它一默”。记住,成功是从微笑开始的,人生不如意事常八九,乐观点,自己营造快乐,学会轻松解决难题。
1、成功从微笑开始
2、学会营造快乐
3、学会轻松愉快地解决难题
4、世上没有绝对幸福的人,只有不肯快乐的心

(三十)“靠”字诀

人生不等不靠,没错,天上不会掉馅饼,守株待兔饿死人,但一点不靠也不行,亲戚朋友、同学、老乡,这是一种“人力资源”,谁人没个三灾六难,能靠则靠,靠不上创造条件也要靠!
1、让朋友成为你的靠山
2、出门落难靠老乡
3、亲戚亲戚,越走越亲
4、恰同学少年,该靠靠一把

六、不败人生字诀——教你人生辉煌

(三十一)“愚”字诀

学学猫头鹰,睁一只眼,闭一只眼。你说我糊涂,其实我不傻!只是世事多变幻,创业难,败家快,人说水至清则无鱼,人至察则无徒。其实是,明哲保身,大智者往往大愚,聪明者多,能过“愚”字关鲜矣!
1、糊涂人聪明一世
2、不要以为自己比别人聪明
3、处事不要太认真
4、谁是英雄?

(三十二)“忍”字诀

真的英雄,何必气短,善始善终,方为不败!忍能保身,忍能成事,忍是大智,大勇,更是大福!忍是厚,忍是黑,忍小人,忍豪强,忍天下难忍之事,不做性情中人,成常人难成之事。
1、忍是大智大勇大福
2、不做性情中人
3、不败人生,忍者无敌

(三十三)“退”字诀

久历江湖,练达人情之人都守一个“退”字。退是一种谋略,退是一种交换,更是一种维系生存的手段。哲人说的好,“不要把痰吐在井里,哪天你口渴的时侯,也要来井边喝水的。”
1、用心计较般般错,退步思量事事顺
2、拒绝妥协,就是拒绝成功
3、惹不起,躲得起

(三十四)“圆”字诀

方圆做人,八面玲珑;圆满做事,事事顺心。人心叵测,凡事最好留一手,有闲时,可研究一下“模糊哲学”,人生这套马车,如若安上方方正正的轮子,你没听说过,我也没听说过,寸步难行嘛!
1、方圆做人,圆满做事
2、做老二,不要做老大
3、人情练达即文章,处世圆通慎言语

(三十五)“危”字诀

“豪华尽出成功后,逸乐安知与祸双?”历史教训如此,平头百姓亦如此。居家过日,工作职场等都逃不过一个“危”字,人无远虑,必有近忧。
1、远虑在先,近处无危
2、郭子仪屏退侍女免祸患
3、上山下乡当农民——范蠡富贵终身

(三十六)“装”字诀

人生在世一台戏,你方唱罢我上场,不管你会不会演,就看你会不会装。充英雄容易,扮弱者难。俗话说得好,枪打出头鸟,不怕贼偷就怕贼惦记着,当你还不具备实力时,请把你过剩的才华藏起来!
1、故意示弱有好处
2、用“拟态”和“保护色”
3、成功需要诈死与佯败

[转]PHP MVC及模板引擎

  模板引擎,这四个字听起来很高深的样子,一般用到“引擎”两字都会感觉比较高级,类似游戏3D引擎、Zend引擎等,其实都是唬人的,骗外行人的。所以在我初学PHP的那会,也因为这四个字导致了我觉得很难而没有去看他到底是什么样一个东西,直到很长时间以后使用Smarty才真正了解模板引擎的原理和作用。Smarty(http://smarty.php.net),PHP官方模板引擎,看名字给人感觉应该很快,其实很慢,即使他有预编译(另一个看起来很高级的名词,同样也是唬人的,下面我会讲到这个)。[注:我刚才点开Smarty发现他说他已经不是一个PHP子项目了,汗,看来确实唬人,哈玩笑^_^]。其实在PHP里,模板引擎扮演着View(其实通俗说就是页面,看英文有时候会给人很高级的错觉)的角色,这是一个很重要的角色,因为用户的交互啊,界面效果啊等等都在这里,这是最终用户看到的你的系统的样子。

  开头就说模板引擎,只是跟大家说明一下这个东西其实没有什么难理解的,明白其原理以后你会发现他是纸老虎,所以你要有信心你会很轻松看完此文。

  为了更好的说明模板引擎所扮演的角色,我不得不也谈谈MVC。这个话题恐怕互联网上谈及的很多,我也只能根据我的理解来描述,可能有不恰当的地方,欢迎讨论。通常的MVC是指Model、View和Controller。也就是模型、视图和控制器。我理解MVC也是在学了PHP不短时间后了,当时请教老廖(http://qeephp.com),才恍然大悟。

  先来说说Controller,也就是控制器,控制器是个什么东西呢?在PHP里他是扮演一个接收用户请求,把用户请求定位到指定数据模型的角色。解释起来感觉不是很好解释,来看一个简单的留言本的例子:

//用户请求可能是 <a href="http://www.example.com/guest.php?module=list">http://www.example.com/guest.php?module=list</a>
$module = $_GET['module']; 

switch ($module) {
    case 'list':
        require_once 'list.php';
        break;
    case 'add':
        require_once 'add.php';
        break;
    case 'del':
        require_once 'del.php';
        break;
    default:
        require_once 'list.php';
        break;
}

  是不是看起来很简单好像没什么东西呀,只是根据用户的请求参数包含不同的文件而已。没错,确实很容易,这个switch语句其实就一个最简单的控制器的实现。他控制什么?他控制你根据不同的用户请求参数调用不同的数据模型处理用户请求。那么这里的list可能是一个留言列表,add是添加留言,del是删除留言。Controller的传统实现可以这么简单,当然现在的很多技巧包括根据不同的用户请求包含不同的业务逻辑处理类,比如list自动定位到/model/List.class.php这样的一些技巧性操作等。

  再来说说Model,其实我们一般花比较长时间设计和编写的也是这块内容,也就是具体的业务逻辑实现。比如一个留言列表要处理些什么,都是在这里实现。还是直接看一个Model例子比较直观:

//Guest_List.class.php
class Guest_List {
    public $page = 1;
    public function __construct() {
        $this->db = DB::init($GLOBALS['dsn']);
        $this->page = (int) $_GET['page'];
    } 

    public function getList() {
        $begin = $this->page * 10;
        $sql = "SELECT * FROM guest ORDER BY addTime DESC LIMIT $begin, 10";
        return $this->db->getAll($sql);
    }
}

  这里的Guest_List就是一个简单的Model实现,构造函数取得页数page参数,getList方法查询留言列表并返回结果集。那么在list.php里可能是这样调用的:

//list.php
require_once 'Guest_List.class.php';
$model = new Guest_List();
$lists = $model->getList();

  嗯,其实很多MVC框架都是这么实现的,只不过可能加了一些自动调用的机制,会根据用户请求自动调用类,自动执行方法,呵呵。Model大功告成。这里需要明确一点就是,Model只是返回视图上所可能需要用到的数据,他不负责任何和显示有关的事情,那么显示相关的就交给View来做了。我们是不是不知不觉已经把表现和业务逻辑分离了?没错,分离就是这么简单。

  好了,来看看View怎么利用Model返回的数据来显示页面吧。最简单的例子,我们只需要在list.php里增加一行即可。

//list.php
require_once 'Guest_List.class.php';
$model = new Guest_List();
$lists = $model->getList();
//上面是Model,那么下面就是View
require_once 'list.html';

  来看看View都做些什么吧,我们用list.html来表示留言列表所展现给用户的界面文件,用html来命名看起来会更直观一些,他好像是个html文件,负责输出html代码给浏览器。来看看list.html可能长什么样子:

<!--list.html--> 

<table>

<?php foreach ($lists as $value) { ?>

<tr>

<td><?php echo htmlspecialchars($value['guest_user_name']);?></td>

<td><?php echo date('Y-m-d H:i', $value['guest_date_time']);?></td>

<td><?php echo htmlspecialchars($value['guest_content']);?></td>

</tr>

<?php } ?>

</table>

  不难看出来这个文件所做的只不过是遍历留言数组$lists,然后输出每一行的留言,对留言的内容处理做了htmlspecialchars和date转换(与显示相关的处理),除了和显示相关的操作,他没有再做任何业务逻辑了(也不应该有)。

  我发现写到这里真的没有什么好写的了,MVC就是这些(或者再做一些扩展),至于怎么做到表现和业务分离,那么就是在你的Model里只返回数据,也就是你View所需要用到的数据,而你的View拿到这些数据后负责去显示他就可以了,不应该在你的Model里做显示和视觉相关的操作,也不应该在你的View里做一些业务逻辑相关的操作,把这两者分清楚,就自然而然的表现与业务分离了。

  接下来说说负责View的模板引擎吧,其实你在上面应该已经看到了一个最简陋的模板引擎,那就是View部分的 require_once 语句。厄,实在是太简单了,模板引擎其实是调度并解析模板的东西,其中调度模板由 require_once 搞定了,那么解析呢?这里由 PHP 引擎本身来搞定了。哈,没错,我一直都认为 PHP 是个最好的模板引擎。

  不过还是不得不说说传统的模板引擎的实现原理,一般来说会有这么几个步骤:
  1、注册变量,也就是把从Model返回的数据注册到模板引擎中,告诉模板引擎这个变量可以使用,其实所谓的注册也只不过是不得不这么做,因为一般引擎内部函数是没办法直接访问Model返回的变量的(变量作用域的问题),所以不得不加一个注册操作,把这些变量转换从模板引擎类的属性等。
  2、模板解析,就是读取模板文件,按照模板语法将标签解析成 PHP 语法,或者执行一些替换操作,用变量内容替换掉模板标签,其实效果都差不多。
  3、如果不是将变量内容替换掉模板标签,那么基本上第三步就是将注册的变量和解析完的模板融合在一起输出,类似于上面的list.html,是个解析完的文件,然后输出。

  一般模板引擎还会提供不少用于显示内容处理的插件,比如日期转换、字符串处理、生成表格、生成select等,这些给页面制作提供了一些方便。Smarty还包含了一些页面缓存机制,也很不错。

  很多模板引擎都顶着语法简单的嚎头,美其名曰降低美工的学习门槛。其实我不得不问,有多少模板是由美工来做的呢?而且对比两种语法,不觉得 PHP 的简单循环和输出有什么难以理解的,对比下面两种语法:

<!-- <?php foreach ($lists as $value) { ?> -->
<?=value['userName']?>
<!-- <?php } ?> -->

  和

<!-- loop lists value -->
{value['userName']}
<!-- loop -->

  我左看右看都觉得他们差不多,呵呵,与其再学习一套语法,还不如直接用你已经非常熟悉的PHP呢,为什么要虐待自己呢?而且从可维护性的角度来讲,维护PHP语法和维护模板语法,哪种更容易呢?PHP是标准,只要会PHP都知道他怎么写,表示什么,但是模板引擎千奇百怪的,各种语法都有,不是一个统一的标准,我想谁维护一个从来没有用过的模板,都需要花不少时间去学习引擎语法。更何况即使模板可以那样写,最终还是需要一堆正则替换成PHP语法。我敢肯定,前面写的哪种模板引擎语法最终会被转换成它上面那种PHP。其实模板引擎的解析也就是将模板语法转换成PHP语法的过程。抛开效率来说,多此一举。就象《C专家编程》作者说的,即使你能用宏把C写成看起来好像另外一种语言,但是你不要这么做,同样的这句告诫是否适合于模板引擎呢,它看起来很像另外一种语言。当然我这篇文章不是来批判模板引擎的,哈。它既然存在,也有其存在的道理,某些场合还是不得不用的,比如如果你把模板提供给用户去制作和使用,那么你不得不采用标签以限制用户使用PHP语法,来增强系统安全性。

  再来说效率问题,由于模板引擎要解析模板语法,会用到很多正则匹配和替换,那么在实际运行中是比较消耗系统资源的,而且当模板标签非常复杂或者嵌套多层的时候,效率是比较低的,因为有了一种处理方法,就是预编译。所谓的预编译,就是把带有模板语法的模板,通过处理,转换成 PHP 语法的文件,只要模板文件没有被修改,那么直接包含编译后的文件即可,这样就不需要再次替换和匹配,可以大大提高效率,不过由于模板引擎的复杂性,导致编译后的结果文件仍然比我们一般写出来的PHP文件复杂得多。所以其实效率还是远低于直接编写PHP模板的。有兴趣的可以打开一个Smarty编译过的文件,看看其嵌套,其实要比直接循环来得复杂。

  本文写到这里也差不多了,具体模板引擎如何编译如何处理,各个模板引擎的方式都不一样,有兴趣的可以去下载几个比较经典的引擎看看,比如Smarty。随后我附上我自己用的PHP模板引擎。

  PS:其实我觉得MVC应该叫做CMV是不是更符合逻辑呢?没有考证过这个词的由来^_^。

我的真正PHP模板引擎:

<?php
/**
 * 模板引擎
 *
 * Copyright(c) 2005-2008 by 陈毅鑫(深空). All rights reserved
 *
 * To contact the author write to {@link mailto:shenkong@php.net}
 *
 * @author 陈毅鑫(深空)
 * @version $Id: Template.class.php 1687 2008-07-07 01:16:07Z skchen $
 * @package Template
 */
defined('FW') || exit(header('HTTP/1.0 400 Bad Request'));

class Template {
    protected static $obj;

    public $vars;
    public $includeFiles;
    public $includeFile;
    public $templates;
    public $template;
    public $contents;
    protected $_content;
    protected $_contents;
    protected $_path;

    protected function __construct() {
        $this->vars = array();
        require_once ROOT_PATH . "lib/template.func.php";
    }

    /**
     * 初始化模板引擎
     *
     * @return object 模板引擎对象
     */
    public static function &init() {
        if (is_null(self::$obj)) {
            self::$obj = new Template();
        }
        return self::$obj;
    }

    /**
     * 注册模板变量
     *
     * 注册模板变量后在模板里就可以直接使用该变量,注册与被注册变量名不一定要一样
     * 如:$template->assign('var', $value);
     * 意思是将当前变量$value注册成模板变量var,在模板里就可以直接调用$val
     *
     * @param string $var 注册到模板里的变量名的字符串形式,不包含$
     * @param mixed $value 需要注册的变量
     */
    public function assign($var, $value) {
        if (is_array($var)) {
            foreach ($var as $key => $val) {
                $this->vars[$key] = $val;
            }
        } else {
            $this->vars[$var] = $value;
        }
    }

    /**
     * 解析模板文件
     *
     * 解析模板,并将变量植入模板,解析完后返回字符串结果
     *
     * @param unknown_type $templates
     * @return unknown
     */
    public function fetch($templates) {
        if (is_array($templates)) {
            $this->templates = $templates;
        } else {
            $this->templates = func_get_args();
        }
        extract($this->vars);

        $this->_contents = '';
        foreach ($this->templates as $this->template) {
            ob_end_clean();
            ob_start();
            $this->_path = $this->getPath($this->template);
            require $this->_path;
            $this->_content = ob_get_contents();
            ob_end_clean();
            ob_start();
            $this->_contents .= $this->_content;
            $this->contents[$this->template] = $this->_content;
        }
        return $this->_contents;
    }

    public function getPath($path) {
        $path = explode(".", $path);
        $num = count($path);
        if ($num == 1) {
            return ROOT_PATH . "template" . DIRECTORY_SEPARATOR . $path[0] . ".html";
        } elseif ($num > 1) {
            $templatePath = '';
            $templatePath = $path[$num - 1];
            array_pop($path);
            $templatePath = ROOT_PATH . implode(DIRECTORY_SEPARATOR, $path) . DIRECTORY_SEPARATOR . 'template' . DIRECTORY_SEPARATOR . $templatePath . ".html";
            return $templatePath;
        } else {
            return false;
        }
    }

    public function display($templates = array()) {
        if (!is_array($templates)) {
            $templates = func_get_args();
        }
        if (empty($templates)) {
            foreach ($this->templates as $this->template) {
                echo $this->contents[$this->template];
            }
        } else {
            echo $this->fetch($templates);
        }
    }
}

//end of script
<?php
/**
 * 模板扩充函数
 *
 * Copyright(c) 2005 by 陈毅鑫(深空). All rights reserved
 *
 * To contact the author write to {@link mailto:shenkong@php.net}
 *
 * @author 陈毅鑫(深空)
 * @version $Id: template.func.php 1687 2008-07-07 01:16:07Z skchen $
 * @package Template
 */

defined('FW') || exit(header('HTTP/1.0 400 Bad Request'));

/**
 * 包含模板
 *
 * 当你需要在主模板文件里(有些模板引擎称之为layout布局模板,其实不是所有模板都是布局)
 * 再包含其他公共模板的时候,使用该函数进行包含,则所有已注册的变量均可在被包含文件里使
 * 用,貌似支持多层嵌套,没有测试过,参数可以使用数组,也可以使用多个参数,如:
 * <?=includeFile('user.header', 'user.main', 'user.footer')?> 或者
 * <?=includeFile(array('user.header', 'user.main', 'user.footer'))?>
 *
 * @param string|array $filename 模板名(module.templateName形式)
 */
function includeFile($templates) {
    $template = Template::init();
    if (is_array($templates)) {
        $template->includeFiles = $templates;
    } else {
        $template->includeFiles = func_get_args();
    }
    extract($template->vars);
    foreach ($template->includeFiles as $template->includeFile) {
        require $template->getPath($template->includeFile);
    }
}

//end of script

限制文本框只能输入数字,小数点,英文字母,汉字

1.文本框只能输入数字代码(小数点也不能输入):

<input onkeyup=”this.value=this.value.replace(/\D/g,”)” onafterpaste=”this.value=this.value.replace(/\D/g,”)”>

2.只能输入数字,能输小数点. (方法1)

<input onkeyup=”if(isNaN(value))execCommand(‘undo’)” onafterpaste=”if(isNaN(value))execCommand(‘undo’)”>

<input name=txt1 onchange=”if(/\D/.test(this.value)){alert(‘只能输入数字’);this.value=”;}”>

3.数字和小数点方法二

<input type=text t_value=”” o_value=”” onkeypress=”if(!this.value.match(/^[\+\-]?\d*?\.?\d*?$/))this.value=this.t_value;else this.t_value=this.value;if(this.value.match(/^(?:[\+\-]?\d+(?:\.\d+)?)?$/))this.o_value=this.value” onkeyup=”if(!this.value.match(/^[\+\-]?\d*?\.?\d*?$/))this.value=this.t_value;else this.t_value=this.value;if(this.value.match(/^(?:[\+\-]?\d+(?:\.\d+)?)?$/))this.o_value=this.value” onblur=”if(!this.value.match(/^(?:[\+\-]?\d+(?:\.\d+)?|\.\d*?)?$/))this.value=this.o_value;else{if(this.value.match(/^\.\d+$/))this.value=0+this.value;if(this.value.match(/^\.$/))this.value=0;this.o_value=this.value}”>

4.只能输入字母和汉字

<input onkeyup=”value=value.replace(/[\d]/g,”) “onbeforepaste=”clipboardData.setData(‘text’,clipboardData.getData(‘text’).replace(/[\d]/g,”))” maxlength=10 name=”Numbers”>

5.只能输入英文字母和数字,不能输入中文

<input onkeyup=”value=value.replace(/[^\w\.\/]/ig,”)”>

6.只能输入数字和英文

<input onKeyUp=”value=value.replace(/[^\d|chun]/g,”)”>

7.小数点后只能有最多两位(数字,中文都可输入),不能输入字母和运算符号:

<input onKeyPress=”if((event.keyCode<48 || event.keyCode>57) && event.keyCode!=46 || /\.\d\d$/.test(value))event.returnValue=false”>

8.小数点后只能有最多两位(数字,字母,中文都可输入),可以输入运算符号:

<input onkeyup=”this.value=this.value.replace(/^(\-)*(\d+)\.(\d\d).*$/,’$1$2.$3′)”>

调用onkeypress事件实现 限制文本框只能输入数字及小数点(并且只能输入1次)

function KeyPress(objTR)
{
var txtval = objTR.value;
var key = event.keyCode;
if((key <48 || key >57)&&key !=46)
{
event.keyCode = 0;
}
else
{
if(key == 46)
{
if(txtval.indexOf(“.”) != -1 || txtval.length == 0)
event.keyCode = 0;
}
}
}

电脑辐射/每天用电脑4-6小时的人必看

    随着科技的发展,各种各样的电子产品进入我们的生活,我们惊奇地发现“辐射”一词离我们越来越近。那辐射是什么呢?它对我们又有什么伤害和影响呢?笔记本电脑对我们的辐射又有多大呢?下面我就给大家详细的介绍一下。

辐射是什么

    其实,辐射只不过是一个单纯的物理概念,自然界中的一切物体,只要温度在绝对温度零度以上,都以电磁波的形式时刻不停地向外传送热量,这种传送能量的方式称为辐射。物体通过辐射所放出的能量,称为辐射能,简称辐射。这样说来,我们自己也是一个辐射源,想想看,我们所处的环境里充满着各种各种的电磁波:手机信号、电视信号、电台广播信号等等,几乎到处都是辐射了,岂不是“草木皆兵”了!

    其实大家不用害怕,我们的生活中的确是到处都是辐射,但辐射大致可以分为非电离辐射及电离辐射两类。一般来说,非电离辐射(例如光线及无线电波)的能量较低,不足以改变物质的化学性质。相反,电离辐射(例如α粒子及β粒子)有足够的能量使原子中的电子游离而生成带电离子。这个电离过程通常会导致生物组织发生化学变化,因而对生物构成伤害。一般所指可引起伤害的辐射,就是电离辐射。而我们在日常生活中,接触到的一般都是非电离辐射,一般的辐射对我们的影响是微不足道的。

辐射对我们的危害

    人体对辐射都有一定的承受度,只有超过了这个可承受度的辐射才会对人体构成伤害,但随着计算机等电子产品的逐渐增多,我们周围的低辐射源也越来越多,这些辐射加在一起,就比较可怕了,如果接受了不当或不必要的辐射剂量,就有可能产生辐射的生物效应,而造成躯体或基因细胞上的伤害。普通电脑的辐射量一般为:键盘1000V/m、鼠标450V/m、屏幕218V/m、主机170V/m,而笔记本电脑的辐射量竟然达到了2500V/m。而在一般情况下,人体抗辐射强度为1000V/m。笔记本电脑无疑是人们最大的辐射杀手。鉴于电脑的电磁辐射的危害性,相关的国际、国内专业机构和电脑制造商,很早就开始了防护电脑辐射的工作。经过多年的努力,就电脑等电子产品的生产制造,制定出了MPR、TCO、FCC、UL等多种严格的认证标准,以确保人类健康不受损害。

    如果环境中的辐射量超出人体可以承受的范围,那么这些辐射就会危害到我们身体,电磁辐射危害人体的机理主要是热效应、非热效应和累积效应:

    1 热效应:人体70%以上是水,水分子受到电磁波辐射后相互摩擦,引起机体升温,从而影响到体内器官的正常工作。 

    2 非热效应:人体的器官和组织都存在微弱的电磁场,它们是稳定和有序的,一旦受到外界电磁场的干扰,处于平衡状态的微弱电磁场即将遭到破坏,人体也会遭受损伤。 

    3 累积效应:热效应和非热效应作用于人体后,对人体的伤害尚未来得及自我修复之前(通常所说的人体承受力——内抗力),再次受到电磁波辐射的话,其伤害程度就会发生累积,久之会成为永久性病态,危及生命。

使用笔记本时应注意防辐射

    1 在电脑旁放上几盆仙人掌,它可以有效地吸收辐射。

    2 使用笔记本电脑时,应避免放在膝盖上操作,如果长时间操作最好使用外接键盘。

    3 科学研究证实,电脑的荧屏能产生一种叫溴化二苯并呋喃的致癌物质,上网时尤其要注意通风。

    4 我们使用电脑时,要调整好屏幕的亮度,一般来说,屏幕亮度越大,电磁辐射越强。

    5 在操作电脑后,脸上会吸附不少电磁辐射的颗粒,要及时用清水洗脸,对于生活紧张而忙碌的人群来说,抵御电脑辐射最简单的办法就是在每天上午喝2至3杯的绿茶,吃一个橘子。绿茶不但能消除电脑辐射的危害,还能保护和提高视力。如果不习惯喝绿茶,菊花茶同样也能起着抵抗电脑辐射和调节身体功能的作用。

SQL查询语句精华使用简要

一、 简单查询
简单的Transact-SQL查询只包括选择列表、FROM子句和WHERE子句。它们分别说明所查询列、查询的表或视图、以及搜索条件等。
例如,下面的语句查询testtable表中姓名为“张三”的nickname字段和email字段。
SELECT nickname,email FROM testtable WHERE name=’张三’

(一) 选择列表
选择列表(select_list)指出所查询列,它可以是一组列名列表、星号、表达式、变量(包括局部变量和全局变量)等构成。
1、选择所有列
例如,下面语句显示testtable表中所有列的数据:
SELECT * FROM testtable
2、选择部分列并指定它们的显示次序
查询结果集合中数据的排列顺序与选择列表中所指定的列名排列顺序相同。
例如:
SELECT nickname,email FROM testtable
3、更改列标题
在选择列表中,可重新指定列标题。定义格式为:
列标题=列名
列名 列标题
如果指定的列标题不是标准的标识符格式时,应使用引号定界符,例如,下列语句使用汉字显示列标题:
SELECT 昵称=nickname,电子邮件=email FROM testtable
4、删除重复行
SELECT语句中使用ALL或DISTINCT选项来显示表中符合条件的所有行或删除其中重复的数据行,默认为ALL。使用DISTINCT选项时,对于所有重复的数据行在SELECT返回的结果集合中只保留一行。
5、限制返回的行数
使用TOP n [PERCENT]选项限制返回的数据行数,TOP n说明返回n行,而TOP n PERCENT时,说明n是表示一百分数,指定返回的行数等于总行数的百分之几。
例如:
SELECT TOP 2 * FROM testtable
SELECT TOP 20 PERCENT * FROM testtable

(二)FROM子句
FROM子句指定SELECT语句查询及与查询相关的表或视图。在FROM子句中最多可指定256个表或视图,它们之间用逗号分隔。在FROM子句同时指定多个表或视图时,如果选择列表中存在同名列,这时应使用对象名限定这些列所属的表或视图。例如在usertable和citytable表中同时存在 cityid列,在查询两个表中的cityid时应使用下面语句格式加以限定:
SELECT username,citytable.cityid FROM usertable,citytable

WHERE usertable.cityid=citytable.cityid
在FROM子句中可用以下两种格式为表或视图指定别名:
表名 as 别名

表名 别名
例如上面语句可用表的别名格式表示为:
SELECT username,b.cityid FROM usertable a,citytable b

WHERE a.cityid=b.cityid
SELECT不仅能从表或视图中检索数据,它还能够从其它查询语句所返回的结果集合中查询数据。例如:
SELECT a.au_fname+a.au_lname FROM authors a,titleauthor ta

(SELECT title_id,title
FROM titles WHERE ytd_sales>10000 ) AS t WHERE a.au_id=ta.au_id

AND ta.title_id=t.title_id
此例中,将SELECT返回的结果集合给予一别名t,然后再从中检索数据。

(三) 使用WHERE子句设置查询条件
WHERE子句设置查询条件,过滤掉不需要的数据行。例如下面语句查询年龄大于20的数据:
SELECT * FROM usertable WHERE age>20
WHERE子句可包括各种条件运算符:
比较运算符(大小比较):>、>=、=、<、<=、<>、!>、!<
范围运算符(表达式值是否在指定的范围):BETWEEN…AND…
NOT BETWEEN…AND…
列表运算符(判断表达式是否为列表中的指定项):IN (项1,项2……)
NOT IN (项1,项2……)
模式匹配符(判断值是否与指定的字符通配格式相符):LIKE、NOT LIKE
空值判断符(判断表达式是否为空):IS NULL、NOT IS NULL
逻辑运算符(用于多条件的逻辑连接):NOT、AND、OR
1、范围运算符例:age BETWEEN 10 AND 30相当于age>=10 AND age<=30
2、列表运算符例:country IN (‘Germany’,’China’)
3、模式匹配符例:常用于模糊查找,它判断列值是否与指定的字符串格式相匹配。可用于char、varchar、text、ntext、datetime和smalldatetime等类型查询。
可使用以下通配字符:
百分号%:可匹配任意类型和长度的字符,如果是中文,请使用两个百分号即%%。
下划线_:匹配单个任意字符,它常用来限制表达式的字符长度。
方括号[]:指定一个字符、字符串或范围,要求所匹配对象为它们中的任一个。

 

[^]:其取值也[] 相同,但它要求所匹配对象为指定字符以外的任一个字符。
例如:
限制以Publishing结尾,使用LIKE ‘%Publishing’
限制以A开头:LIKE ‘[A]%’
限制以A开头外:LIKE ‘[^A]%’
4、空值判断符例WHERE age IS NULL
5、逻辑运算符:优先级为NOT、AND、OR

(四)查询结果排序
使用ORDER BY子句对查询返回的结果按一列或多列排序。ORDER BY子句的语法格式为:
ORDER BY {column_name [ASC|DESC]} [,…n]
其中ASC表示升序,为默认值,DESC为降序。ORDER BY不能按ntext、text和image数据类型进行排序。例如:
SELECT * FROM usertable ORDER BY age desc,userid ASC
另外,可以根据表达式进行排序。

二、 联合查询
UNION运算符可以将两个或两个以上上SELECT语句的查询结果集合合并成一个结果集合显示,即执行联合查询。UNION的语法格式为:
select_statement UNION [ALL] selectstatement UNION [ALL]

selectstatement][…n]
其中selectstatement为待联合的SELECT查询语句。ALL选项表示将所有行合并到结果集合中。不指定该项时,被联合查询结果集合中的重复行将只保留一行。联合查询时,查询结果的列标题为第一个查询语句的列标题。因此,要定义列标题必须在第一个查询语句中定义。要对联合查询结果排序时,也必须使用第一查询语句中的列名、列标题或者列序号。在使用UNION 运算符时,应保证每个联合查询语句的选择列表中有相同数量的表达式,并且每个查询选择表达式应具有相同的数据类型,或是可以自动将它们转换为相同的数据类型。在自动转换时,对于数值类型,系统将低精度的数据类型转换为高精度的数据类型。在包括多个查询的UNION语句中,其执行顺序是自左至右,使用括号可以改变这一执行顺序。例如:
查询1 UNION (查询2 UNION 查询3)

三、连接查询
通过连接运算符可以实现多个表查询。连接是关系数据库模型的主要特点,也是它区别于其它类型数据库管理系统的一个标志。在关系数据库管理系统中,表建立时各数据之间的关系不必确定,常把一个实体的所有信息存放在一个表中。当检索数据时,通过连接操作查询出存放在多个表中的不同实体的信息。连接操作给用户带来很大的灵活性,他们可以在任何时候增加新的数据类型。为不同实体创建新的表,尔后通过连接进行查询。

连接可以在SELECT 语句的FROM子句或WHERE子句中建立,似是而非在FROM子句中指出连接时有助于将连接操作与WHERE子句中的搜索条件区分开来。所以,在 Transact-SQL中推荐使用这种方法。SQL-92标准所定义的FROM子句的连接语法格式为:
FROM join_table join_type join_table [ON (join_condition)]
其中join_table指出参与连接操作的表名,连接可以对同一个表操作,也可以对多表操作,对同一个表操作的连接又称做自连接。
join_type 指出连接类型,可分为三种:内连接、外连接和交叉连接。内连接(INNER JOIN)使用比较运算符进行表间某(些)列数据的比较操作,并列出这些表中与连接条件相匹配的数据行。根据所使用的比较方式不同,内连接又分为等值连接、自然连接和不等连接三种。
外连接分为左外连接(LEFT OUTER JOIN或LEFT JOIN)、右外连接(RIGHT OUTER JOIN或RIGHT JOIN)和全外连接(FULL OUTER JOIN或FULL JOIN)三种。与内连接不同的是,外连接不只列出与连接条件相匹配的行,而是列出左表(左外连接时)、右表(右外连接时)或两个表(全外连接时)中所有符合搜索条件的数据行。
交叉连接(CROSS JOIN)没有WHERE 子句,它返回连接表中所有数据行的笛卡尔积,其结果集合中的数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。
连接操作中的ON (join_condition) 子句指出连接条件,它由被连接表中的列和比较运算符、逻辑运算符等构成。
无论哪种连接都不能对text、ntext和image数据类型列进行直接连接,但可以对这三种列进行间接连接。例如:

 SELECT p1.pub_id,p2.pub_id,p1.pr_info
FROM pub_info AS p1 INNER JOIN pub_info AS p2
ON DATALENGTH(p1.pr_info)=DATALENGTH(p2.pr_info)

(一)内连接
内连接查询操作列出与连接条件匹配的数据行,它使用比较运算符比较被连接列的列值。内连接分三种:
1、等值连接:在连接条件中使用等于号(=)运算符比较被连接列的列值,其查询结果中列出被连接表中的所有列,包括其中的重复列。
2、不等连接: 在连接条件使用除等于运算符以外的其它比较运算符比较被连接的列的列值。这些运算符包括>、>=、<=、<、!>、!<和<>。
3、自然连接:在连接条件中使用等于(=)运算符比较被连接列的列值,但它使用选择列表指出查询结果集合中所包括的列,并删除连接表中的重复列。
例,下面使用等值连接列出authors和publishers表中位于同一城市的作者和出版社:
SELECT *
FROM authors AS a INNER JOIN publishers AS p ON a.city=p.city
又如使用自然连接,在选择列表中删除authors 和publishers 表中重复列(city和state):
SELECT a.*,p.pub_id,p.pub_name,p.country FROM authors

AS a INNER JOIN publishers AS p ON a.city=p.city

(二)外连接
内连接时,返回查询结果集合中的仅是符合查询条件( WHERE 搜索条件或 HAVING 条件)和连接条件的行。而采用外连接时,它返回到查询结果集合中的不仅包含符合连接条件的行,而且还包括左表(左外连接时)、右表(右外连接时)或两个边接表(全外连接)中的所有数据行。如下面使用左外连接将论坛内容和作者信息连接起来:
SELECT a.*,b.* FROM luntan LEFT JOIN usertable as b ON

a.username=b.username
下面使用全外连接将city表中的所有作者以及user表中的所有作者,以及他们所在的城市:
SELECT a.*,b.*
FROM city as a FULL OUTER JOIN user as b ON a.username=

b.username

(三)交叉连接
交叉连接不带WHERE 子句,它返回被连接的两个表所有数据行的笛卡尔积,返回到结果集合中的数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。例,titles表中有6类图书,而publishers表中有8家出版社,则下列交叉连接检索到的记录数将等于6*8=48行。
SELECT type,pub_name FROM titles CROSS JOIN publishers

ORDER BY type

Sql查询实例之联合查询和连接查询

连接查询 

   通过连接运算符可以实现多个表查询。连接是关系数据库模型的主要特点,也是它区别于其它类型数据库管理系统的一个标志。

   在关系数据库管理系统中,表建立时各数据之间的关系不必确定,常把一个实体的所有信息存放在一个表中。当检索数据时,通过连接操作查询出存放在多个表中的不同实体的信息。连接操作给用户带来很大的灵活性,他们可以在任何时候增加新的数据类型。为不同实体创建新的表,尔后通过连接进行查询。

   连接可以在SELECT 语句的FROM子句或WHERE子句中建立,似是而非在FROM子句中指出连接时有助于将连接操作与WHERE子句中的搜索条件区分开来。所以,在Transact-SQL中推荐使用这种方法。

   SQL-92标准所定义的FROM子句的连接语法格式为:

FROM join_table join_type join_table

[ON (join_condition)]

其中join_table指出参与连接操作的表名,连接可以对同一个表操作,也可以对多表操作,对同一个表操作的连接又称做自连接。

join_type 指出连接类型,可分为三种:内连接、外连接和交叉连接。内连接(INNER JOIN)使用比较运算符进行表间某(些)列数据的比较操作,并列出这些表中与连接条件相匹配的数据行。根据所使用的比较方式不同,内连接又分为等值连接、自然连接和不等连接三种。 中国.网管联盟

外连接分为左外连接(LEFT OUTER JOIN或LEFT JOIN)、右外连接(RIGHT OUTER JOIN或RIGHT JOIN)和全外连接(FULL OUTER JOIN或FULL JOIN)三种。与内连接不同的是,外连接不只列出与连接条件相匹配的行,而是列出左表(左外连接时)、右表(右外连接时)或两个表(全外连接时)中所有符合搜索条件的数据行。

交叉连接(CROSS JOIN)没有WHERE 子句,它返回连接表中所有数据行的笛卡尔积,其结果集合中的数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。

连接操作中的ON (join_condition) 子句指出连接条件,它由被连接表中的列和比较运算符、逻辑运算符等构成。

无论哪种连接都不能对text、ntext和image数据类型列进行直接连接,但可以对这三种列进行间接连接。例如:

SELECT p1.pub_id,p2.pub_id,p1.pr_info

FROM pub_info AS p1 INNER JOIN pub_info AS p2

ON DATALENGTH(p1.pr_info)=DATALENGTH(p2.pr_info)

(一)内连接

内连接查询操作列出与连接条件匹配的数据行,它使用比较运算符比较被连接列的列值。内连接分三种:

1、等值连接:在连接条件中使用等于号(=)运算符比较被连接列的列值,其查询结果中列出被连接表中的所有列,包括其中的重复列。

bitsCN.nET中国网管博客
2、不等连接: 在连接条件使用除等于运算符以外的其它比较运算符比较被连接的列的列值。这些运算符包括>、>=、<=、<、!>、!<和<>。

3、自然连接:在连接条件中使用等于(=)运算符比较被连接列的列值,但它使用选择列表指出查询结果集合中所包括的列,并删除连接表中的重复列。

例,下面使用等值连接列出authors和publishers表中位于同一城市的作者和出版社:

SELECT *

FROM authors AS a INNER JOIN publishers AS p

ON a.city=p.city

 

又如使用自然连接,在选择列表中删除authors 和publishers 表中重复列(city和state):

SELECT a.*,p.pub_id,p.pub_name,p.country

FROM authors AS a INNER JOIN publishers AS p

ON a.city=p.city

 

(二)外连接

内连接时,返回查询结果集合中的仅是符合查询条件( WHERE 搜索条件或 HAVING 条件)和连接条件的行。而采用外连接时,它返回到查询结果集合中的不仅包含符合连接条件的行,而且还包括左表(左外连接时)、右表(右外连接时)或两个边接表(全外连接)中的所有数据行。

如下面使用左外连接将论坛内容和作者信息连接起来:
bbs.bitsCN.com

 

SELECT a.*,b.* FROM luntan LEFT JOIN usertable as b

ON a.username=b.username

 

下面使用全外连接将city表中的所有作者以及user表中的所有作者,以及他们所在的城市:

SELECT a.*,b.*

FROM city as a FULL OUTER JOIN user as b

ON a.username=b.username

 

(三)交叉连接

交叉连接不带WHERE 子句,它返回被连接的两个表所有数据行的笛卡尔积,返回到结果集合中的数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。

例,titles表中有6类图书,而publishers表中有8家出版社,则下列交叉连接检索到的记录数将等

于6*8=48行。

SELECT type,pub_name

FROM titles CROSS JOIN publishers

ORDER BY type
联合查询

UNION运算符可以将两个或两个以上上SELECT语句的查询结果集合合并成一个结果集合显示,即执行联合查询。UNION的语法格式为:

select_statement

UNION [ALL] selectstatement

[UNION [ALL] selectstatement][…n]

其中selectstatement为待联合的SELECT查询语句。

ALL选项表示将所有行合并到结果集合中。不指定该项时,被联合查询结果集合中的重复行将只保留一行。
www_bitscn_com

联合查询时,查询结果的列标题为第一个查询语句的列标题。因此,要定义列标题必须在第一个查询语句中定义。要对联合查询结果排序时,也必须使用第一查询语句中的列名、列标题或者列序号。 在使用UNION 运算符时,应保证每个联合查询语句的选择列表中有相同数量的表达式,并且每个查询选择表达式应具有相同的数据类型,或是可以自动将它们转换为相同的数据类型。在自动转换时,对于数值类型,系统将低精度的数据类型转换为高精度的数据类型。 在包括多个查询的UNION语句中,其执行顺序是自左至右,使用括号可以改变这一执行顺序。例如: 查询1 UNION (查询2 UNION 查询3)

正则表达式口诀及教程

正则其实也势利,削尖头来把钱揣; (指开始符号^和结尾符号$)
特殊符号认不了,弄个倒杠来引路; (指\. \*等特殊符号)
倒杠后面跟小w, 数字字母来表示; (\w跟数字字母;\d跟数字)
倒杠后面跟小d, 只有数字来表示;
倒杠后面跟小a, 报警符号嘀一声;
倒杠后面跟小b, 单词分界或退格;
倒杠后面跟小t, 制表符号很明了;
倒杠后面跟小r, 回车符号知道了;
倒杠后面跟小s, 空格符号很重要;
小写跟罢跟大写,多得实在不得了;
倒杠后面跟大W, 字母数字靠边站;
倒杠后面跟大S, 空白也就靠边站;
倒杠后面跟大D, 数字从此靠边站;
倒框后面跟大B, 不含开头和结尾;

单个字符要重复,三个符号来帮忙; (* + ?)
0 星加1 到无穷,问号只管0 和1; (*表0-n;+表1-n;?表0-1次重复)
花括号里学问多,重复操作能力强; ({n} {n,} {n,m})
若要重复字符串,园括把它括起来; ((abc){3} 表示字符串“abc”重复3次 )
特殊集合自定义,中括号来帮你忙;
转义符号行不通,一个一个来排队;
实在多得排不下,横杠请来帮个忙; ([1-5])
尖头放进中括号,反义定义威力大; ([^a]指除“a”外的任意字符 )
1竖作用可不小,两边正则互替换; (键盘上与“\”是同一个键)
1竖能用很多次,复杂定义很方便;
园括号,用途多;
反向引用指定组,数字排符对应它; (“\b(\w+)\b\s+\1\b”中的数字“1”引用前面的“(\w+)”)
支持组名自定义,问号加上尖括号; (“(?<Word>\w+)”中把“\w+”定义为组,组名为“Word”)
园括号,用途多,位置指定全靠它;
问号等号字符串,定位字符串前面; (“\b\w+(?=ing\b)”定位“ing”前面的字符串)
若要定位串后面,中间插个小于号; (“(?<=\bsub)\w+\b”定位“sub”后面的字符串)
问号加个惊叹号,后面跟串字符串;
PHPer都知道, !是取反的意思;
后面不跟这一串,统统符合来报到; (“\w*d(?!og)\w*”,“dog”不符合,“do”符合)
问号小于惊叹号,后面跟串字符串;
前面不放这一串,统统符合来报到;
点号星号很贪婪,加个问号不贪婪;
加号问号有保底,至少重复一次多;
两个问号老规矩,0次1次团团转;
花括号后跟个?,贪婪变成不贪婪;
还有很多装不下,等着以后来增加

最适合程序员使用的程序代码显示字体

平时一般都用最常见的Courier New字体显示代码,但看久了总是感觉字体发虚,不舒服,于是打算尝试换个别的字体,当然肯定要求是等宽Monospace类字体。这里强力推荐MonacoBitstream Vera Sans Mono这两个字体(后者我想不用介绍,用linux的朋友都知道,这是gnome自带的等宽字体),尤其是Monaco,真的看起来很舒服,写程序时感觉有别样轻松的感觉,毕竟健康对每个程序员都份外的重要!

 

编程用桌面显示规范:

1. 视力不差的话,800×600以上,1024×768最优

2. 字体大小9pt至12pt最佳,保证全屏方式下一目24行以上,40行以下

3. 字体采用绝对的等宽字体,常用的有新宋体/ FixedSys / Courier New等

 

编程用字体选择标准:

1. 所有字符等宽

2. 简洁、清晰、规范的字符形体

3. 支持ASCII码为128以上的扩展字符集

4. 空白字符(ASCII: 0x20)与其他字符等宽

5. ‘1’、’l’和’i’等三个字符易于区分

6. ‘0’、’o’和’O’等三个字符易于区分

7. 双引号、单引号的前后部分易于区分,最好是镜像对称的

8. 清晰的标点符号外形,尤其是大括符、圆括符和方括符