Keeping development and production databases in synch
We're getting ready to put the app I developed into production and we're facing an interesting issue. This app is designed to be a simple interface for mapping an "attribute value" from one system to another system. Currently, we do this with SQL in our dev database, and then copy these tables' data to production when we deploy.
However, with this application, we now have the ability to push out the "mapping responsibility" to our users. The problem is that if our users enter the data in production, we have to figure out a way to synch between dev and prod. We constantly need to enter our own mappings in while we're developing - so there's always going to be data entered in both dev and prod databases.
Is it possible to share the same sequence tables b/w Oracle instances and use triggers to do a second insert into dev when someone does something in prod (or vise versa)? I suppose a manual solution is possible - where we make sure and enter values into prod when we enter them into dev, but that's just ugly.
Update: TheServerSide has additional coverage of this topic.
Posted by Ryan on May 03, 2005 at 09:10 PM MDT #
Posted by David Carter on May 03, 2005 at 09:26 PM MDT #
We used to have a user.id for the primary key, but then it was impossible to use Hibernate's one-to-many to link user to role in the user_role table. This was when we were using CMA and had little control of the SQL query.
I'm sure it could be refactored now that we're using Acegi Security. But if it ain't broken - why fix it? ;-) Using the username as the primary key makes it easier to integrate with LDAP.
Posted by Matt Raible on May 03, 2005 at 09:37 PM MDT #
Hibernate should also transparently handle the one-to-many (or isn't it many-to-many?) between users & roles, even using surrogate keys.
I understand the CMA integration issues, but as you say, that should no longer be an issue when using Acegi. Maybe this question could be revisited once people get comfortable with the CMA/Acegi change? I look at Appfuse as a repository for best practices, and it seems that surrogate keys are the recommendation I keep seeing put forth as a best practice. Admittedly, it's not a very big deal with simple classes like user & role, but it can get to be a much bigger deal with more complex classes, where composite business keys would need to be used in the absence of a surrogate key.
Posted by David Carter on May 03, 2005 at 10:54 PM MDT #
Posted by J-High on May 04, 2005 at 01:57 AM MDT #
Posted by Gilberto on May 04, 2005 at 11:38 AM MDT #
Posted by greg akins on May 04, 2005 at 11:58 AM MDT #
Posted by v.kvassov on May 04, 2005 at 01:25 PM MDT #
Posted by Radu-A. Popescu on May 05, 2005 at 07:24 AM MDT #
1. specify the the static part of the data.
2. create a holding area for the static data both in the database and on file. (therefore you can put it under source control, cvs/sourcesafe/subversion what ever tickles your fancy) 3. specify/establish the rules for transformation.
4. load the static data from file in your holding table.
5. transform your static data into final data.
Posted by m.dankoor on May 05, 2005 at 08:39 AM MDT #
Posted by Thomas Van de Velde on May 05, 2005 at 01:46 PM MDT #
Posted by Matt Raible on May 05, 2005 at 01:50 PM MDT #
We had a similar issue many years ago at a startup; we had personalization and rules information that could be entered by business users in production or the prerelease environment, and both needed to be kept in sync. The original solution was to use a set of triggers that copied the changes into a q table, but this was somewhat unreliable and ugly. The real key is to create a third repository that is the master, and make production and the test environments slaves to the master. Whenever a change needs to be made, it is entered into the master (usually located in the production environment), and it flows out via the async method of your choice to the all of the slave databases. Oracle has some built in facilities for replicating tables, although I think our version simply opened a db connection to the remote system and ran the update.
The upshot of that whole experience is that I never try and replicate between databases - I've always since managed to find a simpler solution :)
Of course, if you just have a few occasional changes, take a look at http://uptodater.sf.net.
Posted by Andy Pruitt on May 06, 2005 at 05:59 AM MDT #
You can enforce uniqueness with a unique index you don't have to have a primary key. The database will still do all the work for you, albeit a slight different error message.
One reason to not use user names as a primary key, for example, is they have a nasty habit of changing (marrige/divorce come to mind). Cascading a primary key change to child tables can sometimes be tricky depending on how much referential integrity you've built in. Regardless some code will need to be introduced to ensure the key change is cascaded properly so you don't end up with orphans. Clearly this is prone to errors as the complexity increases.
Posted by David on May 12, 2005 at 05:48 AM MDT #