views:

96

answers:

3

I am working on an application where users 'fight' to own larger parts of the map. Each map is made of a 1000 regions. Now my initial plan was to store the areas a user owns as a comma separated string e.g

a user owns regions one to ten 1,2,3,4,5,6,7,8,9,10

Problem is a user could potentially own all 1000 which means it could be a string 3893 characters long... I stored it as a varchar(3893)... which seems horribly inefficient.

I did consider a binary solution e.g

1111111111 followed by 990 0's

Which is a good solution if only one user owns the whole grid as that's 1000 characters but if its 4 or more then its less efficient.

Also I need to consider a way that is easy to compute back to a comma separated string as that is how my javascript will use it.

Thanks,

+2  A: 

Why not to store Ids of user-owned regions in a separate table? UserID|OwningLandPlotID

You can then select them all and implode() in PHP to produce comma separated string. What server environment do you have?

FractalizeR
yes, PHP - thanks
Mark
+8  A: 

Why not normalize your table? Have a table that simply matches pairs of numbers - one the ID of a player, the other the ID of a region. If a player controls 5 regions, they'll have 5 rows in the table. If they control 1000, they have 1000 rows. That's how relational databases are designed and optimized to work.

Example:

table `users`:

ID  Name
------------
1   John
2   Jessie
3   James

table `regions`:

ID  Name
------------
1   France
2   China
3   Australia

table `ownership`:

Owner  Place
------------
1      1
1      3
3      2

Thus, John currently owns France and Australia, and James owns China.

Not only does this simplify your column types, but since it's normalized, you have much more flexibility in the kinds of queries you can run - for instance, you can ask "what's the name of the person who owns region X" or "how many territories does person Y own" without ever having to actually manually parse anything yourself - the DB can do that processing for you.

Amber
Thanks for your thorough answer. As I have many maps I guess I just need to add map id to the ownership table.. right?
Mark
Yep. Or you could simply have the region ID be unique across all maps, but having a separate map id makes it easier to run queries about particular maps or the regions within them, so I'd say a map id is the way to go.
Amber
+1  A: 

would it not be better to have a user -> region mapping table?

eg

CREATE TABLE `usertoregion` (
  `iUser` int(11),
  `iRegion` int(11)
);

You can then easily get a list back and quickly find which users own which regions etc.

rikh
I like this solution... I am just worried that too many joins might make it slow. What's your take on normalization vs denormalization. Some people seem to be pro one, some the other
Mark
joins for what? so far I've not seen anything in this problem that requires joins.
Amber
Let the database do what it was designed for - relate data. As for performance considerations - first go for the simplest possible approach (which is a mapping table) and only when that is *proven* to be too slow for your purposes, look for alternatives. This is not a problem complicated enough to make me worry at all, however.
Daniel Schneller