I would suggest a completely different approach, completely getting rid of the storage problem, and should make your application more efficient. Storing serialized arrays, full of information that can be extracted from your database, is in any case redundant and extremely inefficient. The best approach here is to normalize your data.
You should create a fourth table, possibly called " region_categories ", which will be a simple lookup table:
CREATE TABLE region_categories ( regionId int unsigned not null, categoryId int unsigned not null, PRIMARY KEY(regionId,categoryId) );
Now, instead of saving everything to an array, for each city / region you need to instead populate this table with the categories that are in that city. The data size is very small, since all you store is a pair of identifiers.
When the time comes to get categories for a given region, you just need to run a simple SELECT :
SELECT category.* FROM region_categories AS rc LEFT JOIN categories AS c ON rc.categoryId=c.categoryId WHERE rc.regionId=[whatever region you're dealing with]
Now you can repeat the results and you will have all the categories for this region.
source share