<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Agile DBA</title>
    <link rel="alternate" type="text/html" href="http://www.sadalage.com/" />
    <link rel="self" type="application/atom+xml" href="http://www.sadalage.com/atom.xml" />
   <id>tag:www.sadalage.com,2008://2</id>
    <link rel="service.post" type="application/atom+xml" href="http://www.sadalage.com/cgi-bin/mt/mt-atom.cgi/weblog/blog_id=2" title="Agile DBA" />
    <updated>2008-10-24T21:28:34Z</updated>
    <subtitle>My thoughts on evolutionary design in regards to databases. Database administration. Best Pratices, Database utilities and other things</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type 3.2</generator>
 

<entry>
    <title>Hibernate weirdness with property names</title>
    <link rel="alternate" type="text/html" href="http://www.sadalage.com/2008/10/hibernate_weirdness_with_prope.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.sadalage.com/cgi-bin/mt/mt-atom.cgi/weblog/blog_id=2/entry_id=48" title="Hibernate weirdness with property names" />
    <id>tag:www.sadalage.com,2008://2.48</id>
    
    <published>2008-10-24T21:21:40Z</published>
    <updated>2008-10-24T21:28:34Z</updated>
    
    <summary>Consider this Hibernate mapping @Column(name = &quot;qReferenceId&quot;) public Long getQReferenceId() { return qReferenceId; } Where qReferenceId is data provided to our application via a external reference, we do not have a QReference Object or Table for FK references.When trying to...</summary>
    <author>
        <name>Pramod Sadalage</name>
        
    </author>
    
        <category term="Open Source" />
    
    <content type="html" xml:lang="en" xml:base="http://www.sadalage.com/">
        <![CDATA[<p>Consider this Hibernate mapping </p>

<pre class="codeexample">
@Column(name = "qReferenceId")
public Long getQReferenceId() {
return qReferenceId;
}
</pre>

<p>Where <strong>qReferenceId</strong> is data provided to our application via a external reference, we do not have a QReference Object or Table for FK references.When trying to query this object using DetachedQuery, this Simple expression was used.</p>

<pre class="codeexample">
public List<Movie> findByQReferenceId(Long id) {
     final SimpleExpression matchesId = Property.forName("qReferenceId").eq(id);
    DetachedCriteria criteria = DetachedCriteria.forClass(Movie.class);
    criteria = criteria.add(matchesId);
    List<Movie> movies = (List<Movie>) getHibernateTemplate().findByCriteria(criteria);
    return movies;
}
</pre>

<p>When running this method, I kept getting errors shown below.<br />
<pre class="codeexample"><br />
could not resolve property: qReferenceId of: com.example.Movie; <br />
nested exception is org.hibernate.QueryException: could not resolve property: qReferenceId of: com.example.Movie<br />
....<br />
....<br />
</pre></p>

<p>I thought I had a spelling mistake on the property name and also tried many other combinations. Finally I said why not use "QReferenceId" and suddenly everything was hunky dory, this kind of weirdness does not happen when working with property names that do not have consecutive double uppercase characters in the getter/setter for the property. very interesting. So this method worked</p>

<pre class="codeexample">
public List<Movie> findByQReferenceId(Long id) {
    final SimpleExpression matchesId = Property.forName("QReferenceId").eq(id);
    DetachedCriteria criteria = DetachedCriteria.forClass(Movie.class);
    criteria = criteria.add(matchesId);
    List<Movie> movies = (List<Movie>) getHibernateTemplate().findByCriteria(criteria);
    return movies;
}
</pre>]]>
        
    </content>
</entry>

