views:

197

answers:

2

Hi all,

There're a few entities that we wish to hide its exact ID from the customers - the main reason is that, we do not want customers to know how many of them are in the DB.

e.g. from the URL, http://mydomain/user/get/27, it says that this is the 27th user.

Therefore, I am implementing a solution that assigns random ID (that has to be unique). In another words, instead of using unique sequence number, am going for an unique non-sequence+randomize number solution.

e.g. from the URL, http://mydomain/user/get/8534023, which is actually the 27th user.

My question here is, knowing that some users here may have experience on the similar problem, shall I use a map or assign the random ID to the primary key column?

e.g.

CREATE TABLE IF NOT EXISTS `test` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `somethingElse` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
)

CREATE TABLE IF NOT EXISTS `map` (
  `id` int(10) unsigned NOT NULL,
  /* Foreign Key to test table */
  `parent` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `parent` (`parent`)
)

VS.

CREATE TABLE IF NOT EXISTS `test` (
  /* Assign random ID here */
  `id` int(10) unsigned NOT NULL,
  `somethingElse` varchar(255) NOT NULL
  PRIMARY KEY (`id`)
)

To me, the latter comes to be more handy, as I do not have to maintain a map, nor I have to customize the DAO/application to use the mapped ID (or the exact ID internally). For both case, I have to write my own random ID generator.

+2  A: 

Why don't you just set your increment seed start value to something like 8534023? Your first customer is 8534023, your second customer is 8534024 etc. Your customers will never know what this means but you will.

Randy Minder
+1 nice solution!
jspcal
Migration between databases risks different key values - having a surrogate key would insulate the user from ever knowing the change took place.
OMG Ponies
But still sequential; so you're still leaking chronology information.
lhunath
+2  A: 

You are correct - the latter is the better approach. It is a one-to-one relationship - there's no reason to have a separate table. I recommend having:

  • an index on the "fake" user_id, as it will be used for lookups
  • A UNIQUE constraint on the column, to ensure that duplicate values are not inserted

Your concern is also valid to not expose actual primary key values. It ensures that if the database changed, and the actual primary key value changed - the user would have no knowledge of the change.

OMG Ponies
+1 And it's definitely a best practice to have a "functional" key.
Pascal Thivent