views:

37

answers:

2

Suppose you have to build a DB tables that depicts states and their borders between each other. Let's say the States table would look like:

States: Name(PK), Size, etc...

What would be the appropriate way to define the relationships (borders) between states?

I came up with three alternatives -

  1. Defining a Borders table with primary key combined by two fields: Id(PK), StateName(PK,FK)
  2. Defining a Borders table with StateName1(PK,FK), StateName2(PK,FK)
  3. Defining a Borders table with a concatenated value of two states' names.

Some more information:

  • I am going to query the data as follows: someState.HasBorderWith(State anotherState)
  • I use EF 4.0 with POCO entities.
+2  A: 

Option 2 is the standard implementation of such a relationship. I don't understand what you mean w/ option 1, and option 3 isn't an option - it would be a nightmare to query this!

Will A
In my first option I meant to have two entries for each border while both will have same border id.
Aaron
+1: We should take turns smacking Aaron's hands with a ruler for mentioning option #3...
OMG Ponies
@Aaron - this would then permit a single border to have less or more than 2 States associated - which given your requirements is wrong. #2 is by far the best approach - but I'd consider having a separate PK on the table as Andrew suggests below (I'm not saying I _would_ have this - but I'd consider it for sure).
Will A
@OMG Ponies - agreed. That reminds me - my driving instructor from over ten years ago would smack my hand with a ruler if I screwed up - way to go to cause an accident, silly woman!
Will A
+1  A: 

Personally, I would create a table with:

 Id (PK)
 StateName1 (FK)
 StateName2 (FK)

This is basically your second option with an additional Id field (which isn't necessary, but use Id fields on almost every single table out of practice).

Andrew
OMG Ponies
I wouldn't use a separate surrogate key on a link table... and an ORM tail should not wag the database dog...
gbn
We don't do it for ORM reasons, we primarily do it because it makes foreign keys very obvious. Foreign keys would always be named <table>_id, which makes writing/understanding queries much easier (in our experience at least). Regarding duplicates - we would just add a unique constraint on state 1/2 columns.
Andrew
@gbn: Why would the ORM be the tail and the database the dog? Both are tools that serve a single purpose: to support the business function for which they were created. If my ORM means I can do that faster, more accurately and with greater flexibility for the application, then by all means let the ORM dog wag the database tail! :-)
Marjan Venema
@Marjan Venema: this has been mentioned before, bit ORMs have negative points too when they go wrong...
gbn
@gbn: ?!? But of course. Any software - including a database - has negative points when it goes wrong. D'oh. Now if software has negative points when it goes right, that would be a more interesting argument. And please - don't drag me into a ORM versus database debate, been there, done that. It's boring. I now still only object to people not wanting to have their precious database "wagged" by an ORM while that ORM has crucial business value in and of itself and as such has every right to wag the database.
Marjan Venema
@Marjan Venema: IMHO, when an ORM goes wrong, it's the database people who have to pick up the pieces. Correct db design and ORMs are incompatible quite often: which is why i said what I did.
gbn
@gbn: I understand. I guess your mileage is different from mine and you probably suffered having to pick up the pieces yourself. Just don't go blaming ORM's as such for that. In the end db people have to pick up the pieces no matter where an app goes wrong. And rather than being the culprit, I think an ORM may actually help limit developer errors as the can be used to enforce all kinds of rules and bring a lot of consistency to the way a db is accessed from an app.
Marjan Venema