Revenue Source

Welcome to the Revenue Source affiliate marketing forums.

You are viewing our internet marketing and SEO forums as a guest which gives you limited access to most of our discussions.  By joining our free community, you will have access to post affiliate marketing topics, communicate privately with other members (PM), exchange SEO strategies, and access many other special features.  Registration is fast, simple and absolutely free so please, join our community today!

If you have any problems, please don't hesitate to contact us.

Go Back   Revenue Source > Site Design & Development > Databases
Reload this Page Merge Tables Gotcha
Tags: , ,

Reply
 
LinkBack Thread Tools Search this Thread
Old
  (#1 (permalink))
Affiliate Blogs is Offline
Revenue Source Veteran
Affiliate Blogs has a brilliant future here!
 
Affiliate Blogs's Avatar
 
Join Date: Oct 2005
Posts: 9,144
Jack of All Trades
CyberSpace United States
   
Merge Tables Gotcha - 05-09-2007

I had the interesting customer case today which made me to do a bit research on the problem.
You can create merge table over merge tables which contain primary key and global uniqueness would not be enforced in this case, this is as far as most people will think about it. In fact however it is worse than that - if you have same key values in underlying merge tables some of the queries may give you wrong results:
PLAIN TEXT
SQL:
  1. [FONT='Courier New', Courier, monospace]mysql> CREATE TABLE t1(id int UNSIGNED PRIMARY KEY);[/font]
  2. [FONT='Courier New', Courier, monospace]Query OK, 0 rows affected (0.07 sec)[/font]
  3. [FONT='Courier New', Courier, monospace] [/font]
  4. [FONT='Courier New', Courier, monospace]mysql> CREATE TABLE t2(id int UNSIGNED PRIMARY KEY);[/font]
  5. [FONT='Courier New', Courier, monospace]Query OK, 0 rows affected (0.02 sec)[/font]
  6. [FONT='Courier New', Courier, monospace] [/font]
  7. [FONT='Courier New', Courier, monospace]mysql> CREATE TABLE tm(id int UNSIGNED NOT NULL PRIMARY KEY) type=merge union(t1,t2);[/font]
  8. [FONT='Courier New', Courier, monospace]Query OK, 0 rows affected, 1 warning (0.03 sec)[/font]
  9. [FONT='Courier New', Courier, monospace] [/font]
  10. [FONT='Courier New', Courier, monospace]mysql> INSERT INTO t1 VALUES(1);[/font]
  11. [FONT='Courier New', Courier, monospace]Query OK, 1 row affected (0.00 sec)[/font]
  12. [FONT='Courier New', Courier, monospace] [/font]
  13. [FONT='Courier New', Courier, monospace]mysql> INSERT INTO t2 VALUES(1);[/font]
  14. [FONT='Courier New', Courier, monospace]Query OK, 1 row affected (0.00 sec)[/font]
  15. [FONT='Courier New', Courier, monospace] [/font]
  16. [FONT='Courier New', Courier, monospace] [/font]
  17. [FONT='Courier New', Courier, monospace]mysql> SELECT * FROM tm WHERE id=1;[/font]
  18. [FONT='Courier New', Courier, monospace]+----+[/font]
  19. [FONT='Courier New', Courier, monospace]| id |[/font]
  20. [FONT='Courier New', Courier, monospace]+----+[/font]
  21. [FONT='Courier New', Courier, monospace]| 1 |[/font]
  22. [FONT='Courier New', Courier, monospace]+----+[/font]
  23. [FONT='Courier New', Courier, monospace]1 row IN SET (0.00 sec)[/font]
  24. [FONT='Courier New', Courier, monospace] [/font]
  25. [FONT='Courier New', Courier, monospace]mysql> SELECT * FROM tm;[/font]
  26. [FONT='Courier New', Courier, monospace]+----+[/font]
  27. [FONT='Courier New', Courier, monospace]| id |[/font]
  28. [FONT='Courier New', Courier, monospace]+----+[/font]
  29. [FONT='Courier New', Courier, monospace]| 1 |[/font]
  30. [FONT='Courier New', Courier, monospace]| 1 |[/font]
  31. [FONT='Courier New', Courier, monospace]+----+[/font]
  32. [FONT='Courier New', Courier, monospace]2 rows IN SET (0.00 sec)[/font]
  33. [FONT='Courier New', Courier, monospace] [/font]
  34. [FONT='Courier New', Courier, monospace]mysql> EXPLAIN SELECT * FROM tm WHERE id=1 \G[/font]
  35. [FONT='Courier New', Courier, monospace]*************************** 1. row ***************************[/font]
  36. [FONT='Courier New', Courier, monospace] id: 1[/font]
  37. [FONT='Courier New', Courier, monospace] select_type: SIMPLE[/font]
  38. [FONT='Courier New', Courier, monospace] TABLE: tm[/font]
  39. [FONT='Courier New', Courier, monospace] type: const[/font]
  40. [FONT='Courier New', Courier, monospace]possible_keys: PRIMARY[/font]
  41. [FONT='Courier New', Courier, monospace] KEY: PRIMARY[/font]
  42. [FONT='Courier New', Courier, monospace] key_len: 4[/font]
  43. [FONT='Courier New', Courier, monospace] ref: const[/font]
  44. [FONT='Courier New', Courier, monospace] rows: 1[/font]
  45. [FONT='Courier New', Courier, monospace] Extra: USING INDEX[/font]
  46. [FONT='Courier New', Courier, monospace]1 row IN SET (0.00 sec) [/font]



In this case there are obviously two rows with value 1 in merge table however select querying by primary index returns only one.
Following EXPLAIN shows why this is the case - MySQL knows this is primary key and pre-reads the value in question as "const" value. Similar things happens in JOIN queries when it would use "eq_ref" lookup type which means it will only do one lookup for each key value as it knows it is unique.
In the case I was working on it was required to enforce uniqueness in the tables which are later queries as merge table so we could not drop PRIMARY KEY so I thought I should try using key on the given column instead:
PLAIN TEXT
SQL:
  1. [FONT='Courier New', Courier, monospace]mysql> CREATE TABLE tx (id int UNSIGNED NOT NULL, KEY(id)) type=merge union(t1,t2);[/font]
  2. [FONT='Courier New', Courier, monospace]Query OK, 0 rows affected, 1 warning (0.02 sec)[/font]
  3. [FONT='Courier New', Courier, monospace] [/font]
  4. [FONT='Courier New', Courier, monospace]mysql> SELECT * FROM tx WHERE id=1;[/font]
  5. [FONT='Courier New', Courier, monospace]+----+[/font]
  6. [FONT='Courier New', Courier, monospace]| id |[/font]
  7. [FONT='Courier New', Courier, monospace]+----+[/font]
  8. [FONT='Courier New', Courier, monospace]| 1 |[/font]
  9. [FONT='Courier New', Courier, monospace]| 1 |[/font]
  10. [FONT='Courier New', Courier, monospace]+----+[/font]
  11. [FONT='Courier New', Courier, monospace]2 rows IN SET (0.00 sec)[/font]
  12. [FONT='Courier New', Courier, monospace] [/font]
  13. [FONT='Courier New', Courier, monospace] [/font]
  14. [FONT='Courier New', Courier, monospace]mysql> SELECT * FROM tx;[/font]
  15. [FONT='Courier New', Courier, monospace]+------+[/font]
  16. [FONT='Courier New', Courier, monospace]| id |[/font]
  17. [FONT='Courier New', Courier, monospace]+------+[/font]
  18. [FONT='Courier New', Courier, monospace]| 1 |[/font]
  19. [FONT='Courier New', Courier, monospace]| 1 |[/font]
  20. [FONT='Courier New', Courier, monospace]+------+[/font]
  21. [FONT='Courier New', Courier, monospace]2 rows IN SET (0.00 sec) [/font]



This way it works fine.
Interesting enough first time I tried it I made a mistake of not defining column as NOT NULL for the merge table:
"create table tx (id int unsigned, key(id)) type=merge union(t1,t2)" If you create table this way it structure will be in fact different from underlying tables as PRIMARY KEY on the column automatically changes it to NOT NULL (which I think is bad behavior and it would better throw the error and ask to change the column type instead).
There is in fact the note about converting primary key to the key in MySQL manual
Here is what it says:
Note that the a column is indexed as a PRIMARY KEY in the underlying MyISAM tables, but not in the MERGE table. There it is indexed but not as a PRIMARY KEY because a MERGE table cannot enforce uniqueness over the set of underlying tables.
This however only speaks about enforcing uniqueness it does not tell anything about wrong results you may get.


Merge Tables Gotcha - Read More...
  
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Similar Threads for: Merge Tables Gotcha
Thread Thread Starter Forum Replies Last Post
Felix Geisendorfer's Blog: New fix for array junkies: Set::merge assembles yummy arra Affiliate Blogs Programming Help 0 04-06-2007 04:03 PM
Flickr Account Merge Drives Users Mad Affiliate Marketing News Internet Marketing Articles 0 02-01-2007 02:56 AM
COUNT(*) for Innodb Tables Affiliate Blogs Databases 0 12-01-2006 06:04 PM
Opening Tables scalability Affiliate Blogs Databases 0 11-21-2006 12:43 PM
Dynamic / Fixed Tables SEO Blogs SEO / SEM 0 11-15-2006 10:41 PM



© 2004-6 RevenueSource.com.  All rights reserved.  Do not duplicate or redistribute in any form.
This website and its logos/design are property of RevenueSource.com.  All rights reserved. vBSEO 3.2.0 RC7


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