tags:

views:

240

answers:

9

Classic database table design would include an tableId int index(1,1) not null which results in an auto-increment int32 id field.

However, it could be useful to give these numbers some meaning, and I wanted to know what people thought about using a Char(4) field for an table containing enumerables.

Specifically I was thinking of a User Role table which had data like;

"admn" - "Administrator"
"edit" - "Editor".

I could then reference these 'codes' in my code.

Update
It makes more sense when writing code to see User.IsInRole("admin") rather than User.IsInRole(UserRoles.Admin) where Admin is an int that needs to be updated/synchronised if you ever rebuild your database.

+3  A: 

I always tend to use a surrogate primary key in my tables. That is, a key that has no meaning in the business domain. A primary key is just an administrative piece of data that is required by the database ...

What would be the advantage of using 'admn' as primary key in this case ?

Frederik Gheysels
Surrogates are good for the app design. They keep entries loose coupled from the code.
Martin K.
it makes more sense when writing code to see User.IsInRole("admin") rather than User.IsInRole(UserRoles.Admin) where Admin is an int that needs to be updated if you ever rebuild your database.
Dead account
Primary keys are not required by databases.
paxdiablo
Pax? mhhh.. (Relational-)Databases need referencial integrity to be ACID. So there have to be foreign keys and primary keys.
Martin K.
I actually do not agree that User.IsInRole("admin") makes more sense. You can always (and you should in this case) explicitly set the values of your enum members. And primary keys that you reference in code should not rely on autonumbers of any sort.
Rashack
@Pax - they're not required - but I can hardly think of a occasion where you don't want to use them - can you name few?
Rashack
We've had minuscule tables where keys made little sense - a config table that only had 20-odd entries (that fitted within a sinle page) so there was little advantage to indexing - a full table scan was fast enough. Of course, if it ever got bigger, we would have to change it.
paxdiablo
@Martin, ACID has to do with transactions and their effects, they do not require primary keys. You can create a table fine with no primary or foreign keys. The DB transactions will still obey ACID.
paxdiablo
A database table doesn't need a PK; in strictu senso you're right.Just as much like you don't need a seat in your car in order to be able to drive it ...You need to be able to uniquely identify each row in your table, and that's just the purpose of a primary key.
Frederik Gheysels
You *don't* need a PK to uniquely identify a row in your table. It may be a good idea but it's not required. One example: if all you ever do is <UPDATE tbl SET VAL = 'yyy' WHERE KEY = 'xxx'> on a 20-row table, then a primary key is not required.
paxdiablo
We're quibbling about semantics here. I agree with you all that table should have PKs but the assertion was that they were required to have them - this is wrong.
paxdiablo
Sorry, ACID is really only about transactions. I only wanted to say that the consistence of the database can get broken if you don't use referencial integrity.
Martin K.
Pax: It sounds like the table you're describing *does* have a PK, at least in the relational sense. Whether you want it marked as such in the DBMS is another matter. IME, the only tables that don't have true PKs are ones with duplicate rows (usually used with aggregate functions).
kquinn
A: 

Hard code => database references are always a bad idea! (Except you set them before application start etc.)

Beside this: Should mappings from admn=>administrator really be done in the database?

And you can only store 23^4-(keywords) entries with a varchar4 with a LATIN 23char alphabet.

Martin K.
At some point, "hardcoded" entries must be in the application. Otherwise, there's no connection between app and DB.
paxdiablo
The connection can me made transparent, following conventions. Have a look at SpringSecurity/Acegi. The "connections" are loose coupled (surrogate keys => mapping entries). How the app register something depends on the convention.
Martin K.
+4  A: 

An id field (not associated with the data) is called a surrogate key. They have their advantages and disadvantages. You can see a list of those on this Wikipedia article. Personally I feel that people overuse them and have forgotten (or have never learned) how to properly normalise a database structure.

Mladen Mihajlovic
Denormalisation can be a well design pattern. In the "real world" there are issues like versioning/archiving. If you know what you do, redundancy haven't to be a bad thing. Look at the Star-Schema (Business Intelligence), it's common used and heavy denormalized.
Martin K.
+1  A: 

A primary key is better if it's never going to change. You can change a primary key as long as you update all references to it but it's a bit of a pain.

Sometimes there's no natural non-changing column in a table and, in that case, a surrogate is useful.

But, if you have a natural non-changing value (like an employee ID that's never recycled or a set of roles that you never expect to change), it's better to use that.

Otherwise, you're introducing complexity to cater for something with a minuscule chance of happening.

That's only my opinion, my name isn't Codd or Date, so don't take this as gospel.

paxdiablo
+4  A: 

No. No, no, no, no, and no.

Keys are not data. Keys do not have meaning. That way when meaning changes, keys do not change.

Keys do not have encoded meaning. Encoded meaning is not even potentially possibly maybe useful unless you have an algorithm for decoding it.

Since there's no way to get from "admn" to "Aministrator" without a lookup, and since the real meaning, "Administrator" sits right next to the SEKRET ENKODED "useful" key, why would I ever look at the key instead of the real data right next to it in the table?

If you want an abbreviated form, an enum-like name, or what have you, then call it that and realize it's data. That's perfectly acceptable. create table( id int not null primary key, abbv char(4), name varchar(64));

But it's not a key, it doesn't hash like a integer key, it takes up four character compares and a look for the null terminator to compare it to "edtr", as opposed to one subtraction to compare two integers. There's no decent way to generate a next key: what's next in the sequence ('admn', 'edtr', ?)?

So you've lost generate-ability, easy comparison, possibly size (if you could have used, day, a tinyint as your key), and all for an arbitrary value that's of no real use.

Use a synthetic key. If you really need an abbreviation, make that an attribute column.

tpdi
+1 thanks, id / code / description makes more sense
Dead account
No problem. Sorry to sound so acerbic. ;)
tpdi
+1  A: 

I think the answer is in your post. Your example of User.IsInRole("admin") will always return false as you have a primary key of char(4) and used "admn" as key for the administrator.

I would go for a surrogate Primary key which will never ever change and have the option for a 'functional primary key' to query certain roles which are used hardcoded in the code.

Janco
+1... ha ha! well spotted
Dead account
+1  A: 

A key should preferrably not have any special meaning in itself. Conditions tend to change, so you may have to change a key if it's meaning changes, and changing keys is not something that you want to do.

Also, when the amount of information that you can put in the key is so limited, it's not much point of having it there.

Guffa
+1  A: 

You are comparing auto-increment vs. the fixed char key, but in that scenario you don't want an auto-incremented id.

There are different routes to go. One is to use an enum, that maps to int ids. These are not auto incremented and are the primary key of the table.

eglasius
A: 

If you use a non-related number as primary key it's called Surrogate key and a class of person believe it's the best practice.

http://en.wikipedia.org/wiki/Surrogate_key

If you use "admn" as primary key then it's called Natural key and a different class of developers believe it's the best practice.

http://en.wikipedia.org/wiki/Surrogate_key

Both of them are never going to agree. It's a age old religious war (Surrogate Key vs Natural key). Therefore use what you are most comfortable with. Just know that there are a many that supports your view for everyone that disagrees --- no matter which one you chose.

CDR