views:

72

answers:

4

I have an MS Access database with plenty of data. It's used by an application me and my team are developing. However, we've never added any foreign keys to this database because we could control relations from the code itself. Never had any problems with this, probably never will either.

However, as development has developed further, I fear there's a risk of losing sight over all the relationships between the 30+ tables, even though we use well-normalized data. So it would be a good idea go get at least the relations between the tables documented.

Altova has created DatabaseSpy which can show the structure of a database but without the relations, there isn't much to display. I could still use to add relations to it all but I don't want to modify the database itself.

Is there any software that can analyse a database by it's structures and data and then do a best-guess about it's relations? (Just as documentation, not to modify the database.)


This application was created more than 10 years ago and has over 3000 paying customers who all use it. It's actually document-based, using an XML document for it's internal storage. The database is just used as storage and a single import/export routine converts it back and to XML. Unfortunately, the XML structure isn't very practical to use for documentation and there's a second layer around this XML document to expose it as an object model. This object model is far from perfect too, but that's what 10 years of development can do to an application. We do want to improve it but this takes time and we can't disappoint the current users by delaying new updates.
Basically, we're stuck with it's current design and to improve it, we need to make sure things are well-documented. That's what I'm working on now.

A: 

There might be a tool out there that might be able to "guess" the relations but I doubt it. Frankly I am scared of databases without proper foreign keys in particular and multi user apps that uses Access as a DBMS as well. I guess that the app must be some sort of internal tool, otherwise I would suggest that you move to a proper DBMS ( SQL Express is for free) and adds the foreign keys.

Kasper
Actually, it's a commercial product with a 3000+ user base. :-) Then again, it's not uncommon for applications to use Access as database since it's easy to use. (Enterprise Architect, the UML tool, also uses Access for it's models!) You are right, databases without relations are scary but they are maintained well enough. We are considering better options but right now we still need to maintain this application that's already used for more than 10 years...
Workshop Alex
Well, since this is brown field it might be kind of tricky to replace the database, but it should still be doable. Then again, if the DAL is nice and clean the ROI on replacing the DB might be to low
Kasper
Replacing the DB isn't an issue. We're going to replace it by a document model, where the DB won't even exist. We're already using an in-memory XML document and we're going to use this to export data to XML so users will select a file instead a record from a database. This solves quite a few problems. But before we do this, we just want to have a good view of the current database structure. We can do this without a tool but a good tool might save us some time.
Workshop Alex
What does not having foreign keys have to do with replacing Access as a backend?
Tony Toews
Tony, nothing as such but in this case both issues are present
Kasper
Kasper, what issues are present in this thread that require moving to a SQL Server Express or similar?
Tony Toews
Kasper, there are no issues except the lack of documentation. The application is doing great, is very robust and reliable and is extremely well-tested. And we're considering to move to a document-based design where data isn't stored inside a database anymore, just a structured, encrypted XML file. To do this, it's helpful if we've some documentation of the structure, though. Especially the relations between data.
Workshop Alex
+1  A: 

If your database does not have relationships defined somewhere other than code, there is no real way to guess how tables relate to each other.
Worse, you can't know the type of relationship and whether cascading of update and deletion should occur or not.

Having said that, if you followed some strict rules for naming your foreign key fields, then it could be possible to reconstruct the structure of the relationships.

For instance, I use a scheme like this one:

Table Product
- Field ID          /* The Unique ID for a Product */
- Field Designation
- Field Cost

Table Order
- Field ID          /* the unique ID for an Order */
- Field ProductID
- Field Quantity

The relationship is easy to detect when looking at the Order: Order.ProductID is related to Product.ID and this can easily be ascertain from code, going through each field.

If you have a similar scheme, then how much you can get out of it depends on how well you follow your own convention, but it could go to 100% accuracy although you're probably have some exceptions (that you can build-in your code or, better, look-up somewhere).

The other solution is if each of your table's unique ID is following a different numbering scheme.
Say your Order.ID is in fact following a scheme like OR001, OR002, etc and Product.ID follows PD001, PD002, etc.
In that case, going through all fields in all tables, you can search for FK records that match each PK.

