Is it acceptable to have 2 one to many relationships between 2 tables? - sql

I have a database for utility structures (poles, towers) with wire between them. Each span of wire is connected to two structures. I need to define the relationship between the structures and the spans.
I came up with a relationship between structure A to a "from" foreign key field in the span table and another between structure B and a "To" foreign key field in the span table. Is this acceptable database design?
Here's a diagram:

Your model indicates that a span is related to exactly 2 structures. So I think you're good, there. My only comment is that with the names, "fkFromStructureID" and, "fkToStructureID" you imply an orientation that may not exist. It's nit-picky, I admit. But if you do not have a concept of "direction" in your real-world model, you might want to consider different names. If orientation does exist, then this works fine.
Note: If you plan to be able to "walk" the chain of spans and structures using these FK fields, then you'll want to be certain that you manage your orientation on the way into the database. One span that has the From and To backwards will ruin the ability to walk the chain.

Yes, this is quite a common requirement when designing databases and your approach is probably the best way of fulfilling this requirement.

Related

Database table, Should all tables require a foreign key from the user table without over normalising

I am trying to design a database for a garage management system. And I am struggling with over normalising, Would it be best to have User_ID as a foreign key within all tables to make querying faster or does this design make sense?
Any help is appreciated
As for ORM, your design is absolutely correct. There is no redundancy and data is easily reached by transitivity. Nevertheless, sometimes, development urges for simplification and better performance. Performance must prevail over design.
I would not recommend adding user_id to the other tables. That just seems like a maintenance nightmare -- ensuring that the user_id is consistent across the tables.
Instead, you might want to borrow a technique which is associated with dimensional modeling (which is described in Wikipedia). That is flattening dimensions.
This means that you would have one table apart from users at the most detailed level. All the information about spaces, zones, boxes, and items would be in the same table.
This works assuming that the dimension values do not really change over time -- think time dimensions or geographic dimensions.

What is the problem with many-to-many relationships?

I feel like I have searched through the internet to find an answer to this question for quite some time now, but without success. Does anyone feel comfortable explaining why many-to-many relationships should be replaced with a bridge table?
Probably most (all??) RDMS implement a M:N relationship by creating a table containing two columns with the FKs.
So there is no advantage to explicitely model the bridge table.
But in most realistic cases you want to store additional information (besides the fact of its existence) about the relationship instance, e.g. timestamp and user from the creation. That means that you need to model the bridge table anyway.

How many foreign keys is too many?

After running across this article:
http://diovo.com/2008/08/are-foreign-keys-really-necessary-in-a-database-design/
It seems like a good idea to use foreign keys when designing a database. But when are you using too many?
For example, suppose I have a main table used to store a list of machinery part information that other programs make reference to with the following columns:
ID
Name
Colour
Price
Measurement Units
Category
etc...
Should I be making tables containing a list of all possible colours, units and categories and then setting these as foreign keys to the corresponding columns in my machine part info table? At what point would the benefit of using foreign keys out weight the fact that I'm making all these extra tables and relationships?
Any attribute for which you want to be able to state, with certainty, that there are only known, valid values present in the database should be protected with a foreign key. Otherwise, you can only hope to catch invalid values in your application code and whatever interfaces are created in the future.
It is NOT a bad thing to have more tables and relationships. The only issue -- and it usually is not one -- has to do with the overhead of maintaining the indexes that are used in enforcing those relationships. Until you experience performance issues you should create a foreign key relationship for every column that "should" have one (because the values need to be validated against a list).
The performance considerations would have to be pretty dire before I would be willing to sacrifice correctness for performance.
Every Design is a compromise of competing goals, so there are very few simple answers (except the wrong ones).
I would certainly put discrete measures such as name, color, category, measure unit, etc.. in their own key tables. Variable measures (cost, number of units ,etc..) not so much, unless you have units in standard size packages (i.e. only 1, 6, 12, etc..)
The simplest way to design a database is to start with the requirements. In one classical methodology, the requirements are summarized in an ER (Entity-Relationship) model. In this model, relationships between entities are not invented, they are discovered. If they lie within the scope of the information the database is supposed to cover, then they are part of the model. Period.
From there, when you turn to database design, you already know what relationships you need. You have a few decisions to make about the structure of your tables, but almost all the foreign keys that reference a primary key are a direct consequence of the requirements.
Of course, if you are at liberty to change the requirements as you go through the design process, then you can do anything you want.
Dimensional modelling covers all points of your question well. Having too many foreign key relationships can make query performance suffer. Kimball's Group Reader is a great introduction to Dimensional Design and how to translate customer requirements to a schema.
http://en.wikipedia.org/wiki/Dimensional_modeling
The main question to ask is 'how constrained does the data need to be?' Concerning the color of machine parts, I'd assume, it would be in everyone's best interest not to have burnt ciena and camomille as color options. So, a look up table for these would be best.

