<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>DBA on Architecture and Data Blog</title>
    <link>https://sadalage.com/tags/dba/</link>
    <description>Recent content in DBA on Architecture and Data Blog</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Tue, 23 Sep 2025 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://sadalage.com/tags/dba/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Automated testing of custom sql</title>
      <link>https://sadalage.com/post/automated_custom_sql_testing/</link>
      <pubDate>Tue, 23 Sep 2025 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/automated_custom_sql_testing/</guid>
      <description>&lt;p&gt;Lots of time hand coded SQL is written in the applications for performance sake, getting data using complex SQL out of the tables. As the database structure changes it becomes really hard to find out all the SQL that needs to be changed. In other cases SQL is generated based on certain conditions in the code and its hard to find if the generated SQL is valid after database changes are done.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Generate boiler plate code</title>
      <link>https://sadalage.com/post/generate_boiler_plate_code/</link>
      <pubDate>Sat, 17 May 2025 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/generate_boiler_plate_code/</guid>
      <description>&lt;p&gt;When accessing the database using stored procedures for basic Create, Read, Update and Delete (CRUD) functions, or when you want to write triggers that capture the before and after values in tables, or when you want to create Plain Old Java Objects (POJO&amp;rsquo;s) that match the database objects, writing these by hand takes a lot of effort and also since the requirements are changing in an agile projects at a frequent rate, there will be design changes to meet the requirement changes, so the triggers, CRUD stored procedures or Data Access Objects (DAO) are going to be out of data, instead of hand coding, its better to generate the code, using the metadata of the database&lt;/p&gt;</description>
    </item>
    <item>
      <title>Data specialists should pair with developers</title>
      <link>https://sadalage.com/post/pair-with-developers/</link>
      <pubDate>Thu, 01 Aug 2024 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/pair-with-developers/</guid>
      <description>&lt;p&gt;Traditionally the data-team is used to sitting in their own area and working for many project teams by handling requests either via a ticketing system or vi email. The hand-over of work or throwing of work over the wall creates knowledge silos and inefficiencies.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Publish data models in CI Pipeline</title>
      <link>https://sadalage.com/post/publish-data-models/</link>
      <pubDate>Sat, 16 Sep 2023 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/publish-data-models/</guid>
      <description>&lt;p&gt;Many a times ER models are created by the data team and are not shared outside of the data team generally for the lack of tools licenses, since its not feasible for the entire team to purchase licenses for the ER modelling tools such as &lt;a href=&#34;https://www.erwin.com/products/erwin-data-modeler&#34;&gt;Erwin Data Modeller&lt;/a&gt; or &lt;a href=&#34;https://www.idera.com/products/er-studio/data-architect&#34;&gt;Er Studio&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Static Analysis of PL/SQL code</title>
      <link>https://sadalage.com/post/static-analysis-of-plsql-code/</link>
      <pubDate>Tue, 01 Aug 2017 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/static-analysis-of-plsql-code/</guid>
      <description>&lt;p&gt;In all new development and sometimes during legacy codebase modernization, developers tend to add code quality checks and static analysis of codebase such as style checks, bug finders, cyclomatic complexity checking etc. into the CI/CD pipeline. When we inherit a codebase that has much PL/SQL and there is a desire to put the PL/SQL code base through the same types of code analysis, what options does a developer/dba have?&lt;/p&gt;</description>
    </item>
    <item>
      <title>Using liquibase to load data and ignore some columns</title>
      <link>https://sadalage.com/post/using-liquibase-to-load-data-and-ignore-some-columns/</link>
      <pubDate>Mon, 15 May 2017 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/using-liquibase-to-load-data-and-ignore-some-columns/</guid>
      <description>&lt;p&gt;Loading data into tables is needed many times on projects to load test, &lt;a href=&#34;http://www.liquibase.org/&#34;&gt;Liquibase&lt;/a&gt; provides a method to load data into tables with lots of customization.&#xA;In the example shown below, I&amp;rsquo;m loading &lt;a href=&#34;http://federalgovernmentzipcodes.us/&#34;&gt;zip code data&lt;/a&gt; with the following column layout&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;#34;Zipcode&amp;#34;,&amp;#34;ZipCodeType&amp;#34;,&amp;#34;City&amp;#34;,&amp;#34;State&amp;#34;,&amp;#34;LocationType&amp;#34;,&amp;#34;Lat&amp;#34;,&amp;#34;Long&amp;#34;,&amp;#34;Location&amp;#34;,&amp;#34;Decommisioned&amp;#34;,&amp;#34;TaxReturnsFiled&amp;#34;,&amp;#34;EstimatedPopulation&amp;#34;,&amp;#34;TotalWages&amp;#34;&#xA;&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>Automatically adding columns to Rails migrations</title>
      <link>https://sadalage.com/post/automatically-adding-columns-to-rails-migrations/</link>
      <pubDate>Mon, 25 Apr 2016 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/automatically-adding-columns-to-rails-migrations/</guid>
      <description>&lt;p&gt;Many projects need addition of identical columns to all the tables created by the project. Audit columns are an example of such a requirement. The requirement is to add columns such as &lt;em&gt;created_by&lt;/em&gt;, &lt;em&gt;created_date&lt;/em&gt;, &lt;em&gt;modified_by&lt;/em&gt; and &lt;em&gt;modified_date&lt;/em&gt; to all the tables, these columns store, who created the row, when the row was created,  who modified the row last and when was it modified. &lt;em&gt;created_by&lt;/em&gt; and &lt;em&gt;created_date&lt;/em&gt; are required to be present when the row is inserted and thus are required to be &lt;em&gt;not nullable&lt;/em&gt;. Adding these columns to each and every table is a lot of work for developers.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Synonyms as abstraction layer</title>
      <link>https://sadalage.com/post/synonyms-as-abstraction-layer/</link>
      <pubDate>Fri, 15 Apr 2016 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/synonyms-as-abstraction-layer/</guid>
      <description>&lt;p&gt;In many development shops, developers are not allowed to access the database schema directly, and are not allowed to create tables, indexes, views etc, instead are given access via a different schema that allows &lt;em&gt;SELECT&lt;/em&gt;, &lt;em&gt;UPDATE&lt;/em&gt; and &lt;em&gt;DELETE&lt;/em&gt; access on data. The general reason is to avoid developers creating database objects without&lt;/p&gt;</description>
    </item>
    <item>
      <title>Using rake and activerecord to generate boilerplate DB Code</title>
      <link>https://sadalage.com/post/using-rake-and-activerecord-to-generate-boilerplate-db-code/</link>
      <pubDate>Mon, 20 Jul 2015 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/using-rake-and-activerecord-to-generate-boilerplate-db-code/</guid>
      <description>&lt;p&gt;IN many projects, there are tables which need default audit columns such as &lt;em&gt;Created_By&lt;/em&gt;, &lt;em&gt;Created_Date&lt;/em&gt;, &lt;em&gt;Modified_By&lt;/em&gt;, &lt;em&gt;Modified_date&lt;/em&gt; and other columns that need to be updated every time some actions are done against the tables and/or columns. This type of functionality can be implemented using triggers.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Database naming conventions in different environments</title>
      <link>https://sadalage.com/post/database-naming-conventions-in-different-environments/</link>
      <pubDate>Wed, 10 Jun 2015 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/database-naming-conventions-in-different-environments/</guid>
      <description>&lt;p&gt;In every enterprise and every project we end up having multiple environments, especially the database side of the enterprise tends to stick around for a longer period of time and has much more dependencies or application integration as opposed to application urls etc.&#xA;Given this, how to name the servers, databases and schemas becomes a very important decision, do these names provide for an easy way to use the application and not make it harder or the developers to access the database.&lt;/p&gt;</description>
    </item>
    <item>
      <title>8 Techniques for testing migration of data from legacy systems</title>
      <link>https://sadalage.com/post/testing-migration-of-data-from-legacy-systems/</link>
      <pubDate>Fri, 23 Jan 2015 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/testing-migration-of-data-from-legacy-systems/</guid>
      <description>&lt;p&gt;Many of the projects we end up working on are replacing existing systems with existing data either wholly or in part. In all of the above projects we end up writing data migration or data conversion code to move the data from legacy systems to the new systems. Many stake holders of the project such as business users, project managers, business analysts really care about the data conversion scripts and the quality of the conversion. Since this conversion is business entity related and matters a lot as future business/functionality depends on the data being logically equivalent to the legacy system.&lt;/p&gt;</description>
    </item>
    <item>
      <title>10 node mongodb ReplicaSet on a Single Machine&#34;</title>
      <link>https://sadalage.com/post/node-mongodb-replicaset-on-a-single-machine/</link>
      <pubDate>Mon, 09 Jun 2014 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/node-mongodb-replicaset-on-a-single-machine/</guid>
      <description>&lt;p&gt;While doing evalauation of NoSQL databases, we had a&#xA;&lt;a href=&#34;http://sadalage.com/blog/2013/04/25/10_node_riak_cluster/&#34;&gt;10 node riak cluster&lt;/a&gt; and wanted check how a similar setup would work with mongodb. So started to setup a 10 node &lt;a href=&#34;http://www.mongodb.org/&#34;&gt;mongodb&lt;/a&gt; cluster. Since this was for initial spikes, we decided to set this up on a single machine as with the other test setup using &lt;a href=&#34;http://basho.com/riak/&#34;&gt;Riak&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Before I explain how we setup 10 node mongodb ReplicaSet, let me talk about replica sets. MongoDB implements replication, providing high availability using &lt;a href=&#34;http://sadalage.com/blog/2010/10/31/replica_sets_in_mongodb/&#34;&gt;replica sets&lt;/a&gt;. In a replica set, there are two or more nodes participating in an asynchronous master-slave replication. The replica-set nodes elect the master node, or primary node, among themselves and when the primary node goes down, the rest of the node elect the new primary node.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Usage of mixed case database object names is dangerous</title>
      <link>https://sadalage.com/post/mixed_case_database_objects/</link>
      <pubDate>Tue, 06 Aug 2013 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/mixed_case_database_objects/</guid>
      <description>&lt;p&gt;Some versions back, Oracle would not allow to create database object names with mixed cases, even if we tried to create them, we could not. In newer versions of Oracle we can create tables, columns, indexes etc using mixed case or lower case, when the names are put inside double quotes. For example&lt;/p&gt;</description>
    </item>
    <item>
      <title>10 node Riak cluster on a single machine</title>
      <link>https://sadalage.com/post/node_riak_cluster/</link>
      <pubDate>Thu, 25 Apr 2013 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/node_riak_cluster/</guid>
      <description>&lt;p&gt;When trying to evaluate NoSQL databases, its usually better to try them out. While trying them out, its better to use them with multiple node configurations instead of running single node. Such as clusters in Riak or Replica-set in mongodb maybe even a sharded setup. On our project we evaluated a 10 node Riak cluster so that we could experiment with N, R and W values and decide which values where optimal for us. In Riak here is what N, R and W mean.&lt;/p&gt;</description>
    </item>
    <item>
      <title>With so much pain, why are stored procedures used so much</title>
      <link>https://sadalage.com/post/why_use_stored_procedures/</link>
      <pubDate>Wed, 19 Jan 2011 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/why_use_stored_procedures/</guid>
      <description>&lt;p&gt;I keep encountering situations where all the business logic for the applications is in stored procedures and the application layer is just calling the stored procedures to get the work done and return the data. There are many problems with this approach some of them are.&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Writing stored procedure code is fraught with danger as there are no modern IDE&amp;rsquo;s that support refactoring, provide code smells like &amp;ldquo;variable not used&amp;rdquo;, &amp;ldquo;variable out of scope&amp;rdquo;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Replica sets in MongoDB</title>
      <link>https://sadalage.com/post/replica_sets_in_mongodb/</link>
      <pubDate>Sun, 31 Oct 2010 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/replica_sets_in_mongodb/</guid>
      <description>&lt;p&gt;Replica sets is a feature of MongoDB for Automatic Failover, in this setup there is a primary server and the rest are secondary servers. If the primary server goes down, the rest of the secondary servers choose a new primary via an election process, each server can also be assigned number of votes, so that you can decide the next primary based on data-center location, machine properties etc, you can also start mongo database processes that act only as election tie-breakers these are known as arbiters, these arbiters will never have data, but just act as agents that break the tie.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Create an Index for all FK Columns in the database</title>
      <link>https://sadalage.com/post/create_an_index_for_all_fk_columns/</link>
      <pubDate>Thu, 03 Sep 2009 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/create_an_index_for_all_fk_columns/</guid>
      <description>&lt;p&gt;Most of the time I have seen database foreign key constraints on tables without indexes on those columns. Lets say the application is trying to delete a row from the CUSTOMER table&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;DELETE FROM CUSTOMER WHERE CUSTOMERID = 1000;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When the database goes about deleting the customerId of 1000, if there are foreign key constraints defined on customerId, then the database is going to try to find if the customerId of 1000 is used in any of those tables. Lets say ORDER table has the customerId column, the database is going to issue&lt;/p&gt;</description>
    </item>
    <item>
      <title>Explicitly rollback when you encounter a deadlock.</title>
      <link>https://sadalage.com/post/explicitly_rollback_when_you_get_deadlock/</link>
      <pubDate>Tue, 26 May 2009 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/explicitly_rollback_when_you_get_deadlock/</guid>
      <description>&lt;p&gt;Dead lock is caused in the database when you have resources (connections) waiting for other connections to release locks on the rows that are needed by the session, resulting in all session being blocked. Oracle automatically detects deadlocks are resolves the deadlock by rolling back the statement  in the transaction that detected the deadlock. Thing to remember is that &lt;strong&gt;last statement is rolled back and not the whole transaction&lt;/strong&gt;, which means that if you had other modifications, those rows are still locked and the application should make sure that it does a explicit rollback on the connection.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Oracle Metadata can be mis-leading</title>
      <link>https://sadalage.com/post/oracle_metadata_can_be_misleading/</link>
      <pubDate>Tue, 31 Mar 2009 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/oracle_metadata_can_be_misleading/</guid>
      <description>&lt;p&gt;Oracle has metadata about all its objects in various tables/views. One such view is the USER_OBJECTS or ALL_OBJECTS, this view has a column named as STATUS which shows you if the given object is VALID or INVALID. The status applies to DB Code (Stored Procedures, Functions, Triggers etc).&lt;/p&gt;&#xA;&lt;p&gt;To find all the INVALID objects in the schema, issue&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d0d0d0;background-color:#202020;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;SELECT&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt; &lt;/span&gt;*&lt;span style=&#34;color:#666&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;FROM&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt; &lt;/span&gt;USER_OBJECTS&lt;span style=&#34;color:#666&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;WHERE&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt; &lt;/span&gt;STATUS=&lt;span style=&#34;color:#ed9d13&#34;&gt;&amp;#39;INVALID&amp;#39;&lt;/span&gt;;&lt;span style=&#34;color:#666&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;One problem with the way oracle maintains this metadata is, changing the underlying table on which the DB Code depends, oracle marks the objects are INVALID even though the underlying table may have changed in such a way, that it does not affect the DB Code at all (like adding a new column, or making a colum nullable). Here is some code which shows you what I mean. Run it through SQLPlus.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Storing just the time in Oracle</title>
      <link>https://sadalage.com/post/storing_time_in_oracle/</link>
      <pubDate>Thu, 12 Feb 2009 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/storing_time_in_oracle/</guid>
      <description>&lt;p&gt;We came across a need to save just the Time in the database, the requirement is to store time of the day, like say the user likes to have Breakfast at 8.15AM and Lunch at 12.32PM etc. Off course oracle does not have a time only data type.  So we ended up using DATE as the data type and just setting the time. for example:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;CREATE TABLE FOO (PREFERRED_TIME DATE NULL);&#xA;INSERT INTO FOO (TO_DATE(&amp;#39;11:34&amp;#39;,&amp;#39;HH24:MI&amp;#39;));&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;oracle automatically sets the date to the first day of the current month. so when you do a select from the FOO table the data would be&lt;/p&gt;</description>
    </item>
    <item>
      <title>Considerations when using stored procedures for doing CRUD</title>
      <link>https://sadalage.com/post/considerations_when_using_procedures/</link>
      <pubDate>Tue, 03 Feb 2009 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/considerations_when_using_procedures/</guid>
      <description>&lt;p&gt;Some environments like to have access to the database tables routed via stored procedures.&#xA;Instead of using Create/Read/Update/Delete aka CRUD with DML, stored procedures are invoked with the parameters to perform the required operation. I&amp;rsquo;m not arguing about the benefits/pitfalls of this approach, if you have to do stored procedures, here are some things to look at.&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Make the stored procedure handle one object/table only and not multiple objects or tables.&lt;/li&gt;&#xA;&lt;li&gt;Do not commit open transactions inside the stored procedures.&lt;/li&gt;&#xA;&lt;li&gt;Do not do business logic in stored procedures.&lt;/li&gt;&#xA;&lt;li&gt;If they are straight CRUD stored procedures, see if you can generate the stored procedure code using some metadata?&lt;/li&gt;&#xA;&lt;li&gt;Make sure creation and execution of the stored procedures is part of your &lt;a href=&#34;http://studios.thoughtworks.com/cruise-continuous-integration&#34;&gt;Continuous Integration&lt;/a&gt; build and developer build.&lt;/li&gt;&#xA;&lt;li&gt;Make sure stored procedures (or the metadata used to generate them) is under Version Control, have seen many problems when the stored procedure version does not match application code version&lt;/li&gt;&#xA;&lt;li&gt;Develop against the production stack database.&lt;/li&gt;&#xA;&lt;li&gt;Make sure exceptions thrown by the database are passed back to the application.&lt;/li&gt;&#xA;&lt;/ul&gt;</description>
    </item>
    <item>
      <title>Moved to a Mac</title>
      <link>https://sadalage.com/post/moved_to_a_mac/</link>
      <pubDate>Mon, 01 Sep 2008 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/moved_to_a_mac/</guid>
      <description>&lt;p&gt;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.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Create a Index for every Foreign Key constraint created</title>
      <link>https://sadalage.com/post/create_a_index_for_every_foreign_key/</link>
      <pubDate>Tue, 15 Jul 2008 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/create_a_index_for_every_foreign_key/</guid>
      <description>&lt;p&gt;When creating a Foreign Key constraint on the database as shown below&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ALTER TABLE BOOK ADD&#xA;    (CONSTRAINT FK_BOOK_AUTHOR FOREIGN KEY (AUTHORID)&#xA;     REFERENCES AUTHOR)&#xA;/&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;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&lt;/p&gt;</description>
    </item>
    <item>
      <title>Writing a SQL to generate a SQL</title>
      <link>https://sadalage.com/post/writing_a_sql_to_generate_a_sql/</link>
      <pubDate>Tue, 06 May 2008 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/writing_a_sql_to_generate_a_sql/</guid>
      <description>&lt;p&gt;We had a weird requirement on our project recently..&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;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&lt;/p&gt;&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>Experience using DBDeploy on my project</title>
      <link>https://sadalage.com/post/exprerience_using_dbdeploy_on_project/</link>
      <pubDate>Mon, 14 Jan 2008 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/exprerience_using_dbdeploy_on_project/</guid>
      <description>&lt;p&gt;We have been using &lt;a href=&#34;http://DBDeploy.com&#34;&gt;DBDeploy&lt;/a&gt; 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.&lt;/p&gt;&#xA;&lt;p&gt;Define the ANT task first&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d0d0d0;background-color:#202020;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-XML&#34; data-lang=&#34;XML&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;&amp;lt;taskdef&lt;/span&gt; &lt;span style=&#34;color:#bbb&#34;&gt;name=&lt;/span&gt;&lt;span style=&#34;color:#ed9d13&#34;&gt;&amp;#34;dbdeploy&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#bbb&#34;&gt;classname=&lt;/span&gt;&lt;span style=&#34;color:#ed9d13&#34;&gt;&amp;#34;net.sf.dbdeploy.AntTarget&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#bbb&#34;&gt;classpath=&lt;/span&gt;&lt;span style=&#34;color:#ed9d13&#34;&gt;&amp;#34;lib/dbdeploy.jar&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;/&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;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.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Parsing mapping files for usage information</title>
      <link>https://sadalage.com/post/parsing_mapping_files_for_usage_information/</link>
      <pubDate>Thu, 19 Jul 2007 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/parsing_mapping_files_for_usage_information/</guid>
      <description>&lt;p&gt;Currently working on a legacy application, thats been in production for a long time now. I wanted to find out what are the Tables and Columns being used by the application. Since we could see that some table columns where not being used.&#xA;We are using a Object Relational mapping framework on the project, so we decided to write some code that would parse all the mapping files and gives us a list of table names and columns. We used this list to create rows in a table with two columns tablename and columnname. Once the table had this data, we just ran one more SELECT against the metadata of the database and our table which pretty much gave us a list of Table and Columns that we are not using&lt;/p&gt;</description>
    </item>
    <item>
      <title>Long Running Data Migrations during Database Refactorings</title>
      <link>https://sadalage.com/post/long_running_data_migrations/</link>
      <pubDate>Fri, 29 Jun 2007 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/long_running_data_migrations/</guid>
      <description>&lt;p&gt;When you are refactoring large databases, you will have certain tables that have millions of rows, so lets say we are doing the &lt;a href=&#34;http://databaserefactoring.com/MoveColumn.html&#34;&gt;Move Column&lt;/a&gt; refactoring, moving the TaxAmount column from Charge table which has millions of rows to TaxCharge table. Create the TaxAmount column in the TaxCharge table. Then have to move the data from the TaxAmount column in the Charge table to the TaxAmount column you created in the TaxCharge table.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Enforcing your assumptions about database functionality</title>
      <link>https://sadalage.com/post/enforcing_your_assumptions/</link>
      <pubDate>Fri, 08 Jun 2007 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/enforcing_your_assumptions/</guid>
      <description>&lt;p&gt;When you are writing xUnit tests you are in certain ways trying to make sure that the test breaks when the code that is being tested changes the assumptions you made when writing the Test and Production code.&lt;/p&gt;&#xA;&lt;p&gt;Similarly if you are relying on the database to throw a error when you put invalid data, then you should write a test around this assumption, so that when someone changes the database to not behave the way you assumed it to behave, the test you wrote will break and it will force the team to think about the change to the database that is being undertaken. If the change is really required, then the team would fix the test else rollback the change being made.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Moscow</title>
      <link>https://sadalage.com/post/moscow/</link>
      <pubDate>Wed, 11 Apr 2007 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/moscow/</guid>
      <description>&lt;p&gt;Last week I was at SD Best Practices in Moscow, doing a presentation on &amp;ldquo;Refactoring Databases: Evolutionary Database Design&amp;rdquo;. Moscow seems like a interesting place, loads of huge buildings, squares, fountains and roads. Things some how feel rundown, feels like a player trying to regain his former ability or glory.&lt;/p&gt;&#xA;&lt;p&gt;Opening Keynote by &lt;a href=&#34;http://www.mccarthyshow.com/TheCore/TheCoreCommitments/tabid/1324/Default.aspx&#34;&gt;Jim McCarthy&lt;/a&gt; about how teams should operate was interesting, he proposed 11 principals or protocols as he calls them, to be followed by members in a team so that the team becomes more productive, many of these protocols are about avoiding waste and promoting clear communication channels.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Implementing Make Column Non Nullable</title>
      <link>https://sadalage.com/post/implementing_make_column_non_nullable/</link>
      <pubDate>Fri, 15 Dec 2006 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/implementing_make_column_non_nullable/</guid>
      <description>&lt;p&gt;While working on a Legacy Application with Legacy Database design as part of fixing a bug, I thought this bug would not have ever happened if a particular column was defined as &lt;strong&gt;Non Nullable&lt;/strong&gt; since this particular column was the identifier to the parent table.&lt;/p&gt;&#xA;&lt;p&gt;We had a Customer table and the all the names a customer could have like LegalName, LongName, ShortName etc are stored in the CustomerName table. CustomerName cannot exist without Customer hence its logical that the CustomerName.CustomerID column cannot be nullable and should also have a Foreign Key constraint enforcing the relationship. Implementing just the Foreign Key constraint is not enough since the application could potentially be inserting null values in the CustomerName.CustomerID creating orphan records.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Automated Tablespace deployment</title>
      <link>https://sadalage.com/post/automated_tablespace_deployment/</link>
      <pubDate>Mon, 01 May 2006 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/automated_tablespace_deployment/</guid>
      <description>&lt;p&gt;In development mode you don&amp;rsquo;t want to worry about which table goes into what Tablespace in production as it complicates development environments. The production DBA&amp;rsquo;s want to have their input and control over deciding what table goes into what Tablespace. To allow for this I used a mapping scheme as shown below.&lt;/p&gt;&#xA;&lt;p&gt;Lets assume we have 3 tables in our system Customer, CustomerOrder, OrderStatus. Where we are expecting Customer table to have large numbers of rows and CustomerOrder to have significanly large number of rows while OrderStatus would have few rows and not change as much. In development environments all these tables and their indexes will be put under the same tablespace. In production like environments we want to put them into seperate tablespaces.&lt;/p&gt;</description>
    </item>
    <item>
      <title>To allow NULLs or NOT</title>
      <link>https://sadalage.com/post/to_null_or_not/</link>
      <pubDate>Wed, 08 Feb 2006 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/to_null_or_not/</guid>
      <description>&lt;p&gt;Database designs I have seen tend to &lt;em&gt;not constrain&lt;/em&gt; the data in the database. For example make the &lt;em&gt;Item.ManufacturerID&lt;/em&gt; non-nullable and make it a foreign key to the &lt;em&gt;Manufacturer&lt;/em&gt; table. Similarly &lt;em&gt;Manufacturer.Name&lt;/em&gt; and &lt;em&gt;Item.Rate&lt;/em&gt; as non-nullable columns. In any greenfield application (existing production application is a topic for another post). When you design table(s) lets say you have &lt;em&gt;Item&lt;/em&gt; and &lt;em&gt;Manufacturer&lt;/em&gt; table as shown below&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d0d0d0;background-color:#202020;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;CREATE&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;TABLE&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt; &lt;/span&gt;Item&lt;span style=&#34;color:#666&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;&lt;/span&gt;(ItemID&lt;span style=&#34;color:#666&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#24909d&#34;&gt;NUMBER&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;NOT&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;NULL&lt;/span&gt;,&lt;span style=&#34;color:#666&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;&lt;/span&gt;ManufacturerID&lt;span style=&#34;color:#666&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#24909d&#34;&gt;NUMBER&lt;/span&gt;,&lt;span style=&#34;color:#666&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;&lt;/span&gt;Name&lt;span style=&#34;color:#666&#34;&gt; &lt;/span&gt;VARCHAR2(&lt;span style=&#34;color:#3677a9&#34;&gt;128&lt;/span&gt;),&lt;span style=&#34;color:#666&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;&lt;/span&gt;Rate&lt;span style=&#34;color:#666&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#24909d&#34;&gt;NUMBER&lt;/span&gt;,&lt;span style=&#34;color:#666&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;CONSTRAINT&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt; &lt;/span&gt;PK_ITEM&lt;span style=&#34;color:#666&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;              &lt;/span&gt;&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;PRIMARY&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;KEY&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt; &lt;/span&gt;(ItemID)&lt;span style=&#34;color:#666&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;&lt;/span&gt;);&lt;span style=&#34;color:#666&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;CREATE&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;TABLE&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt; &lt;/span&gt;Manufacturer&lt;span style=&#34;color:#666&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;&lt;/span&gt;(ManufacturerID&lt;span style=&#34;color:#666&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#24909d&#34;&gt;NUMBER&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;NOT&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;NULL&lt;/span&gt;,&lt;span style=&#34;color:#666&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;&lt;/span&gt;Name&lt;span style=&#34;color:#666&#34;&gt; &lt;/span&gt;VARCAHR2(&lt;span style=&#34;color:#3677a9&#34;&gt;128&lt;/span&gt;),&lt;span style=&#34;color:#666&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;CONSTRAINT&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt; &lt;/span&gt;PK_MANUFACTURER&lt;span style=&#34;color:#666&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;              &lt;/span&gt;&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;PRIMARY&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#6ab825;font-weight:bold&#34;&gt;KEY&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt; &lt;/span&gt;(ManufacturerID)&lt;span style=&#34;color:#666&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;&lt;/span&gt;);&lt;span style=&#34;color:#666&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For now let&amp;rsquo;s talk about &lt;strong&gt;NOT NULL&lt;/strong&gt; constraint. Many say they don&amp;rsquo;t make columns non-nullable, because they don&amp;rsquo;t know the requirements at design time, or they don&amp;rsquo;t want their tests to create elaborate sets of data, or that the application enforces the constraint then why enforce the constraint on the database?&lt;/p&gt;</description>
    </item>
    <item>
      <title>Refactoring Data</title>
      <link>https://sadalage.com/post/refactoring_databases/</link>
      <pubDate>Thu, 19 Jan 2006 00:00:00 +0000</pubDate>
      <guid>https://sadalage.com/post/refactoring_databases/</guid>
      <description>&lt;p&gt;Many a times &lt;a href=&#34;http://refactoring.com&#34;&gt;Refactoring&lt;/a&gt; is talked about in the context of code, recently I finished working with Scott Ambler on &lt;a href=&#34;http://www.databaserefactoring.com&#34;&gt;Database Refactoring&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Lately I have been working on changing data in an production database, and have been wondering how do I define it, Data Refactoring? what are the patterns of Data Refactoring. First let me talk about what I mean by Data Refactoring.&lt;/p&gt;&#xA;&lt;p&gt;When a given application goes into production, and starts life as a live application we find bugs with the application, these bugs create a weird data in the database, also with the way people change data through the app and some times through the database (yikes) and these data changes do lead to bad data.  How do you go about fixing these data problems, are there patterns to these fixes.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