If you're following a sane convention for naming your fields and tables, then you can probably automate the discovery of the relations between them, store that in a table and manually go through to make corrections.
Once you're done, use that result table to actually build the relationships from code using the Database.CreateRelation() method (look up the Access documentation, there is sample code for it).

Renaud Bompuis
For another slightly more elaborate naming convention see Tony's Table and Field Naming Conventions http://www.granite.ab.ca/access/tablefieldnaming.htm
Tony Toews
Fortunately, we did use a strict naming scheme, with only two or three exceptions. :-) It's just that we don't want to modify the database to document those relations. We're actually trying to move away from a database model and towards a document model. The database model was chosen 10 years ago as solution and it turns out to be too restrictive.
Workshop Alex
@Tony Toews: be fair: post your self-confessed unpopular naming convention as a separate answer so that we can down-vote it.
onedaywhen
+2  A: 

Only 30+ tables? Shouldn't take but a half hour or an hour to create all the relationships required. Which I'd urge you to do. Yes, I know that you state your code checks for those. But what if you've missed some? What if there are indeed orphaned records? How are you going to know? Or do you have bullet proof routines which go through all your tables looking for all these problems?

Use a largish 23" LCD monitor and have at it.

Tony Toews
At home, I use two monitors, one 24 inch and the other 25.5 inch. :-) And indeed, modifying the database by adding relations should not bee too much work. But what if I don't want to modify the database? All I'm thinking of is a simple tool that reads the database structure, which can guess about 75% of all relationships and then allows the user to add/modify and delete those relations without modifying the database? Just for documentation? No one ever made such a tool?
Workshop Alex
@Tony Toews: Don't you mean, "Should take but a half hour or an hour..."?
onedaywhen
Alex. Why would anyone make such a tool as to guess relationships? Anyone who designs databases should be creating relationships. Period. Also make the relationships diagram in a test copy of the database. And that's your documentation. Print it off on a plotter. (The relationships diagram of one of my systems was 4' wide and 3' tall so we had to use a plotter for it.)
Tony Toews
@Tony, such a tool would be real useful for developers who take over existing projects, like in my case. It's a project that is in use for over 10 years but in the past, no one bothered to write a single line of documentation! Bad design, of course. Which is why the original developers received a kick in the ass and new developers have been given the task to do more improvements. This is much more common that you'd expect so I wondered if someone has created a tool for this already. Apparently not.
Workshop Alex
I do agree that if the developer doesn't create relationships they're idiots. However usually such systems are badly designed and clumsy to use. Thus these systems are treated as a prototype and thrown out in favour of a system redesign and rewrite
Tony Toews
In the end, this was what I did. :-)
Workshop Alex
2Tony, the application doesn't use relations in the DB itself simply because the developers from the past had lots of problems maintaining the database integrity. Nowadays, we just extract data inside an XML document, work with the XML and then write the data back to the multiple tables. The integrity is handled inside the XML and a bit complex import/export routine that works, so it's not going to be fixed. (But we just want to get rid of the database and store data in just the XML.)
Workshop Alex
@Tony Toews: "Also make the relationships diagram in a test copy of the database. And that's your documentation." -- if only implementation = design. Do you get a spec as a picture, do the coding, print it out then hold them up to the light to test for bugs?!
onedaywhen
@Alex Above you state "However, we've never added any foreign keys to this database because we could control relations from the code itself." then here you state "lots of problems maintaining the database integrity." Well, that's clearly contradictory but that's life I guess.
Tony Toews
+1  A: 

You can build a small piece of VBA code, divided in 2 parts:

  1. Step 1 implements the database relations with the database.createrelation method
  2. Step 2 deleted all created relations with the database.delete command

As Tony said, 30 tables are not that much, and the script should be easy to set. Once this set, stop the process after step 1, run the access documenter (tools\analyse\documenter) to get your documentation ready, launch step 2. Your database will then be unchanged and your documentation ready.

I advise you to keep this code and run it regularly against your database to check that your relational model sticks to the data.

Philippe Grondier
Actually what you could do is create the relationships. Then use the following utility which compares two databases and creates VBA code to upgrade the one database to the other. I use it all the time. Compare'Emhttp://home.gci.net/~mike-noel/CompareEM-LITE/CompareEMscreens/CompareEM-About.htm
Tony Toews