Refactor schema with multiple many-to-many relationships to semantically different but structurally similar entities?

I have a schema with a number of many to many relationships and what I'm seeing is a alot of similar data structure spread out among tables with different names. The intuition I have is that there is a more efficient/desirable way to achieve the same result but I'm not sure what alternative approaches fall into reasonable design/best practices.
Note: Counries, TrafficTypes and People - as they exist now - could all be represented by Id and Name columns, but in the future may have additional fields. Maybe what I'm after is some kind of technique akin to inheritance?
Here's the diagram of what I've got:
Don't lump together things which you think are similar; they may diverge later when you need to store more information about each entity.
Is there a problem with the number of tables you have in your database?
You are probably thinking about the problem from an object oriented design position and thinking you can use some sort of "parent" table to represent the common parts - databases don't work that way.
If you are not careful you will end up with a MUCK or OTLT table.
Off the bat, I would keep seperate enties/objects/(cars vs animals) in seperate tables.
The chances of such enties overlapping properties are slim at best.
Thing is, once those entites start to evolve in your system, you will find that a single table will have hundreds of columns with singles populated per entity.
I don't see how inheritance applies to your case. But if you are interested in inheritance, as it applies to SQL tables or relations, here are some things to look up:
At the level of ER modeling look up "ER model specialization". This is the way the extended ER model diagrams "is A" relationships.
At the level of table design, look up "Class Table Inheritance" and "Shared primary key" for a couple of techniques that, used together, sort of mimic what inheritance does for you in an OOP. You might also want to look up "single table inheritance" for an alternative that's simpler, but can be more wasteful.
Don't worry. You're doing it right.
In a highly normalized schema, you're going to have tons of tables that are nearly identical.
As the others have said, what you're starting to consider (a generic table for multiple things) is a very bad idea and has many drawbacks.
The biggest drawback is that your relationships are made useless by it, in terms of maintaining data integrity. There's nothing stopping someone from assigning a CountryCode where a TrafficTypeId should be, and so on.
Another drawback would be that having one larger table will likely perform worse than many smaller, specialized tables; due to extra, unnecessary blocking.
Your may still want to implement some type of inheritance concept, but that'll be best done in whatever code accesses the database.

How to handle column growth of wide, flat tables

How would you DBA's handle this? I have taken ownership of an existing app (VB6) and database that was written in 1999. The database design is fairly 'flat', meaning the main tables are fairly wide (100+ columns) and developers have continued to tack on additional columns to the end of the tables. This has resulted in columns that have a lot of Nulls since they don't directly relate to the primary key.
I am considering splitting the main table out as a way to abstract myself from the years and years of 'column explosion'. I am certain that new fields will continue to be added as new requirements come up.
So the question is, as new fields are needed, do you continue to grow the width of the existing table? Or do you STOP extending an existing table and split it out into a separate supporting table that will house new fields, thereby creating a 1-to-1 relationship? If you were to split the main table, what would your naming scheme be?
Let's assume for this example I have a table called 'Foreclosure' with 150 fields.
What is a good name for the new 1-to-1 table? 'ForeclosureExtended'? ForeclosureOtherInfo'?
By the way, there are Views and Stored Procs that will need to be modified to support any new tables, but that is inevitable anyway when columns are added.
thanks in advance for any thoughts.
80% of the time, your nulls have definite patterns.
These patterns define subclasses of your table. In your case, they will be subclasses of Foreclosure.
Your splitting should be based on these subclass relationships.
Say, for example, some Foreclosure instances have a bunch of fields related to legal proceeding that are nearly all filled in. And other Foreclosure instances have the legal proceeding fields entirely filled with nulls.
You have two classes. You need to work out the relationship between them -- are they superclass-subclass or are they peer subclasses of some other superclass?
This tells you how to partition your table to make useful stuff happen.
You may have proper superclass subclass relationships
You may have found a thing (a LegalProceeding) which should have been a separate table all along. It should not have been permanently joined into Foreclosure. This is remarkably common.
You now have some relational implementation choices.
One common choice is to put all subclasses into a single, massive table with a lot of nulls. This is what you have today, and it isn't working.
One choice is to split the two subclass relationship tables into peers, duplicating the common information.
One choice is to have a superclass table with an optional FK reference to the additional information in the subclass.
One choice is to have a subclass table with a mandatory FK reference to the superclass information.
Unless you are really brave, app is very small/simple, or there are major performance issues do not fix the schema. If it ain't broke, don't fix it.
Just create a new table ForeclosureExtended, as you suggest with the same key and start adding columns. Or, you could make proper tables with grouped columns as new columns appear. Either way, if the schema is this bad, I'll bet the code is very fragile.
Why do you feel that you have a problem? To my mind it's easier to deal with one table that has a lot of columns than it is to deal with a ton of narrower tables and all the associated views you have to maintain.