-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.xml
2179 lines (1999 loc) · 60 KB
/
index.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
<!ENTITY author "<ulink url='mailto:johnson.AT.worldhello.net'>Johnson</ulink>">
<!ENTITY orgname "<ulink url='http://www.worldhello.net'>worldhello.net</ulink>">
<!ENTITY % vers SYSTEM "version.xml">
%vers;
]>
<article id="index">
<articleinfo>
<title>Website Construction Howto</title>
<author><firstname>鑫</firstname><surname>蒋</surname></author>
<affiliation>
<orgname>&orgname;</orgname>
<address><email>johnson.AT.worldhello.net</email></address>
</affiliation>
<revhistory>
<!--revision>
<revnumber>$Revision$</revnumber>
<date>$Date$</date>
<authorinitials>$Author$</authorinitials>
<revremark>...</revremark>
</revision-->
<revision>
<revnumber>1.2</revnumber>
<date>2002/12/16</date>
<authorinitials>jiangxin</authorinitials>
<revremark>
添加数据库设计和 PHP 中间件开发
</revremark>
</revision>
<revision>
<revnumber>1.1</revnumber>
<date>2002/12/02</date>
<authorinitials>jiangxin</authorinitials>
<revremark>
补充网站更新流程
</revremark>
</revision>
<revision>
<revnumber>1.0</revnumber>
<date>2002/11/13</date>
<authorinitials>jiangxin</authorinitials>
<revremark>
转换为 docbook 格式
</revremark>
</revision>
<revision>
<revnumber>0.1</revnumber>
<date>2000/9</date>
<authorinitials>jiangxin</authorinitials>
<revremark>
eastmd portal configuration
</revremark>
</revision>
</revhistory>
<abstract>
<para>
本文当基于以前的一个文档《用Apache, Php, MySQL, Oracle 构建电子商务网》,希望对网站开发和维护人员有所帮助。
</para>
<para>
(编译自版本: &doc.revision;,最后更新时间: &doc.lastchange;)
</para>
</abstract>
</articleinfo>
<sect1 id="cvs"><title>CVS进行版本控制和网站更新流程</title>
<sect2><title>CVS进行版本控制</title>
<warning>
<para>
CVS 已经过时,Git 是版本控制的最佳选择。(I wrote a book on Git at 2011, and becomes a Git contributor since then.)
</para>
<para>
没有版本控制的软件开发,永远只能是作坊式的开发。成本高,风险大。
</para>
</warning>
<para>
在网站开发和更新流程中,完全可以利用 CVS,来进行版本控制和版本提升。
</para>
<para>
版本控制,保障了多人的协同工作,不会因为一个人的修改,覆盖另外一个人的更改。而且,也可以通过版本控制系统,获知是谁的修改导致出现BUG,加强责任感。
</para>
<para>
版本提升,引入里程碑概念,使得网站前台的代码是不是最新的代码,而是测试过的,基于某一个时间、label的稳定版本。开发人员不会因为怕给前台带来问题,而不敢 checkin 代码;而且也提供了测试人员介入的接口。
</para>
</sect2>
<sect2><title>网站更新流程</title>
<itemizedlist>
<listitem>
<para>
里程碑
</para>
<para>
CVS可以利用文件来实现里程碑的概念。在工程的根目录下存放 .promotion 文件记录当前网站发布代码的LABEL。保证对外提供服务的生产平台的WEB网页,一定是基于某个里程碑(LABEL)的,而不一定是当前最新的代码。
</para>
</listitem>
<listitem>
<para>
更新脚本
</para>
<para>
更新脚本负责读取 .promotion,确认当前分支(还需要一个文件,确认当前的分支状态)的里程碑label,并依据该 label,Checkout 代码。
</para>
</listitem>
<listitem>
<para>
镜像服务器到生产服务器的同步
</para>
<para>
为了保证生产服务器的安全,可以另外设置一个镜像服务器,定时进行镜像服务器和生产服务器的同步。
</para>
</listitem>
<listitem>
<para>
网站维护的安全性
</para>
<para>
基于CVS工作后,开发小组完成自己网页修改和校验,打上相应的TAG。而网页向镜像服务器和生产服务器的提交,不需要开发小组的干预,而是经过测试小组测试后,由管理员提交。
</para>
</listitem>
<listitem>
<para>
数据库的维护
</para>
<para>
数据库一定要有一个设计结构图。Visio可以自动完成数据库结构图的创建。MySQL数据库可以通过MyODBC作接口,用Visio绘图。
</para>
</listitem>
</itemizedlist>
</sect2>
</sect1>
<sect1 id="dev-product"><title>开发平台和生产平台</title>
<warning>
<para>
想要进行网站开发,必须要建立开发环境,因为网站开发不是简单的网页修改!涉及到脚本解释引擎的安装、数据库的安装、WEB服务器的安装、为调试方便而区分的开发平台和生产平台。
</para>
</warning>
<para>
生产平台,就是网站处于发布环境下,对外/对内提供服务的状态。服务器的配置处于最安全和稳定的状态。
</para>
<para>
开发平台,就是网站处于调试环境下,不对外提供服务,是开发人员的调试平台。服务器配置和代码处于诊断状态,便于程序调试。
</para>
<sect2><title>APACHE 配置的差异</title>
<itemizedlist>
<listitem>
<para>
在生产平台,加入 CheckSpelling,提供对文件名纠错功能
</para>
<screen>
# 生产平台
<IfModule mod_speling.c>
CheckSpelling on
</IfModule>
</screen>
</listitem>
<listitem>
<para>
在开发平台,传递标识变量,用以识别开发平台,打开PHP调试函数
</para>
<screen>
# 在开发平台加入环境变量 MY_DEBUG, 可传递到PHP环境中,识别开发平台和生产平台。
<IfModule mod_env.c>
SetEnv MY_DEBUG on
PassEnv MY_DEBUG
</IfModule>
</screen>
</listitem>
</itemizedlist>
</sect2>
<sect2><title>PHP 配置的差异</title>
<itemizedlist>
<listitem>
<para>
debug 函数只在生产平台在页面输出调试信息
</para>
<para>
调试类 clDebug 提供调试函数,只在生产平台在页面输出调试信息,生产平台,调试信息输出到日志文件。
</para>
<para>
示例:include/test/debug.php
</para>
<screen>
<?php
include("pub/debug.inc");
_debug("hehe");
_debug("hehe","xxx");
$debug=new clDebug();
$debug->timer_init();
for ($i=0; $i<10000; $i++);
_debug("\$i",$i);
$debug->timer_during();
//$debug->set_log("c:/php.debug.html");
for ($i=0; $i<100000; $i++);
_debug("\$i",$i);
$debug->timer_during();
$debug->timer_total();
phpinfo();
?>
</screen>
</listitem>
<listitem>
<para>
display_errors 和 display_startup_errors 的设置
</para>
<para>
在开发平台,设置 display_errors 和 display_startup_errors 为 On;
在生产平台,设置 display_errors 和 display_startup_errors 为 Off。
</para>
<para>
目的是在开发平台能够将PHP报错信息直接显示在网页上。
</para>
</listitem>
<listitem>
<para>
error_reporting 的设置
</para>
<para>
在开发平台,设置 error_reporting 为 <command>error_reporting = E_ALL</command>;
在生产平台,设置 error_reporting 为 <command>error_reporting = E_ALL & ~E_NOTICE</command>。
</para>
<para>
目的是在开发平台能够报告PHP语法上的警告信息。
</para>
</listitem>
</itemizedlist>
</sect2>
</sect1>
<sect1 id="db-oop"><title>数据库设计和 PHP 中间件开发</title>
<para>
PHP支持面向对象的编程。利用类封装数据库的操作,可以保证在脚本中屏蔽掉复杂的数据库操作,而且也可以在网站进行数据库迁移时,减轻工作量。
</para>
<para>
示例:略。
</para>
</sect1>
<sect1 id="ssi"><title>使用SSI (Server Side Include)技术</title>
<para>
想要找到既富有创意的平面设计人员,又有脚本开发经验的人员,实在是太难了。而如果一个百分之百的页面都是php脚本的网站,将为页面维护带来非常大的困难。而且使用了php的自动加头和加尾的方法,使得几乎所有页面都是语义不完整的,不能借助任何一款页面设计工具工作,是另一个弊病。
</para>
<para>
利用SSI技术,可以有效的将HTML网页和CGI脚本逻辑上分开,也可以将重复的HTML元素抽象和独立出来,减轻维护负担。
</para>
<para>
SSI (Server Side Includes) are directives that are placed in HTML pages,
and evaluated on the server while the pages are being served.
They let you add dynamically generated content to an existing HTML page,
without having to serve the entire page via a CGI program, or other dynamic technology.
</para>
<sect2><title>配置Apache,支持SSI</title>
<screen>
# This tells Apache that you want to permit files to be parsed for SSI directives.
Options +Includes -IncludesNOEXEC
# You have to tell Apache which files should be parsed.
AddType text/html .shtml
AddHandler server-parsed .shtml
</screen>
</sect2>
<sect2><title>SSI语法</title>
<itemizedlist>
<listitem>
<para>
Basic SSI directives Syntax
</para>
<screen>
<!--#element attribute=value attribute=value ... -->
</screen>
</listitem>
<listitem>
<para>
Today's date
</para>
<screen>
<!--#config timefmt="%Y/%m/%d %a %H:%M:%S" -->
Today is <!--#echo var="DATE_LOCAL" -->
</screen>
</listitem>
<listitem>
<para>
Modification date of the file
</para>
<screen>
This document last modified <!--#flastmod file="index.html" -->
</screen>
</listitem>
<listitem>
<para>
Including the results of a CGI program
</para>
<screen>
<!--#include virtual="/cgi-bin/counter.pl" -->
<!--#include virtual="/cgi-bin/example.cgi?argument=value" -->
</screen>
<para>
You can use "#exec cgi=" directive, but it can be disabled using the IncludesNOEXEC Option.
</para>
</listitem>
<listitem>
<para>
Including a standard footer
</para>
<screen>
<!--#include virtual="/footer.html" -->
</screen>
</listitem>
<listitem>
<para>
Executing commands
</para>
<screen>
<!--#exec cmd="ls" -->
</screen>
<para>
This feature is dangerous. You can allow SSI, but not the exec feature, with the IncludesNOEXEC argument to the Options directive.
</para>
</listitem>
<listitem>
<para>
Setting variables
</para>
<screen>
<!--#set var="modified" value="$LAST_MODIFIED" -->
<!--#set var="date" value="${DATE_LOCAL}_${DATE_GMT}" -->
</screen>
</listitem>
<listitem>
<para>
Conditional expressions
</para>
<screen>
<!--#if expr="test_condition" -->
<!--#elif expr="test_condition" -->
<!--#else -->
<!--#endif -->
</screen>
</listitem>
</itemizedlist>
</sect2>
</sect1>
<sect1 id="webtest"><title>网页测试</title>
<itemizedlist>
<listitem>
<para>
脱机浏览/网站拷贝软件的使用
</para>
<para>
使用脱机浏览/网站拷贝软件,将网站复制到本地。检查 php 警告和错误特征字符串,检查 mysql 数据库错误字符串。
</para>
<para>
如:PHP 特征字符串:“on line”,mysql特征字符串:"mysql"
</para>
</listitem>
<listitem>
<para>
开发平台和生产平台的对照
</para>
<para>
可以检查出脚本编程许多不规范之处。
</para>
</listitem>
<listitem>
<para>
Differ软件
</para>
<para>
和上一次或者一致的正确版本网站的本地拷贝作比较,察看异同。
</para>
</listitem>
<listitem>
<para>
HTML Tidy and Validate
</para>
<para>
用专业软件,检查网页连接。
</para>
</listitem>
</itemizedlist>
</sect1>
<appendix id="append-mysql"><title>MySQL 安装和使用经验</title>
<sect1 id="mysql-install"><title>安装</title>
<itemizedlist>
<listitem>
<para>
Windows
</para>
<screen>
bin\mysqld-nt --install # Install MySQL as a service
NET START mysql
NET STOP mysql
bin\mysqld-nt --remove # remove MySQL as a service
</screen>
</listitem>
<listitem>
<para>
Unix
</para>
<screen>
<![CDATA[
# groupadd mysql
# useradd -g mysql mysql
# 源代码安装模式
# tar zxvf mysql-xxx.tar.gz
# cd mysql-xxx/
# ./configure --prefix=/usr/local/mysql --localstatedir=/var/db/mysql
# make
# make install
# 二进制安装模式
# cd /usr/local
# gunzip < /path/to/mysql-xxx.tar.gz | tar xvf -
# ln -s mysql-xxx mysql
# cd /usr/local/mysql
# scripts/mysql_install_db
# chown -R root:mysql /usr/local/mysql
# chown -R mysql PATH_TO_MYSQL_DB
# cp surrport_files/mysql.server /etc/rc.d/init.d/mysqld
# chmod a+x /etc/rc.d/init.d/mysqld
# ln -s /etc/rc.d/init.d/mysqld /etc/rc.d/rc3.d/S98mysql
# /etc/rc.d/init.d/mysqld start
# 则启动进程:
/usr/local/mysql/bin/mysqld --defaults-extra-file=/usr/local/mysql/data/my.cnf
--basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
--user=mysql --pid-file=/usr/local/mysql/data/ltcvs.pid --skip-locking
]]>
</screen>
</listitem>
</itemizedlist>
</sect1>
<sect1 id="mysql-conf"><title>配置</title>
<para>
Since MySQL Version 3.22, read default startup options for the server and for clients from option files.
Location: <filename>/etc/my.cnf</filename>, <filename>DATADIR/my.cnf</filename>, or <filename>~/.my.cnf </filename> on Unix,
<filename>windows-system-directory\my.ini</filename>,<filename>c:\my.cnf</filename> or <filename>C:\mysql\data\my.cnf</filename> on Windows.
</para>
<para>
注意 my.cnf 中关于 socket 的设置,如果设置和php识别的不一致,会导致以 unix socket访问数据库失败。建议采用TCP/IP方式建立连接:
即在建立连接时,host填写IP地址,如果是本机,使用127.0.0.1(TCP/IP),而不使用localhost(Unix Socket)。
</para>
</sect1>
<sect1 id="mysql-usage"><title>用法</title>
<sect2><title>常用语法</title>
<itemizedlist>
<listitem>
<para>
测试
</para>
<screen>
shell> telnet server_host 3306
shell&gt; BINDIR/mysqlshow
+-----------+
| Databases |
+-----------+
| mysql |
+-----------+
shell&gt; BINDIR/mysqlshow mysql
Database: mysql
+--------------+
| Tables |
+--------------+
| columns_priv |
| db |
| func |
| host |
| tables_priv |
| user |
+--------------+
shell&gt; BINDIR/mysql -e "select host,db,user from db" mysql
+------+--------+------+
| host | db | user |
+------+--------+------+
| % | test | |
| % | test_% | |
+------+--------+------+
</screen>
</listitem>
<listitem>
<para>
SQL基础
</para>
<screen>
shell> mysql --help
shell> mysql -h <hostname> -u <username> -p[password] [database] [< batch-file]
shell> mysql < batch-file > mysql.out
shell> telnet server_host 3306
mysql> SeLeCt VERSON(), current_DATE;
mysql> SELECT SIN(PI()/4), (4+1)*5;
mysql> SELECT VERSION(); SELECT NOW();
mysql> SHOW DATABASES;
mysql> USE test
mysql> GRANT ALL ON menagerie.* TO your_mysql_name;
mysql> CREATE DATABASE menagerie;
mysql> USE menagerie
shell> mysql -h host -u user -p menagerie
mysql> SHOW TABLES;
mysql> CREATE TABLE pet (name VARCHAR(20), owner VARCHAR(20),
-> species VARCHAR(20), sex CHAR(1), birth DATE, death DATE);
mysql> SHOW TABLES;
mysql> DESCRIBE pet;
mysql> INSERT INTO pet
-> VALUES ('Puffball','Diane','hamster','f','1999-03-30',NULL);
mysql> LOAD DATA LOCAL INFILE "pet.txt" INTO TABLE pet;
mysql> SELECT * FROM pet;
mysql> SELECT name, species, birth FROM pet ORDER BY species, birth DESC;
mysql> SELECT name, birth, CURRENT_DATE,
-> (YEAR(CURRENT_DATE)-YEAR(birth))
-> - (RIGHT(CURRENT_DATE,5)<RIGHT(birth,5))
-> AS age
-> FROM pet;
mysql> SELECT * FROM pet WHERE name LIKE "b%";
mysql> SELECT * FROM pet WHERE name LIKE "%w%";
-- To find names containing exactly five characters, use the `_' pattern character: --
mysql> SELECT * FROM pet WHERE name LIKE "_____";
mysql> SELECT * FROM pet WHERE name REGEXP "^[bB]";
mysql> SELECT * FROM pet WHERE name REGEXP BINARY "^b";
mysql> SELECT * FROM pet WHERE name REGEXP "^.....$";
mysql> SELECT COUNT(*) FROM pet;
mysql> SELECT species, sex, COUNT(*) FROM pet
-> WHERE species = "dog" OR species = "cat"
-> GROUP BY species, sex;
mysql> SELECT pet.name, (TO_DAYS(date) - TO_DAYS(birth))/365 AS age, remark
-> FROM pet, event
-> WHERE pet.name = event.name AND type = "litter";
mysql> SELECT p1.name, p1.sex, p2.name, p2.sex, p1.species
-> FROM pet AS p1, pet AS p2
-> WHERE p1.species = p2.species AND p1.sex = "f" AND p2.sex = "m";
CREATE TABLE shop (
article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL,
dealer CHAR(20) DEFAULT '' NOT NULL,
price DOUBLE(16,2) DEFAULT '0.00' NOT NULL,
PRIMARY KEY(article, dealer));
CREATE TABLE persons (
id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
name CHAR(60) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE shirts (
id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
style ENUM('t-shirt', 'polo', 'dress') NOT NULL,
color ENUM('red', 'blue', 'orange', 'white', 'black') NOT NULL,
owner SMALLINT UNSIGNED NOT NULL REFERENCES persons,
PRIMARY KEY (id)
);
mysql> SELECT 1 IS NULL, 1 IS NOT NULL;
+-----------+---------------+
| 1 IS NULL | 1 IS NOT NULL |
+-----------+---------------+
| 0 | 1 |
+-----------+---------------+
SELECT MAX(article) AS article FROM shop;
<emphasis>How mysql handles sub-query</emphasis>
-- In ANSI SQL this is easily done with a sub-query:
-- SELECT article, dealer, price
-- FROM shop
-- WHERE price=(SELECT MAX(price) FROM shop);
-- In MySQL (which does not yet have sub-selects), just do it in two steps:
-- Get the maximum price value from the table with a SELECT statement.
-- Using this value compile the actual query:
SELECT article, dealer, price
FROM shop
WHERE price=19.95
-- Another solution is to sort all rows descending by price and only get the first row using the MySQL specific LIMIT clause:
SELECT article, dealer, price
FROM shop
ORDER BY price DESC
LIMIT 1;
-- In ANSI SQL, I'd do it with a sub-query like this:
SELECT article, dealer, price
FROM shop s1
WHERE price=(SELECT MAX(s2.price)
FROM shop s2
WHERE s1.article = s2.article);
-- In MySQL it's best do it in several steps:
-- Get the list of (article,maxprice).
-- For each article get the corresponding rows that have the stored maximum price.
-- This can easily be done with a temporary table:
CREATE TEMPORARY TABLE tmp (
article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL,
price DOUBLE(16,2) DEFAULT '0.00' NOT NULL);
LOCK TABLES shop read;
INSERT INTO tmp SELECT article, MAX(price) FROM shop GROUP BY article;
SELECT shop.article, dealer, shop.price FROM shop, tmp
WHERE shop.article=tmp.article AND shop.price=tmp.price;
UNLOCK TABLES;
DROP TABLE tmp;
shell> mysqldump [OPTIONS] database [tables]
OR mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]
OR mysqldump [OPTIONS] --all-databases [OPTIONS]
--opt : Same as --quick --add-drop-table --add-locks --extended-insert --lock-tables.
Should give you the fastest possible dump for reading into a MySQL server.
--no-data
Don't write any row information for the table. This is very useful if you just want to get a dump of the structure for a table!
</screen>
</listitem>
</itemizedlist>
</sect2>
<sect2><title>SQL JOIN</title>
<para>参考链接
</para>
<itemizedlist>
<listitem>
<para>
<ulink url="https://blog.udemy.com/beginners-guide-to-sql/">A Beginner’s Guide to SQL</ulink>
</para>
</listitem>
<listitem>
<para>
<ulink url="http://www.w3schools.com/sql/sql_join.asp">W3SCHOOLS: SQL JOIN</ulink>
</para>
</listitem>
</itemizedlist>
</sect2>
<sect2><title>Others</title>
<itemizedlist>
<listitem>
<para>
Ansi Compatible: use single quote('), note double quote(").
</para>
<screen>
-- the following are the same.
insert into jxtest (ttt) values('js''s test');
insert into jxtest (ttt) values('js\'s test');
</screen>
</listitem>
<listitem>
<para>
Case Sensitivity in Names
</para>
<para>
Database, Table, Alias on Table are case sensitive.
</para>
<para>
If lower_case_table_names is 1 MySQL will convert all table names to lower case on storage and lookup.
Note that if you change this option, you need to first convert your old table names to lower case before
starting mysqld.
</para>
</listitem>
<listitem>
<para>
</para>
</listitem>
</itemizedlist>
</sect2>
</sect1>
<sect1 id="mysql-security"><title>Security</title>
<itemizedlist>
<listitem>
<para>
Don't run the MySQL daemon as the Unix root user.
</para>
</listitem>
<listitem>
<para>
Invest in a firewall
</para>
<para>
Check whether unnecessary host can access database using command "<command>shell> telnet server_host 3306</command>".
</para>
</listitem>
<listitem>
<para>
Password protect your database account
</para>
<screen>
shell> mysql -u root mysql
mysql> UPDATE user SET Password=PASSWORD('new_password')
WHERE user='root';
mysql> FLUSH PRIVILEGES;
or shell> mysqladmin -u root password new_password;
</screen>
</listitem>
<listitem>
<para>
DON'T EVER GIVE ANYONE (EXCEPT THE MySQL ROOT USER) ACCESS TO THE user TABLE IN THE mysql DATABASE!
</para>
<para>
The GRANT and REVOKE commands are used for controlling access to MySQL. Do not grant any more privileges than necessary.
</para>
<screen>
shell> mysql --user=root mysql
mysql> GRANT ALL PRIVILEGES ON *.* TO user1@localhost
IDENTIFIED BY 'some_pass' WITH GRANT OPTION;
mysql> GRANT ALL PRIVILEGES ON *.* TO user1@"%"
IDENTIFIED BY 'some_pass' WITH GRANT OPTION;
</screen>
</listitem>
<listitem>
<para>
Do not keep any plain-text passwords in your database.
</para>
<para>
Instead use MD5() or another one-way hashing function.
</para>
</listitem>
<listitem>
<para>
Do not trust any data entered by your users.
</para>
<para>
A hacker can enters something like ``; DROP DATABASE mysql;'' to destory your database.
</para>
<para>
Check user input data.
</para>
<para>
PHP: use the addslashes() function to quote user import.
</para>
</listitem>
</itemizedlist>
</sect1>
</appendix>
<appendix id="append-oracle"><title>Oracle安装经验</title>
<orderedlist>
<listitem>
<para>
建立dba组oinstall组及oracle用户
</para>
<screen>
#groupadd dba
#groupadd oinstall
#useradd -g oinstall -G dba oracle
#passwd oracle
</screen>
</listitem>
<listitem>
<para>
建立oracle 安装点目录
</para>
<screen>
# mkdir /db/oracle
# chown oracle:oinstall oracle
</screen>
</listitem>
<listitem>
<para>
建立oracle用户环境
</para>
<screen>
#在 .bash_profile 文件中加入:
ORACLE_HOME=/db/oracle ;export ORACLE_HOME
LD_LIBRARY_PATH=$ORACLE_HOME/lib ;export LD_LIBRARY_PATH
PATH=$PATH: $ORACLE_HOME/bin ;export PATH
ORACLE_BASE=$ORACLE_HOME; export ORACLE_BASE
ORACLE_SID=ORC1 ;export ORACLE_SID
NLS_LANG= "FRENCH_FRANCE.WE8ISO8859P1" ;export NLS_LANG
Umask 022
</screen>
</listitem>
<listitem>
<para>
安装过程
</para>
<screen>
以oracle 用户登录运行
$startx
在Xwindows中run /mnt/cdrom/.runInstaller
1. WELCOME 页中选 next
2. FILE LOCATIONS页中若Destination... path为/db/oracle 选 next
3. UNIX GROUP NAME 页中输入UNIX Group Name: oinstall 选 next
4. 弹出一个提示窗要求以root run /db/oracle/orainstRoot.sh
打开一个terminal ,#su ,#orainstRoot.sh 此shell
create Oracle Inventory pointer file (/etc/oraInst.loc)
create groupname of /db/oracle/oraInventory to oinstall
then press retry
5. Available Products 页中选 Oracle8i Enterprise Edition 8.1.6.1.0选 next
6. Installation Types 页中选 Typical(540MB) 选 next
7. Database Identification页中输入 Global Database Name: orc1.est.com.cn
SID: orc1
选 next
8. Database File Location 页中通过Browse或input Directory for Database Files: /db/oracle
选 next
9. Summary 页中 选 Install
10. Install 页 安装过程中弹出Setup Privileges 窗口要求run /db/oracle/root.sh
打开一个terminal ,#su ,#root.sh 此shell
create /etc/oratab file and set
ORACLE_OWNER=oracle
ORACLE_HOME = /db/oracle
ORACLE_SID= orc1
then 选next
11. Configuration Tools 页 完成安装。
12. Web Server(Apache) support
修改/www/apache/bin/apachectl脚本,使启动支持中文ORACLE环境:
在文件中67行("start)")下面加入几行:
export ORACLE_HOME=/db/oracle
export ORACLE_BASE=$ORACLE_HOME
export ORACLE_SID=ORC1
export LD_LIBRARY_PATH=$ORACLE_HOME/lib
;export ORA_NLS33=$ORACLE_HOME/ocommon/nls/admin/data
;export NLS_LANG="SIMPLIFIED CHINESE_CHINA.ZHS16CGB231280"
export NLS_LANG="FRENCH_FRANCE.WE8ISO8859P1"
</screen>
</listitem>
<listitem>
<para>
安装完成以后修改 /etc/oratab 中
</para>
<screen>
orc1:/db/oracle:N 为 orc1:/db/oracle:Y
修改 /db/oracle/bin/dbstart 中85行
/PL\/SQL (Release|Version)/{substr($3,1,3) ;
print substr($3,1,3)}'`
为 /Edition Release/ {substr($5,1,3) ;
print substr($5,1,3)}'`
注意:不可插入多余的字符,最好在修改模式下进行,否则可能会造成不能启动。
</screen>
</listitem>
<listitem>
<para>
启动ORACLE
</para>
<screen>
以oracle 登录 run
lsnrctl start listener
dbstart
</screen>
</listitem>
<listitem>
<para>
自动启动ORACLE
</para>
<screen>
建立脚本 /etc/rc.d/init.d/oracle8i ; chmod +x ;内容如下:
;*************start *************
ORA_HOME=/db/oracle
ORA_OWNER=oracle
case "$1" in
'start')
echo -n "Starting Oracle8i Release 2: "
su - $ORA_OWNER -c $ORA_HOME/bin/dbstart
touch /var/lock/subsys/oracle8i
echo
;;
'stop')
echo -n "Shutting down Oracle8i Release 2:"
su - $ORA_OWNER -c $ORA_HOME/bin/dbshut
rm -f /var/lock/subsys/oracle8i
echo
;;
'restart')
echo -n "Restarting Oracle8i Release 2:"
$0 stop
$0 start
echo
;;
*)
echo "Usage: oracle8i { start | stop | restart }"
exit 1
esac
exit 0
;***************end ****************
建立链接 ln -s /etc/rc.d/init.d/oracle8i /etc/rc.d/rc0.d/K10oracle8i ;Runlevel 0 是 HALT
建立链接 ln -s /etc/rc.d/init.d/oracle8i /etc/rc.d/rc6.d/K10oracle8i ;Runlevel6 是 reboot
建立链接 ln -s /etc/rc.d/init.d/oracle8i /etc/rc.d/rc3.d/S99oracle8i ;Runlevel3 是 缺省运行级别
此时listener 还没运行,需运行 lsnrctl start listener
或则在dbstart 开始处加入此命令。
至此以oracle 用户登录就可以发现oracle 和 listener 都已启动。
注意:
若脚本名字不是oracle8i 则相应的修改下列行中的脚本名
touch /var/lock/subsys/oracle8i
rm -f /var/lock/subsys/oracle8i
</screen>
</listitem>
<listitem>
<para>
其它:修改字符集
</para>
<screen>
附录:
ORACLE中修改字符集( 用此方法也可修改全局数据库名)
Backup your database
Svrmgrl
Connect internal
Update props$ set value$=' WE8ISO8859P1' ;划线部分必须大写
Where name='NLS_CHARACTERSET'; ;划线部分必须大写
Commit
Shutdown
Startup
Exit
常用字符集代码
SIMPLIFIED CHINESE_CHINA.ZHS16GBK
NLS_LANG = AMERICAN_AMERICA.US7ASCII
or
NLS_LANG = FRENCH_FRANCE.WE8ISO8859P1
or
NLS_LANG = FRENCH_CANADA.WE8DEC
or
NLS_LANG = JAPANESE_JAPAN.JA16EUC
</screen>
</listitem>
</orderedlist>
</appendix>
<appendix id="append-apache"><title>Apache配置</title>
<sect1 id="apachache-unix"><title>Unix 安装</title>
<orderedlist>
<listitem>
<para>
Download Apache source
</para>
<screen>
$ tar zxvf apache_xxx.tgz
</screen>
</listitem>
<listitem>
<para>
mod_perl
</para>
<screen>
<![CDATA[
cd ../mod_perl-xxx/
perl Makefile.PL APACHE_SRC=../apache_1.3.xx/src \
DO_HTTPD=1 USE_APACI=1 EVERYTHING=1
make && make test && make install
]]>
</screen>
</listitem>