<entry>
    <title>Using Explicit Order By in your SQL Statements</title>
    <link rel="alternate" type="text/html" href="http://www.sadalage.com/2008/09/using_explicit_order_by_in_you.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.sadalage.com/cgi-bin/mt/mt-atom.cgi/weblog/blog_id=2/entry_id=47" title="Using Explicit Order By in your SQL Statements" />
    <id>tag:www.sadalage.com,2008://2.47</id>
    
    <published>2008-09-30T19:10:34Z</published>
    <updated>2008-10-01T00:55:58Z</updated>
    
    <summary>Recently when our test databases where upgraded new version of Oracle, we started noticing that the order in which some drop down lists were being displayed was not correct. It turns out that the SELECT statement we had, did not...</summary>
    <author>
        <name>Pramod Sadalage</name>
        
    </author>
    
        <category term="Best Practices" />
    
    <content type="html" xml:lang="en" xml:base="http://www.sadalage.com/">
        <![CDATA[<p>Recently when our test databases where upgraded new version of Oracle, we started noticing that the order in which some drop down lists were being displayed was not correct. It turns out that the SELECT statement we had, did not have a ORDER BY clause and the data was being returned in the ORDER of the creation of rows (in the order of ROWID) when the database was upgraded these ROWID's got changed and hence the ORDER of the data being shown in the drop down lists.</p>

<p>Lesson learnt: <strong>have a EXPLICIT ORDER BY in every SQL that provides data to be shown on the screen.</strong> In other words do not rely on the order of the result set provided by the current version of the database server. if you prefer a certain order make that choice explicit in the SQL SELECT statement.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Moved to a Mac</title>
    <link rel="alternate" type="text/html" href="http://www.sadalage.com/2008/09/moved_to_a_mac.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.sadalage.com/cgi-bin/mt/mt-atom.cgi/weblog/blog_id=2/entry_id=46" title="Moved to a Mac" />
    <id>tag:www.sadalage.com,2008://2.46</id>
    
    <published>2008-09-01T21:08:19Z</published>
    <updated>2008-09-01T21:54:49Z</updated>
    
    <summary>Couple of weeks back I was given a choice to upgrade my work Laptop to a Mac Book Pro or a Windows Laptop. I choose Mac ( I know everyone is into macs nowadays). The transition was pretty good, with...</summary>
    <author>
        <name>Pramod Sadalage</name>
        
    </author>
    
        <category term="Learning" />
    
    <content type="html" xml:lang="en" xml:base="http://www.sadalage.com/">
        <![CDATA[<p>Couple of weeks back I was given a choice to upgrade my work Laptop to a Mac Book Pro or a Windows Laptop. I choose Mac ( I know everyone is into macs nowadays). The transition was pretty good, with the exception of moving my oracle database from windows to mac, since there is no native installation of oracle on mac I had to use VMWare fusion to install oracle.</p>

<p>After having oracle run inside the VM, I started setting up the dev environment, I ran into issues with ANT version and JAVA version but they where resolved by pointing to the right location.</p>

<p>Overall this has been a positive experience so far.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Create a Index for every Foreign Key constraint created</title>
    <link rel="alternate" type="text/html" href="http://www.sadalage.com/2008/07/create_a_index_for_every_forei.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.sadalage.com/cgi-bin/mt/mt-atom.cgi/weblog/blog_id=2/entry_id=45" title="Create a Index for every Foreign Key constraint created" />
    <id>tag:www.sadalage.com,2008://2.45</id>
    
    <published>2008-07-15T21:13:33Z</published>
    <updated>2008-07-15T22:53:00Z</updated>
    
    <summary>When creating a Foreign Key constraint on the database as shown below ALTER TABLE BOOK ADD (CONSTRAINT FK_BOOK_AUTHOR FOREIGN KEY (AUTHORID) REFERENCES AUTHOR) / In the above example we are telling the database to check if the BOOK.AUTHORID is a...</summary>
    <author>
        <name>Pramod Sadalage</name>
        
    </author>
    
        <category term="Best Practices" />
    
    <content type="html" xml:lang="en" xml:base="http://www.sadalage.com/">
        <![CDATA[<p>When creating a Foreign Key constraint on the database as shown below</p>

<pre class="codeexample">
ALTER TABLE BOOK ADD 
    (CONSTRAINT FK_BOOK_AUTHOR FOREIGN KEY (AUTHORID) 
     REFERENCES AUTHOR)
/
</pre>

<p>In the above example we are telling the database to check if the BOOK.AUTHORID is a valid value in the Author.AuthorID. When the Author table is being changed, the database does data verification on the BOOK table using SELECT against the BOOK table for the AUTHORID some thing like this</p>

<pre class="codeexample">
SELECT count(*) FROM BOOK WHERE AUTHORID = nnnn
</pre>

<p>Basically the database server is trying to check if it has children rows for the row that just changed (inserted or deleted). While doing this if there is not index on BOOK.AUTHORID, the database will have to scan the whole table which is slow. Hence when creating a Foreign Key constraint, remember to create a corresponding INDEX on the table, so that the performance does not degrade, or when observing slow performance on a database after you put in Foreign Key constraints. Make sure to look for Indexes on the columns that are constrained.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Version Control your work..</title>
    <link rel="alternate" type="text/html" href="http://www.sadalage.com/2008/06/version_control_your_work.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.sadalage.com/cgi-bin/mt/mt-atom.cgi/weblog/blog_id=2/entry_id=44" title="Version Control your work.." />
    <id>tag:www.sadalage.com,2008://2.44</id>
    
    <published>2008-06-06T20:42:45Z</published>
    <updated>2008-06-06T20:45:16Z</updated>
    
    <summary>So we version control/source control everything on our project.. code/data/artifacts/diagrams etc. yesterday I said why not extend it to my writings to everything I have. So I started this long journey of refactoring my folder layout and making a nice...</summary>
    <author>
        <name>Pramod Sadalage</name>
        
    </author>
    
        <category term="Best Practices" />
    
    <content type="html" xml:lang="en" xml:base="http://www.sadalage.com/">
        <![CDATA[<p>So we version control/source control everything on our project.. code/data/artifacts/diagrams etc. yesterday I said why not extend it to my writings to everything I have. So I started this long journey of refactoring my folder layout and making a nice folder structure to hold all the things I have written about have other artifacts in the process of writing and moved them all to subversion, now all my example code and writings are all under version control that gets backed up everyday.... feels liberating</p>]]>
        
    </content>
</entry>

<entry>
    <title>Japanese Version released</title>
    <link rel="alternate" type="text/html" href="http://www.sadalage.com/2008/06/japanese_version_released.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.sadalage.com/cgi-bin/mt/mt-atom.cgi/weblog/blog_id=2/entry_id=43" title="Japanese Version released" />
    <id>tag:www.sadalage.com,2008://2.43</id>
    
    <published>2008-06-05T04:40:44Z</published>
    <updated>2008-06-05T04:47:02Z</updated>
    
    <summary>Japanese translation of &quot;Refactoring Databases: Evolutionary Database Design&quot; has been released, thanks to Yasuo Honda for the information. The Japanese version can be found here...</summary>
    <author>
        <name>Pramod Sadalage</name>
        
    </author>
    
        <category term="Broadcast" />
    
    <content type="html" xml:lang="en" xml:base="http://www.sadalage.com/">
        <![CDATA[<p>Japanese translation of <a href="http://databaserefactoring.com/">"Refactoring Databases: Evolutionary Database Design" </a>has been released, thanks to Yasuo Honda for the information. The Japanese version can be found <a href="http://www.pej-hed.jp/washo/1804.html">here</a></p>]]>
        
    </content>
</entry>

<entry>
    <title>Tool support for Database Refactoring</title>
    <link rel="alternate" type="text/html" href="http://www.sadalage.com/2008/05/tool_support_for_database_refa.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.sadalage.com/cgi-bin/mt/mt-atom.cgi/weblog/blog_id=2/entry_id=42" title="Tool support for Database Refactoring" />
    <id>tag:www.sadalage.com,2008://2.42</id>
    
    <published>2008-05-21T05:20:15Z</published>
    <updated>2008-05-21T05:23:37Z</updated>
    
    <summary>I&apos;m always on the lookout for better tool support to do database refactoring. Just noticed that LiquiBase has come out with a IntelliJ plugin to support database refactoring. This is really cool and hopefully one of long list of tools...</summary>
    <author>
        <name>Pramod Sadalage</name>
        
    </author>
    
        <category term="Learning" />
    
    <content type="html" xml:lang="en" xml:base="http://www.sadalage.com/">
        <![CDATA[<p>I'm always on the lookout for better tool support to do database refactoring. Just noticed that <a href="http://www.liquibase.org">LiquiBase</a> has come out with a IntelliJ plugin to support database refactoring.</p>

<p>This is really cool and hopefully one of long list of tools that will support <a href="http://databaserefactoring.com/">database refactoring</a> in the future. so enjoy </p>]]>
        
    </content>
</entry>

<entry>
    <title>Writing a SQL to generate a SQL</title>
    <link rel="alternate" type="text/html" href="http://www.sadalage.com/2008/05/writing_a_sql_to_generate_a_sq.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.sadalage.com/cgi-bin/mt/mt-atom.cgi/weblog/blog_id=2/entry_id=41" title="Writing a SQL to generate a SQL" />
    <id>tag:www.sadalage.com,2008://2.41</id>
    
    <published>2008-05-06T23:23:01Z</published>
    <updated>2008-05-07T14:58:52Z</updated>
    
    <summary>We had a weird requirement on our project recently.. Find all the Rows in All the tables that do not comply with the Constraints that we have in development but not in QA environments Best way to do this we...</summary>
    <author>
        <name>Pramod Sadalage</name>
        
    </author>
    
        <category term="Learning" />
    
    <content type="html" xml:lang="en" xml:base="http://www.sadalage.com/">
        <![CDATA[<p>We had a weird requirement on our project recently..<br />
<blockquote>Find all the Rows in All the tables that do not comply with the Constraints that we have in development but not in QA environments</blockquote></p>

<p>Best way to do this we thought was to write a SQL statement against the table for each column that was going to have a Foreign Key constrained column and find out what data was not right or did not match the constraint. For example: If we have a INVOICE table that has a ITEMID on it. I want to find all the rows in the INVOICE table that have a ITEMID that does not exist in the ITEM table. Writing this SQL for our 400+ tables database was going to be huge task. </p>

<p>Oracles (or for that matter any databases metadata) metadata to the rescue and we ended up writing a SQL that would generate our above SQL.</p>

<p>here is the SQL that generated the above SQL</p>

<pre class="codeexample">
SELECT 'SELECT '''||table_name||'-'||column_name||''', count(*) FROM '|| 
table_name|| ' WHERE not exists (select 1 from '|| remote_table ||' where '||
remote_table||'.'||remote_column||' = '||table_name||'.'||column_name||') AND '
||table_name||'.'||column_name||' IS NOT NULL
UNION ALL' 
FROM (
   SELECT a.table_name,
      column_name,
      ( SELECT table_name FROM user_constraints 
      		WHERE constraint_name = a.R_CONSTRAINT_NAME) remote_table, 
      ( SELECT column_name FROM user_cons_columns 
      		WHERE constraint_name = a.R_CONSTRAINT_NAME) remote_column 
   FROM user_constraints a, user_cons_columns b 
   WHERE a.constraint_name = b.constraint_name 
   AND a.constraint_type = 'R' )
</pre>

<p>This SQL generates SQL that when run will give us data about tables that do not match our constraints requirements. If you have a CUSTOMER table which has CUSTOMERTYPEID and STATUSID on it, then the SQL generated would be.</p>

<pre class="codeexample">
SELECT 'CUSTOMER-CUSTOMERTYPEID', COUNT(*) FROM CUSTOMER  WHERE NOT EXISTS 
      (SELECT 1 FROM CUSTOMERTYPE WHERE 
             CUSTOMERTYPE.CUSTOMERTYPEID = CUSTOMER.CUSTOMERTYPEID) 
  AND CUSTOMER.CUSTOMERTYPEID IS NOT NULL
UNION ALL
SELECT 'CUSTOMER-STATUSID', COUNT(*) FROM CUSTOMER WHERE NOT EXISTS 
       (SELECT 1 FROM STATUS WHERE 
             STATUS.STATUSID = CUSTOMER.STATUSID) 
  AND CUSTOMER.STATUSID IS NOT NULL
</pre>

<p>Once the above SQL is run, the results will show us data that does not match the constraints we want to introduce into the QA environments.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Setup and Teardown of database during testing</title>
    <link rel="alternate" type="text/html" href="http://www.sadalage.com/2008/04/setup_and_teardown_of_database.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.sadalage.com/cgi-bin/mt/mt-atom.cgi/weblog/blog_id=2/entry_id=40" title="Setup and Teardown of database during testing" />
    <id>tag:www.sadalage.com,2008://2.40</id>
    
    <published>2008-04-17T15:01:30Z</published>
    <updated>2008-04-17T15:15:07Z</updated>
    
    <summary>When doing Performance Testing or running Unit/Functional tests on a database, there is a need to periodically get the database to a known state, so that the tests behave in a predictable way and to get rid of all the...</summary>
    <author>
        <name>Pramod Sadalage</name>
        
    </author>
    
        <category term="Agile DBA" />
    
    <content type="html" xml:lang="en" xml:base="http://www.sadalage.com/">
        <![CDATA[<p>When doing Performance Testing or running Unit/Functional tests on a database, there is a need to periodically get the database to a known state, so that the tests behave in a predictable way and to get rid of all the data created by the tests. Some of the ways to get a clean database are.</p>

<p>Using Scripts: Recreate the database using scripts, the same scripts that are used in development environment. </p>

<p>Using DB Backup: Especially when the database (and the data set) is large (using the scripts approach above will be slow) is to make a backup of the database in its pristine state and then run the tests, once the tests are done running, restore the database with the backup that was done before the tests corrupted the data.</p>

<p>Using Virtual Machine: The DB backup approach can be improved by using Virtual Machine (VM). Setup a VM and run the database server inside the VM, get the database and data so that the tests can run. Now make a image of the VM and run the tests, when the tests are done all that needs to be done is to restore the image of the VM.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Podcast on Keeping Gray code Fit</title>
    <link rel="alternate" type="text/html" href="http://www.sadalage.com/2008/01/podcast_on_keeping_gray_code_f_1.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.sadalage.com/cgi-bin/mt/mt-atom.cgi/weblog/blog_id=2/entry_id=39" title="Podcast on Keeping Gray code Fit" />
    <id>tag:www.sadalage.com,2008://2.39</id>
    
    <published>2008-01-19T04:45:49Z</published>
    <updated>2008-01-19T04:50:05Z</updated>
    
    <summary>Me, Andy, Jeff and Marjorie discuss how to keep a long running project fit in this Podcast, also on itunes. We discuss the management of technology, people, processes and tools on longer and more mature applications. Specific topics such as...</summary>
    <author>
        <name>Pramod Sadalage</name>
        
    </author>
    
        <category term="Broadcast" />
    
    <content type="html" xml:lang="en" xml:base="http://www.sadalage.com/">
        <![CDATA[<p>Me, Andy, Jeff and Marjorie discuss how to keep a long running project fit in this <a href="http://www.thoughtworks.com/what-we-say/podcasts.html">Podcast</a>,  also on <a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewPodcast?id=269759218">itunes</a>. We discuss the management of technology, people, processes and tools on longer and more mature applications. Specific topics such as refactoring, knowledge management, innovation, staffing, production support and others are covered.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Exprerience using DBDeploy on my project</title>
    <link rel="alternate" type="text/html" href="http://www.sadalage.com/2008/01/exprerience_using_dbdeploy_on_1.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.sadalage.com/cgi-bin/mt/mt-atom.cgi/weblog/blog_id=2/entry_id=38" title="Exprerience using DBDeploy on my project" />
    <id>tag:www.sadalage.com,2008://2.38</id>
    
    <published>2008-01-14T23:24:55Z</published>
    <updated>2008-01-17T17:11:00Z</updated>
    
    <summary>We have been using DBDeploy on my project for more than 6 months now and wanted to show how things are going. First lets talk about set up, we are using dbdeploy in our Java development environment with ANT as...</summary>
    <author>
        <name>Pramod Sadalage</name>
        
    </author>
    
        <category term="Agile DBA" />
    
    <content type="html" xml:lang="en" xml:base="http://www.sadalage.com/">
        <![CDATA[<p>We have been using <a href="http://DBDeploy.com">DBDeploy</a> on my project for more than 6 months now and wanted to show how things are going. First lets talk about set up, we are using dbdeploy in our Java development environment with ANT as our build scripting tool, against a Oracle 10g database.</p>

<p>Define the ANT task first</p>

<p><strong>&lt;taskdef name="dbdeploy" classname="net.sf.dbdeploy.AntTarget" classpath="lib/dbdeploy.jar"/&gt;;<br />
</strong></p>

<p>Now we create the main dbinitialize task a ANT task to create you database schema, using the upgrade generated by the dbdeploy file shown below. The thing to note is that dbdeploy generates the upgrade file but does not run it against your database, so we have to make sure we call the generated upgrade file via a sql ANT task.</p>

<p><strong>&lt;target name="dbinit" depends="init,dbclean"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;echo message="Working UserName: ${db.user}"/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;mkdir dir="${migrationfolder}"/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;dbdeploy driver="${driver.name}" url="${db.url}"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; userid="${db.user}" password="${db.password}" deltaset="couger"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dir="db/migration" outputfile="${migrationfolder}/upgrade.sql"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dbms="ora" undoOutputfile="${migrationfolder}/undo.sql"/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;!--Now run the generate upgrade file --&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;sql password="${db.password}" userid="${db.user}" url="${db.url}" driver="${driver.name}"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; classpath="${driver.classpath}" onerror="abort"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;fileset includes="upgrade.sql" dir="${migrationfolder}"/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/sql&gt;<br />
&lt;/target&gt;<br />
</strong><br />
So lets say we want to write the first migration (migration or delta is the same in this context) we will create a new file in the db/migration folder named as 001_CreateCustomerTable.sql the 001 is just a number to sequence the migrations, dbdeploy only cares that the numbers increment and CreateCustomerTable is used to give it a meaningful name, you can name the migration as 1.sql but thats not meaningful is it? neither does the name really say what its doing. When we are done writing the <br />
migration and confirm that it works locally, we check in the file (we used subversion). When &lt;a href="http://cruisecontrol.sourceforge.net/"&gt;CruiseControl&lt;/a&gt; build was done we also published all the <br />
migrations from db/migration folder on CruiseControl artifacts page using the onsuccess event<br />
<strong><br />
&lt;publishers&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;onsuccess&gt;<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;...&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&lt;artifactspublisher dest="artifacts/${project.name}" dir="projects/${project.name}/db/migration"/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/onsuccess&gt;<br />
&lt;/publishers&gt;<br />
</strong></p>

<p>Publishing the migrations allowed us to know what all migrations are needed for this particular build. we have deployed to production twice already and have found this process to be smooth, doing migrations has allowed us to test our migrations hundreds of times and also test them against a copy of the production database before hand so that we can tune the migrations for performance if needed. Delivering the migrations to the client is also easy since its pure SQL that the client DBA's can look at and be comfortable about the migration/upgrade of their database.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Lessons from Re-Learning</title>
    <link rel="alternate" type="text/html" href="http://www.sadalage.com/2007/12/relearning.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.sadalage.com/cgi-bin/mt/mt-atom.cgi/weblog/blog_id=2/entry_id=36" title="Lessons from Re-Learning" />
    <id>tag:www.sadalage.com,2007://2.36</id>
    
    <published>2007-12-28T03:07:50Z</published>
    <updated>2007-12-28T17:18:38Z</updated>
    
    <summary>I have been working on a project that I had worked in 2005, trying to get a handle on what I had done about 3 years back. Exploring code and the database has been fun, also discovering the data layout...</summary>
    <author>
        <name>Pramod Sadalage</name>
        
    </author>
    
        <category term="Mistakes I Learnt from" />
    
    <content type="html" xml:lang="en" xml:base="http://www.sadalage.com/">
        <![CDATA[<p>I have been working on a project that I had worked in 2005, trying to get a handle on what I had done about 3 years back. Exploring code and the database has been fun, also discovering the data layout and building new set of data for production has been extremely entertaining. What I learnt from this whole experience was this <blockquote>if your code(application or other wise) is not expecting data, this data should not be provided or even considered valid by the database, the database should be designed such that it does not even allow invalid combinations of the data.</blockquote></p>

<p>Here is an example. We have a base table named as SETTINGS, that can be changed by the user by overriding the value in the extension table known as SETTINGSEXTENSION, table structure is show below</p>

<pre class="codeexample">
SETTINGS
ID (PK)
KEY (BusinessKey)
VALUE (Value for the Key)
</pre>

<pre class="codeexample">
SETTINGSEXTENTION
ID (PK)
SETTINGSID (FK to SETTINGS table)
OVERRIDDENVALUE (Value overriding the value in the SETTINGS table)
BYUSERID (Value over ridden for user)
</pre>

<p>in this scheme the same user can create extensions for the same base key causing the application to barf. If we <a href="http://databaserefactoring.com/IntroduceIndex.html">introduce unique index</a> on SETTINGSEXTENSION TABLE(SETTINGSID, BYUSERID) we ensure that the database does not allow this data and makes sure that the application will not barf.</p>

<p>There are many more other things I learnt.. those will follow..</p>]]>
        
    </content>
</entry>

<entry>
    <title>Cannot make it out to XP Day London</title>
    <link rel="alternate" type="text/html" href="http://www.sadalage.com/2007/11/cannot_make_it_out_to_xp_day_l.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.sadalage.com/cgi-bin/mt/mt-atom.cgi/weblog/blog_id=2/entry_id=35" title="Cannot make it out to XP Day London" />
    <id>tag:www.sadalage.com,2007://2.35</id>
    
    <published>2007-11-14T01:23:29Z</published>
    <updated>2007-11-14T04:03:27Z</updated>
    
    <summary>After a lot of frustration about my schedule, I have had to come to this conclusion, that I cannot physically make it to London, XP day. I&apos;m going to miss it. Nick Ashley is going to take up my spot...</summary>
    <author>
        <name>Pramod Sadalage</name>
        
    </author>
    
        <category term="Broadcast" />
    
    <content type="html" xml:lang="en" xml:base="http://www.sadalage.com/">
        <![CDATA[<p>After a lot of frustration about my schedule, I have had to come to this conclusion, that I cannot physically make it to <a href="http://xpday.org/node/98">London, XP day</a>.</p>

<p>I'm going to miss it. Nick Ashley is going to take up my spot and I know he will do a great job.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Why do Evolutionary Design</title>
    <link rel="alternate" type="text/html" href="http://www.sadalage.com/2007/11/why_do_evolutionary_design.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.sadalage.com/cgi-bin/mt/mt-atom.cgi/weblog/blog_id=2/entry_id=34" title="Why do Evolutionary Design" />
    <id>tag:www.sadalage.com,2007://2.34</id>
    
    <published>2007-11-05T15:00:03Z</published>
    <updated>2007-11-05T15:10:46Z</updated>
    
    <summary>Why do Evolutionary Design or Iterative Design or Incremental Design? Everyone who has not worked in an evolutionary manner asks this? My answer, if you think the system you designed is NOT GOING TO CHANGE EVER then sure you can...</summary>
    <author>
        <name>Pramod Sadalage</name>
        
    </author>
    
        <category term="Learning" />
    
    <content type="html" xml:lang="en" xml:base="http://www.sadalage.com/">
        <![CDATA[<p>Why do Evolutionary Design or Iterative Design or Incremental Design?<br />
Everyone who has not worked in an evolutionary manner asks this? My answer, if you think the system you designed is <strong>NOT GOING TO CHANGE EVER</strong> then sure you can do design once and deploy once and you are done, move on to next project. But tell me one project you have been on, that does not have any changes in requirements, changes in technology, changes in look and feel etc after it was deployed.</p>

<p>So if every project changes after it was deployed, why live in the fallacy that nothing is going to change ever.</p>

<p>Instead, since you know requirements change, why not get better at managing change, which mean get better at Evolutionary Design or Iterative Design or Incremental Design, so that you are ready for the next requirement change that comes along.</p>]]>
        
    </content>
</entry>

<entry>
    <title>ThoughtWorks at Oracle Open World</title>
    <link rel="alternate" type="text/html" href="http://www.sadalage.com/2007/10/thoughtworks_at_oracle_open_wo.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.sadalage.com/cgi-bin/mt/mt-atom.cgi/weblog/blog_id=2/entry_id=33" title="ThoughtWorks at Oracle Open World" />
    <id>tag:www.sadalage.com,2007://2.33</id>
    
    <published>2007-10-30T14:59:54Z</published>
    <updated>2007-10-30T15:08:19Z</updated>
    
    <summary>ThoughtWorks is going to be at Oracle Open World. I&apos;m excited about this especially since it will give ThoughtWorks and Me to talk about software practices and how to apply these software practices to the database development world, off course...</summary>
    <author>
        <name>Pramod Sadalage</name>
        
    </author>
    
        <category term="Broadcast" />
    
    <content type="html" xml:lang="en" xml:base="http://www.sadalage.com/">
        <![CDATA[<p><a href="http://thoughtworks.com">ThoughtWorks</a> is going to be at <a href="http://www.oracle.com/openworld/2007/index.html">Oracle Open World</a>. I'm excited about this especially since it will give ThoughtWorks and Me to talk about software practices and how to apply these software practices to the database development world, off course I will talk about my books Refactoring Databases and Continuous Database Integration. ThoughtWorks will have a booth at "343 Moscone South" and I will be there on Nov 14.<br />
</p>]]>
        
    </content>
</entry>

</feed> 

