Nm vn chung v c s d liu trên PHP Mc : Trung bình Jack Herrington, Tng biên tp, Code Generation Network 08 01 2010 Hãy khám phá nm vn v c s d liu ph bin xy ra trong các ng dng PHP -- gm thit k lc c s d liu, truy cp c s d liu và mã logic nghip v s dng c s d liu -- cng nh các gii pháp ca chúng. Nu ch có mt cách s dng c s d liu chính xác . Bn có th to thit k c s d liu, truy cp c s d liu và mã logic nghip v PHP t trên u trang ca nó theo mt s cách nào ó và bn thng kt thúc khi nhn thy nó sai. Bài vit này minh ha nm vn thng gp trong vic thit k c s d liu, trong mã PHP truy cp các c s d liu và cách sa cha nhng vn này khi bn bt gp chúng. Vn 1: S dng MySQL trc tip Khi s dùng các hàm mysql_ truy cp trc tip vào c s d liu có mt vn ph bin là mã PHP ã c. Lit kê 1 ch ra cách truy cp trc tip vào c s d liu. Lit kê 1. Access/get.php Hãy lu ý vic s dng hàm mysql_connect truy cp vào c s d liu. Cng chú ý truy vn trong ó có dùng s liên kt chu i b sung tham s $name vào truy vn ó. K! thut này có hai s la chn tt: mô un PEAR DB và các l"p PHP Data Objects (PDO-Các i tng d liu PHP). C hai u cung cp s tr#u tng t# vic la chn ca mt c s d liu c th. Do ó, mã ca bn có th chy mà không cn iu chnh quá nhiu trên IBM® DB2®, MySQL, PostgreSQL, hoc c s d liu khác bt k$ mà bn mun kt ni n. Các giá tr% khác trong vic s dng các tng tr#u tng ca mô un PEAR DB và PDO là bn có th s dng toán t ? trong các câu lnh SQL ca bn. Vic này làm cho SQL d& dàng bo trì hn và bo v ng dng ca bn kh'i các cuc tn công ni x SQL. Mã thay th khi s dng PEAR DB c hin th% d"i ây. Lit kê 2. Access/get_good.php ! ! "#$%$&'()*+,-$)$"..""! /01!2 ! 2 345! 6 "78."! Page 1 of 10Nm vn chung v c s d liu trên PHP Chú ý r(ng tt c các cp trc tip ca MySQL ã di&n ra, tr# chu i kt ni c s d liu trong $dsn . Ngoài ra, chúng ta s dng bin $name trong SQL thông qua toán t ? . Sau ó, d liu v"i truy vn này c gi i thông qua array cui phng thc query() . Vn 2: Không s dng chc nng tng t ng Ging nh hu ht các c s d liu hin i, MySQL có kh nng to các trình nhn dng (identifier) duy nht tng t ng trên mt c s cho m i bn ghi. Mc dù vy, chúng ta v)n thy mã ln u tiên chy mt lnh SELECT tìm mã nhn dng ( id ) ti a, sau ó b sung thêm mt vào id ó, cng nh mt bn ghi m"i. Lit kê 3 cho thy mt lc m)u bad (xu). Lit kê 3. Badid.sql Trng id ây c quy %nh n gin là mt s nguyên. Vì vy, mc dù nó s* là duy nht, chúng ta có th thêm vào bt k$ giá tr% nào mà chúng ta mun, nh ã ch ra trong câu lnh INSERT tip theo câu lnh CREATE . Lit kê 4 ch ra mã PHP b sung thêm users (nhng ngi s dng) vào kiu lc này. Lit kê 4. Add_user.php 9::9 ;:! <7899&! =$>)99$?6+!2 ?6#$%$&'()*+,-$)$ ! ! ?6@ /01!2 ! 2 345! 6 7)*='>8%$@($A@#'#! &)$>'$'>8%$ +$7@B+@C' '$A' '$A' ! @C#$)'@C'*D>%B$#E45! @C#$)'@C'*D>%B$#F4! @C#$)'@C'*D>%B$#E4! "78."! ! 9::9 ;:! <7899&! =$>)99$?6+!2 ?6"#$%$&'G()*+"! ! ?6@ /01!2 HE! ?6"@C#$)'@C'*D>%B$#"! ?6G! ! 2 Page 2 of 10Nm vn chung v c s d liu trên PHP Mã trong add_user.php u tiên thc hin mt truy vn tìm ra giá tr% ti a ca id . Sau ó tp này chy mt câu lnh INSERT v"i giá tr% id cng thêm mt. Mã này có th không chy thành công trong các iu kin ganh ua (race) trên các máy ch có mt ti nng. Hn na, nó không hiu qu. Vì vy, s thay th là gì? S dng tính nng tng t ng trong MySQL to các ID duy nht cho m i ln chèn t ng. Lc cp nht c hin th% bên d"i. Lit kê 5. Goodid.php Chúng ta thêm c NOT NULL ch ra r(ng các trng này không r ng (null). Chúng ta cng ã b sung c AUTO_INCREMENT ch th% r(ng trng này tng t ng, cng nh c PRIMARY KEY ch th% trng nào là id . Nhng thay i này cho phép tng mt chút tc . Lit kê 6 cho thy mã PHP ã cp nht, mã này chèn users (nhng ngi dùng) vào bng. Lit kê 6. Add_user_good.php Thay vì nhn c giá tr% id ti a, tôi bây gi ch cn s dng câu lnh INSERT chèn d liu, sau ó s dng mt câu lnh SELECT ly id ca bn ghi v#a m"i c chèn vào. Mã này n gin hn nhiu và hiu qu hn so v"i phiên bn gc và lc liên quan ca nó. Mt la chn khác i v"i chc nng tng t ng ca MySQL là s dng phng thc nextId() trong h thng PEAR DB. Trong trng hp ca MySQL, iu này to ra mt bng tun t m"i và qun lý vic s dng mt c ch khóa phc tp. Li th ca vic s dng phng thc này là nó s* hot ng trên các h thng c s d liu khác. Dù b(ng cách nào, bn nên s dng mt h thng qun lý s tng các ID duy nht cho bn và không da vào h thng mà bn truy vn u tiên, sau ó tng giá tr% ca chính bn và thêm bn ghi. Cách tip cn th hai d& b% nh hng theo các iu kin ganh ua trên các trang có khi lng cao. 4! 3! 6 7)*='>8%$@($A@#'#! &)$>'$'>8%$ +$7@B+@C'C*'CB%%>B'*@C&)$+$C' '$A'C*'CB%% '$A'C*'CB%% =)@+>)IJ$I ! @C#$)'@C'*D>%B$#45! @C#$)'@C'*D>%B$#4! @C#$)'@C'*D>%B$#4! "78."! 9::9 ;:! <7899&! =$>)99$?6+!2 ?6"@C#$)'@C'*D>%B$#"! ?6G! ?6"#$%$&'"! ! ?6@ /01!2 ! 2 4! 3! 6 Page 3 of 10Nm vn chung v c s d liu trên PHP Vn 3: S dng nhiu c s d liu Mt khi chúng ta thy ng dng mà m i bng trong mt c s d liu riêng bit. Có nhiu lý do thc hin iu ó trong các c s d liu rt l"n, nhng i v"i ng dng trung bình, bn không cn mc phân on này. Ngoài ra, mc dù có th thc hin các truy vn liên quan trên nhiu c s d liu, tôi rt khuyên bn chng li nó. Cú pháp phc tp hn. Qun lý sao lu và khôi phc li không d& dàng. Cú pháp có th hoc không th làm vic gia các máy c s d liu khác nhau. Và tht khó khn tip tc theo cu trúc quan h khi các bng c chia trên nhiu c s d liu. Vì vy, nhiu c s d liu s* ging th nào? + bt u, bn cn mt s d liu. Lit kê 7 cho thy d liu này c chia thành bn tp. Lit kê 7. Các tp c s d liu Trong phiên bn nhiu c s d liu ca các tp này, bn s* np câu lnh SQL vào trong mt c s d liu, sau ó np các câu lnh SQL users (nhng ngi s dng) vào c s d liu khác. Mã PHP truy vn c s d liu cho các tp này liên kt v"i ngi dùng c th c hin th% d"i ây. Lit kê 8. Getfiles.php (.9 (.9(.9 (.9 &)$>'$'>8%$ +$7@B+@C' +$7@B+@C' '$A' '$A' ! %.9 %.9%.9 %.9 @C#$)'@C'*D>%B$#EEE.4:E.4! @C#$)'@C'*D>%B$#FEF.4:F.4! B.9 B.9B.9 B.9 7)*='>8%$@($A@#'#! &)$>'$'>8%$ +$7@B+@C' '$A' '$A' ! %.9 %.9%.9 %.9 @C#$)'@C'*D>%B$#E45! @C#$)'@C'*D>%B$#F4! "78."! 9::9 ;:E! <7899&! =$>)99$?6+!2 ?6"#$%$&'()*+,-$)$" ! ! ?6@ /01!2 ! 2 ! ! 9::9 ;:F! <7899&! =$>)99$?6+!2 Page 4 of 10Nm vn chung v c s d liu trên PHP Hàm get_user kt ni t"i c s d liu cha bng ca nhng ngi s dng và ly ra ID cho mt ngi dùng ã bit. Hàm get_files kt ni n bng các tp và ly ra các hàng có kt hp v"i ngi dùng ã bit. Cách tt hn làm tt c nhng iu này là np d liu vào mt c s d liu, sau ó thc hin mt truy vn, nh c hin th% bên d"i. Lit kê 9. Getfiles_good.php Mã này không ch ngn hn mà nó cng d& hiu hn và hiu qu hn. Thay vì thc hin hai truy vn, chúng ta ang thc hin mt. Trong khi vn này lc iu, chúng ta ã thy nó trong thc t có thi gian bit r(ng tt c các bng phi trong cùng mt c s d liu, tr# khi có mt lý do cp thit khác. Vn 4: Không s dng các mi quan h Các c s d liu quan h không ging nh các ngôn ng lp trình. Chúng không có kiu mng. Thay vào ó, chúng s dng các mi quan h gia các bng to ra cu trúc mt-t"i-nhiu gia các i tng, chúng có cùng tác dng nh mt mng. Mt vn mà tôi ã thy v"i các ng dng là khi các k! s c gng s dng mt c s d liu nh th nó ã là mt ngôn ng lp trình, to arrays (các mng) b(ng cách s dng chu i vn bn v"i các trình nhn dng tách nhau b(ng du ph,y. Hãy xem lc d"i ây. Lit kê 10. Bad.sql ?6"#$%$&'K()*+,-$)$" ! ?6@ /1 !2 ! 2 45! 3! 6 "78."! ! 9::9 ;:! <7899&! =$>)99$?6+!2 ?6 "#$%$&'.K()*+,-$)$ .>C7.." ! ?6@ /1 !2 ! 2 45! 3! 6 7)*='>8%$@($A@#'#! &)$>'$'>8%$ +$7@B+@C' '$A' '$A' ! Page 5 of 10Nm vn chung v c s d liu trên PHP Mt ngi dùng trong h thng có th có nhiu tp. Trong mt ngôn ng lp trình, bn s* s dng mt mng biu di&n các tp liên kt v"i ngi dùng. Trong ví d này, lp trình viên ã chn to ra mt trng files (các tp) cha danh sách các id tp c phân cách b(ng du ph,y. + có c mt danh sách tt c các tp cho ngi dùng c th, lp trình viên tr"c tiên phi c hàng t# bng nhng ngi dùng, sau ó phân tích cú pháp vn bn ca tp và chy mt câu lnh SELECT riêng l- cho m i tp. Mã này c hin th% bên d"i Lit kê 11. Get.php K! thut này chm, khó bo trì và không tn dng tt c s d liu. Gii pháp duy nht là tái kin trúc lc này a nó tr li thành mt dng quan h truyn thng, nh c hin th% d"i ây. Lit kê 12. Good.sql 7)*='>8%$@($A@#'#! &)$>'$'>8%$ +$7@B+@C' '$A' '$A' '$A' ! @C#$)'@C'*D>%B$#EE.4:E.4! @C#$)'@C'*D>%B$#FE.4:E.4! @C#$)'@C'*D>%B$#E45EF! "78."! 9::9 ;:! <7899&! =$>)99$?6+!2 ?6"#$%$&'()*+,-$)$" ! ! ?6@ /01!2 ! ?6"#$%$&'K()*+,-$)$" ! ?6@ /1 !2 2 ! 2 45! 3! 6 7)*='>8%$@($A@#'#! &)$>'$'>8%$ +$7@B+@C' +$7@B+@C' '$A' '$A' ! 7)*='>8%$@($A@#'#! &)$>'$'>8%$ +$7@B+@C' '$A' '$A' ! @C#$)'@C'*D>%B$#E45! @C#$)'@C'*D>%B$#EEE.4:E.4! @C#$)'@C'*D>%B$#FEE.4:E.4! Page 6 of 10Nm vn chung v c s d liu trên PHP . ây, m i tp có liên quan n ngi dùng thông qua hàm user_id trong bng tp. +iu này hu nh có v- lc hu v"i bt k$ ai nhìn thy iu này nh là mt mng. Chc chn, các mng không tham chiu n i tng trong mng -- thc t, ngc li hoàn toàn. Nhng trong mt c s d liu quan h, ây là cách nhng th này làm và lí do các truy vn là nhanh hn và d& dàng hn nhiu. Lit kê 13 cho thy mã PHP tng ng. Lit kê 13. Get_good.php . ây, chúng ta thc hin mt truy vn n c s d liu nhn c tt c các hàng. Mã này không phc tp và nó s dng c s d liu nh nó ã c d %nh. Vn 5: Mu n+1 Tôi không th nói cho bn bit bao nhiêu ln chúng ta ã nhìn thy các ng dng l"n trong ó mã này u tiên ly ra mt danh sách các thc th -- gi là các khách hàng -- sau ó quay tr li và ly ra chúng t#ng ngi mt có c nhng chi tit cho t#ng thc th. Chúng ta gi nó là m)u n+1 vì ó là có bao nhiêu truy vn s* c thc hin -- mt truy vn ly ra danh sách tt c các thc th, ri mt truy vn cho m i mt trong n thc th. +ây không phi là mt vn khi n = 10, nhng s* là gì khi n = 100 hoc n = 1000? Ri, s thiu kh nng thc s óng góp vào. Lit kê 14 cho thy mt ví d v mt lc nh vy. Lit kê 14. Schema.sql "78."! 9::9 ;:! <7899&! =$>)99$?6+!2 ! ?6 "#$%$&'.K()*+,-$)$. >C7.." ! ?6@ /1 !2 ! 2 45! 3! 6 7)*='>8%$@($A@#'#! &)$>'$'>8%$ +$7@B+@C'C*'CB%%>B'*@C&)$+$C' '$A'C*'CB%% =)@+>)IJ$I ! 7)*='>8%$@($A@#'#5! &)$>'$'>8%$5 +$7@B+@C'C*'CB%%>B'*@C&)$+$C' +$7@B+@C'C*'CB%% '$A'C*'CB%% =)@+>)IJ$I ! @C#$)'@C'*D>%B$#L5-! @C#$)'@C'*D>%B$#73'! @C#$)'@C'*5D>%B$#E&M>! @C#$)'@C'*5D>%B$#E=-5! @C#$)'@C'*5D>%B$#E=-=-5! @C#$)'@C'*5D>%B$#F==! @C#$)'@C'*5D>%B$#F))! @C#$)'@C'*5D>%B$#F=)! Page 7 of 10Nm vn chung v c s d liu trên PHP +ây là lc áng tin cy. Không có gì sai ây. Vn là trong mã truy cp vào c s d liu tìm tt c các sách cho mt tác gi c th, nh c hin th% d"i ây. Lit kê 15. Get.php Nu bn nhìn vào mã d"i cùng, bn có kh nng suy ngh/ n chính mình, "Ôi, iu này thc s sch s*." Tr"c tiên, nhn c id , tác gi, ri nhn c mt danh sách các cun sách, sau ó nhn c thông tin v m i cun sách. Chc chn, nó sch s* -- nhng nó có hiu qu không? Không. Hãy nhìn xem chúng ta phi thc hin bao nhiêu các truy vn ly ra ch các sách ca Jack Herrington. Mt truy vn nhn c mt id , mt truy vn khác nhn c mt danh sách các cun sách, sau ó mt truy vn cho m i cun sách. Nm truy vn cho ba cun sách! Gii pháp này là có mt hàm thc hin mt s lng l"n truy vn, nh lit kê d"i ây. Lit kê 16. Get_good.php 78.! 9::9 ;:5! <7899&! =$>)99$?6+!2 ! ?6"#$%$&'()*+,-$)$" ! ! ?6@ /01!2 ! 2 5 ! ?6"#$%$&'()*+5,-$)$" ! ! ?6@ /1 /01!2 ! 2 5 ! ?6"#$%$&'K()*+5,-$)$"! ?6@ !2 ! 2 L5-! 55! 55 555! 35! 2 6 78.! 9::9 ;:5! <7899&! =$>)99$?6+!2 5 ! ?6 "#$%$&'5.K()*+5,-$)$ 5..>C7." ! Page 8 of 10Nm vn chung v c s d liu trên PHP Bây gi ly ra danh sách yêu cu ch mt truy vn, nhanh. Nó có ngh/a là tôi có kh nng s* phi có mt s các kiu các phng thc này v"i các tham s khác nhau, nhng thc s không có s la chn nào. Nu bn mun có mt ng dng PHP có th so sánh c v"i nhau, bn phi s dng hiu qu c s d liu và iu ó có ngh/a là các truy vn thông minh hn. Vn v"i ví d này là nó quá rõ ràng. Thông thng, các kiu ca vn n+1 hay n*n nhy cm hn nhiu. Và chúng ch xut hin khi ngi qun tr% c s d liu chy mt trình %nh hình truy vn trên h thng ca bn khi nó có vn v hiu nng. Kt lun Các c s d liu là các công c mnh và -- nh tt c các công c mnh m* -- chúng có th b% lm dng nu bn không bit cách s dng chúng cho úng. Th thut phía sau vic xác %nh và gii quyt các vn này là hiu rõ hn v công ngh bên d"i. Quá lâu, tôi ã nghe các nhà mã hóa logic nghip v than th r(ng h không mun phi hiu c s d liu hoc mã SQL. H bao bc c s d liu trong các i tng và t h'i ti sao hiu nng li kém n nh vy. H không nhn ra r(ng s hiu bit SQL là nguyên tc c bn chuyn c s d liu t# mt hoàn cnh khó khn thành mt ng minh mnh. Nu bn s dng c s d liu hàng ngày, nhng SQL không phù hp v"i bn, hãy c The Art of SQL (Ngh thut SQL). +ây là h"ng d)n thit thc, c vit rõ ràng nhn c nhiu nht bên ngoài mt c s d liu. Tài nguyên Hc tp The Art of SQL (Ngh thut SQL), ca Stephane Faroult và Peter Robson, là mt cun sách phi c i v"i các lp trình viên, nhng ngi s dng c s d liu trong các ng dng ca h. PHP.net là im khi u cho tt c mi th PHP. Tài liu PEAR DB là mt tài nguyên xut sc. Tài liu các chc nng PDO có th a bn lên n tc trên PHP Data Objects (PDO- Các i tng d liu PHP). MySQL.org có tài liu h"ng d)n xut sc v"i các ví d hin th% cách s dng mt c s d liu tt hn. Truy cp tài nguyên d án PHP ca developerWorks IBM tìm hiu thêm v PHP. Theo sát v"i các s kin k! thut và webcast ca developerWorks. Hãy xem các hi ngh%, các cuc trin lãm thng mi, webcast sp t"i và các s kin trên th gi"i mà các nhà phát trin mã ngun m ca IBM ang quan tâm. Truy cp vào l/nh vc mã ngun m ca developerWorks v"i các thông tin h"ng d)n rng l"n, các công c và d án giúp bn phát trin v"i các công ngh mã ngun m và s dng chúng v"i các sn ph,m ca IBM. ! ?6@ /1 !2 ! 2 55L5-! 35! 6 Page 9 of 10Nm vn chung v c s d liu trên PHP + nghe các cuc ph'ng vn và tho lun thú v% v"i các nhà phát trin phn mm, hãy xem developerWorks podcasts. Ly sn phm và công ngh +i m"i d án phát trin ngun m tip theo ca ca bn v"i phn mm dùng th IBM, có s0n ti xung hoc trên /a DVD. Tho lun Dành tâm trí cho cng ng developerWorks b(ng cách tham gia vào các blog ca developerWorks. ôi nét v tác gi Jack D. Herrington là k! s phn mm cao cp v"i hn 20 nm kinh nghim. Ông là tác gi ca ba cun sách: Code Generation in Action, Podcasting Hacks và PHP Hacks. Ông cng ã vit hn 30 bài báo. Page 10 of 10Nm vn chung v c s d liu trên PHP . ?6G! ! 2 Page 2 of 10Nm vn chung v c s d liu trên PHP Mã trong add_user .php u tiên thc hin mt truy vn tìm ra giá. Action, Podcasting Hacks và PHP Hacks. Ông cng ã vit hn 30 bài báo. Page 10 of 10Nm vn chung v c s d liu trên PHP