Problem Solution Discussion Managing Multiple Simultaneous AUTO_INCREMENT Values

This exam ple illust rat es an im port ant principle: You m ight t hink about values one way id values as single st rings , but t hat doesnt m ean you m ust necessarily represent t hem in t he dat abase t hat way. I f an alt ernat e represent at ion separat e colum ns is m ore efficient or easier t o work wit h, it m ay well be wort h using—even if you m ust reform at t he underlying colum ns for display purposes t o give t hem t he appearance people expect .

11.15 Managing Multiple Simultaneous AUTO_INCREMENT Values

11.15.1 Problem

Youre working wit h t wo or m ore t ables t hat cont ain AUTO_INCREMENT colum ns, and youre having a hard t im e keeping t rack of t he sequence values generat ed for each t able.

11.15.2 Solution

Save t he values in SQL variables for lat er. I f youre using queries from wit hin a program , save t he sequence values in program variables; or you m ay be able t o issue t he queries using separat e connect ion or st at em ent obj ect s t o keep t hem from get t ing m ixed up.

11.15.3 Discussion

As described in Recipe 11.6 , t he LAST_INSERT_ID ser ver - side sequence value indicat or funct ion is set each t im e a query generat es an AUTO_INCREMENT value, whereas client - side sequence indicat ors m ay be reset for every query. What if you issue a st at em ent t hat generat es an AUTO_INCREMENT value, but dont w ant t o refer t o t hat value unt il aft er issuing a second st at em ent t hat also generat es an AUTO_INCREMENT value? I n t his case, t he original value no longer will be accessible, eit her t hrough LAST_INSERT_ID or as a client -side value. To ret ain access t o it , you should save t he value first before issuing t he second st at em ent . There are several ways t o do t his: • At t he SQL level, you can save t he value in a SQL variable aft er issuing a query t hat generat es an AUTO_INCREMENT value: • INSERT INTO tbl_name id,... VALUESNULL,...; SET saved_id = LAST_INSERT_ID ; Then you can issue ot her st at em ent s wit hout regard t o t heir effect on LAST_INSERT_ID . To use t he original AUTO_INCREMENT value in a subsequent query, refer t o t he saved_id variable. • At t he API level, you can save t he AUTO_INCREMENT value in an API language variable. This can be done eit her by saving t he value ret urned from LAST_INSERT_ID or from any API -specific ext ension t hat m ight be available. • A t hird t echnique can be used from wit hin API s t hat allow you t o m aint ain separat e client - side AUTO_INCREMENT values. For exam ple, in Pyt hon, when you use a cursor obj ect t o execut e a query, t he AUTO_INCREMENT value generat ed by t he query is available by calling t he cursors insert_id m et hod. I f you issue ot her queries using t he sam e cursor, t hat value will be lost . However, if you use a different cursor obj ect t o execut e addit ional queries, t he original cursors insert_id value will be unaffect ed: • cursor1 = conn.cursor • cursor2 = conn.cursor • gen_seq_val cursor1 issue query that generates a sequence number • gen_seq_val cursor2 issue another, using a different cursor • seq1 = cursor1.insert_id • seq2 = cursor2.insert_id • print seq1:, seq1, seq2:, seq2 these values will be different • cursor1.close cursor2.close I n Perl, you can achieve t he sam e effect by m eans of t wo st at em ent handles; t he mysql_insertid at t ribut e for each is unaffect ed by query act ivit y on t he ot her. I n Java, use separat e Statement or PreparedStatement obj ect s. The t hird t echnique doesnt work wit h PHP, because t here is no client - side obj ect or st ruct ure t hat m aint ains AUTO_INCREMENT values on a query- specific basis. The client -side AUTO_INCREMENT value is ret urned by mysql_insert_id , w hich is t ied t o t he connect ion, not t o a st at em ent . Yes, I know what youre t hinking: a workaround would be t o open a second connect ion t o t he server and issue t he first and second queries over t he different connect ions. Youre right , t hat would work—but it s not wort h t he effort . The overhead of opening anot her connect ion is m uch higher t han sim ply saving t he mysql_insert_id value in a PHP variable before issuing anot her query. Furt herm ore, opening a second connect ion isnt as st raight forward as it m ight seem . I f you issue a second mysql_connect or mysql_pconnect call w it h t he sam e connect ion param et ers as t he original call, PHP ret urns t he sam e connect ion ident ifier as t he one it ret urned originally Youd have t o connect t o t he server as a different user t o get a t ruly independent connect ion ident ifier. At t he risk of m uddying t he wat ers, I should point out t hat as of PHP 4.2.0, mysql_connect support s t he opt ion of explicit ly forcing a new connect ion t o be opened. You can use t his feat ure t o m aint ain separat e client - side AUTO_INCREMENT values.

11.16 Using AUTO_INCREMENT Values to Relate Tables