티스토리 뷰



데이터베이스를 사용하는 프로그램을 개발하는 경우 대부분은 특정 데이터베이스를 선택하여 사용합니다. C# 닷넷 기반으로 개발하는 경우 해당 데이터베이스 연관 라이브러리를 참조로 추가하여 간편하게 프로그램을 작성하면 됩니다. 닷넷 프레임워크에서 SQL Server DBMS를 사용하는 경우에는 두 제품 모두 마이크로소프트에서 만든 것으로 쉽게 프로그램을 작성할 수 있는 것은 닷넷 환경에서는 어찌 보면 당연한 현실이 아닌가 싶습니다. 그런데, 오라클이나 MySQL과 같은 다른 데이터베이스를 사용한다고 해서 사용법이 크게 달라지는 것은 아닙니다. 다른 데이터베이스를 사용하는 경우에는 이름만 약간 달라질 뿐이지 사용 형태는 SQL Server를 사용하는 경우와 매우 유사합니다. 예를 들어 SQL Server에서 DB연결을 SqlConnection()으로 수행 한다면 MySQL의 경우에는 MySqlConnection()를 사용해서 데이터베이스에 연결 할 수 있습니다.

그런데, 특정 조직이나 회사에서 사용는 프로그램이 아니라 범용 사용자를 대상으로 하거나 회사내에서 사용하더라도 데이터베이스 시스템을(DBMS) 사용자가 선택하여 사용할 수 있도록 기능을 지원하기 위해서는 약간의 준비가 필요합니다. 데이터베이스를 호출하는 모든 프로그램을 DB 종류마다 별도로 만드는 것도 비효율일 뿐만 아니라 각 로직 마다 사용하는 DB에 따라 분기해서 사용하는것 또한 비효율입니다. 이런 경우에 필요한 기술이 바로 데이터베이스 추상화입니다. 데이터베이스 추상화를 통하여 개별 프로그램들이 데이터베이스의 기능을 사용하면 DBMS가 바뀌더라도 개별 프로그램은 수정할 필요 없이 간편하게 DB를 바꿀 수 있습니다.



데이터베이스 추상화를 적용하는 방법은 크게 두가지로 나눌 수 있습니다. 한가지 방법은 데이터베이스 추상화를 적용할 수 있는 프레임워크를 사용하는 것으로 NHibernate for .NET(https://developer.jboss.org/wiki/NHibernateForNET)을 예로 들 수 있습니다. PHP, JSP등의 웹 개발 방법론에서는 이미 많은 프로그램에서 이러한 데이터베이스 추상화 프레임워크를 적용하여 다양한 DBMS를 사용할 수 있도록 배려하고 있습니다. DB 추상화 프레임워크를 사용하면 개발자는 DBMS가 달라지는 것에 대한 포팅 부담을 최소화할 수 있습니다.

C# .Net환경에서 데이터베이스 추상화를 적용하는 두번째 방법은 개발자가 소스 레벨에서 추상화를 구현하는 것입니다. 소스 레벨에서 데이터베이스 추상화를 구현할 수 있는 기술은 가상 클래스(Abstract class)를 사용하는 방법과 인터페이스(Interface)를 사용하는 방법을 예로 들수 있는데 본 글에서는 C#의 인터페이스를 사용하는 방법을 다루어 보겠습니다. 인터페이스를 생성하고 인퍼페이스를 실제로 구현하는 DBMS별 클래스를 만들어 놓으면 개별 프로그램은 인터페이스에 정의한 속성이나 메소드를 사용하여 어떤 DBMS를 사용하는지와 무관하게 다중 DBMS를 사용하는 프로그래밍을 손쉽게 할 수 있습니다.

    public interface IDB
    {
        String name { get; set; }
        String connstr { get; set; }
        String dbname { get; set; }
        byte status { get; set; }
        String errorMsg { get; set; }

        void DBLoop();
        bool isConnect();
    }

위의 코드는 인터페이스를 정의한 예로 DB 연결을 위한 정보와 상태등을 갖는 속성과 연결을 유지하는 쓰레드 함수와 연결 여부 확인을 담당하는 함수를 정의했습니다. 이 인터페이스에 쿼리를 위한 함수 데이터 저장 및 업데이트를 위한 함수등을 추가로 정의할 수 있겠습니다. 

인터페이스를 정의했으면 인터페이스를 구현하는 클래스를 생성해야 하는데 그 클래스의 일부는 다음과 같습니다.

    public class CMySQL : IDB
    {
        protected String _name, _connstr, _dbname;
        protected byte _status = 0;
        protected String _errorMsg = "";
        MySqlConnection conn = null;

        public String name
        {
            get { return _name; }
            set { _name = value; }
        }
        public String connstr
        {
            get { return _connstr; }
            set { _connstr = value; }
        }
        public String dbname
        {
            get { return _dbname; }
            set { _dbname = value; }
        }
        //......
    }

인터페이스를 구현하는 클래스는 인터페이스의 속성과 함수를 모두 정의해야만 합니다. 물론 추가적으로 나름의 속성과 메소드를 가질 수는 있지만 인터페이스에 있는 내용을 누락시켜서는 안됩니다. 위의 예에서는 IDB 인터페이스를 구현하는 MySQL 클래스를 만들었지만 같은 방식으로 IDB 인터페이스를 구현하는 오라클, SQL Server, SQLite DBMS 클래스를 만들면 자연스럽게 데이터베이스 추상화를 적용할 수 있습니다.

IDB hdb = new CMySQL();
hdb.name = "MyDB";
hdb.connstr = MyConnStr;
hdb.dbname = "MyDB";
Thread myth = new Thread(hdb.DBLoop);
myth.Start();

사용법은 위의 예제와 같이 인터페이스를 선언하고 인터페이스를 구현한 클래스의 인스턴스를 인터페이스에 적용하는 방식을 사용하면 됩니다. 클래스의 인스턴스를 인터페이스에 적용한 다음부터는 인터페이스를 통해서 작업하면 됩니다.

데이터베이스 추상화를 적용한 프로그램은 확장성의 폭이 넓어지기 때문에 프로그램의 효용성을 높일 뿐만 아니라 추상화가 적용된 응용의 경우에는 데이터베이스와 연관한 디버깅에서도 장점을 발휘하므로 데이터베이스를 사용하는 프로그램이라면 데이터베이스 추상화 작업을 꼭 한번 검토해 보세요.


댓글
댓글쓰기 폼