데이터베이스

From Hidden Wiki
(Redirected from 디비)
Jump to navigation Jump to search
필독 사항 유닠스 계열 저작물, 성인물, 도박 웹 써버 보안 프로그래밍 그래핔 파싱
필독 사항 고스트BSD 표면 웹 싸이트 제작 리눅스 마스터 파이썬 트킨터 뷰티펄 숲
수학 아이투피 마약, 아청물, 해킹 웹 싸이트 보안 웹 프로그래밍 데이터 분석 게임 제작
통계학 뮤와이어 다크넽 싸이트 제작 정보 보안 기사 쟁고우 팬더즈 파이게임

개요

데이터베이스(database, DB)는 체계화된 데이터의 모임이다.[1] 즉, 작성된 목록으로써 여러 응용 시스템들의 통합된 정보들을 저장하여 운영할 수 있는 공용 데이터들의 묶음이다.

데이터베이스 종류

MySQL이 8.0 메이저 버전 발표를 앞두고 있다. 2017년에 발표될 것이고, 시스템 구성에 영향을 줄만한 개선점들을 도입할 것으로 보인다. MySQL은 여전히 가장 인기있는 데이터베이스 관리 시스템이며, 앞으로 발표될 버전으로 인해 모든 산업군에 이득이 있을 것이다.

PostgreSQL 9.6 버전이 9월에 발표됐다. 조금 더 나은 전문검색(Full text search)을 지원하고 병렬 쿼리와 효율적인 복제, 집합 구성, 인덱싱, 정렬을 통해 성능을 끌어올렸다. Postgres는 대규모, 테라바이트급 데이터셋, 연산이 많은 웹 앱에 최적화되어 사용되고 있다.

NoSQL 팬에게는 CouchDB를 추천한다. CouchDB는 RESTful HTTP API를 지원하면서, 빠르고 확장 가능한 JSON 저장소다. 이 데이터베이스는 사용하기 쉬우면서도 놀라운 성능을 자랑한다. PouchDB처럼 온전히 브라우저에서 구동되고 Couch와 동기화를 맞출 수 있는 데이터베이스도 있다. 웹 앱이 오프라인일 때 Pouch를 사용하고 인터넷이 연결되면 자동으로 Couch와 동기화하는 방식으로 사용할 수 있다.

Redis는 키-값 스토어 중에 인기 있는 데이터베이스다. Redis는 작고 빠르면서도 많은 기능을 제공한다. Memcache 대신 Redis를 사용할 수도 있을 것이고, NoSQL 대신 쓰거나 메시지 전송과 동기화를 위한 채널로 사용할 수도 있다. Redis에서 제공하는 수 많은 데이터 구조를 골라서 사용할 수 있고, 4.0 버전이 나오면 모듈 시스템이 도입되어 복제셋 구성이 더욱 개선될 것이다.

RDBMS vs NoSQL

데이터베이스는 우선 RDBMS를 쓸 것이냐 NoSQL을 쓸 것이냐부터 선택해야 한다. 물론 RDBMS가 여러 모로 유리하다. 많은 스타트업들이 자신들의 서비스가 대박이 나면 그냥 RDBMS로 버티지 못하는 건 아닐까 걱정을 하고, 처음부터 대용량을 커버할 수 있는 설계를 하고 싶어한다. 하지만 RDBMS의 한계는 생각보다 아주 멀리 있다. 우선, 리플리케이션이나 여타 RDBMS를 스케일업할 수 있는 수단을 쓰지 않고 순수하게 RDBMS 서버 한 대에 쿼리 튜닝만 잘 해놓아도 국내에서 방문자 10위권 사이트 정도는 커버가 된다. 간혹 하루 방문자 10만명 내외의 사이트인데 DB가 부하를 못 견딘다고 NoSQL로 가야하는 거 아니냐고 묻는 팀도 있는데, 이건 전적으로 쿼리 튜닝의 문제다. 쿼리 튜닝도 고난이도의 튜닝이 필요한 게 아니라, 잘 정규화가 되어 있고 기본적인 인덱스만 잘 걸려 있으면 된다. 그러면 Django나 Rails에서 사용하는 ORM을 그대로 쓰면서 성능 문제를 해결해갈 수 있는 것이다.

만약 정말로 비즈니스가 대박이 나서 저 정도로는 감당할 수 없는 상황이 되어간다고 해도 방법이 있다. 캐시를 추가하면 캐시 전략에 따라 다르지만 수 배에서 수십 배의 부하를 감당할 수 있다. 이것만으로도 많은 상황이 해결될 것이다. 그리고 read-only 리플리케이션을 붙이면 수 배 확장 가능하고, 샤딩을 하면 데이터 사이즈에서의 대용량도 커버 가능하다. 이 정도 수준까지 하면 사실상 국내 최고 수준의 트래픽도 감당할 수 있다. 그리고 여기까지 하는 것도 이미 사례들이 많아서 그리 어려운 일이 아니다.

이걸로도 해결이 안되는 스케일이 되더라도 여전히 솔루션은 존재한다. 미들웨어를 투입할 수도 있고, 테이블 설계를 단순하게 할 수도 있고, 부분적으로 NoSQL을 사용할 수도 있다. 어쨋든 용량이 커진다고 해서 RDBMS로 만든 것을 갈아엎고 NoSQL을 도입해야 하는 것은 아니고 RDBMS를 주력으로 쓰면서 계속 성능을 개선해갈 수 있다.

그렇지만 사실 RDBMS의 한계보다 스타트업에게 더 중요한 것은 그 한계를 만날 수 있게 되느냐일 것이다. 그 한계를 만나려면 어쨋든 제품이 성공해야 하는 것이고, 제품을 성공시키려면 개발 생산성을 우선할 수 밖에 없다. 그렇게 해서 비즈니스가 성공하고 나서 회사의 자원이 넉넉해지면 나중에 성능을 개선할 방법은 얼마든지 있다. 그래서 초기 단계의 스타트업이 성능을 이유로 NoSQL을 선택할 필요는 없다.

MySQL vs PostgreSQL

RDBMS 중에 선택지는 사실상 둘 뿐이다.

MySQL

PostgreSQL

둘다 나쁘지 않은 선택이다. MySQL이 관리하기는 좀더 쉽다. phpmyadmin 같은 훌륭한 관리 도구도 있고, 세계적으로 가장 널리 쓰이는 DBMS이기 때문에 문서나 각종 레퍼런스도 많다. MySQL에 문제점도 아주 많이 있지만, 그 문제점에 대한 대안조차도 검색하면 다 나올 정도다. 다만 SQL 표준을 지키지 않는 부분이 좀 있고, 개발자의 합리적인 예상을 벗어나는 동작들이 가끔 있기 때문에 간혹 어이 없는 상황을 겪기는 할 것이다. 그리고 MySQL이 오라클에 넘어갔기 때문에 오픈소스 계열은 MySQL을 fork해서 MariaDB를 쓰고 있어서 이 혼란도 부담이 될 수 있다. 한 가지 중요한 포인트는 위치정보를 다루는 기능이 부족하다는 것이다. 스토리지로 MyISAM을 쓸 때만 위치정보 인덱스가 지원되는데 요즘은 MySQL 스토리지 엔진으로 InnoDB를 쓰는 게 대세인지라 위치정보를 제대로 활용하기 어렵다.

PostgreSQL은 좀더 순수한 오픈소스로 자리를 지켜왔고, 표준 SQL을 잘 준수하고 있으며, RDBMS로 갖춰야 할 기능들을 잘 갖추고 있다. GIS 지원이라든지, JSON type, Array type 등 여러 가지 기능 면에서도 PostgreSQL이 앞선다. 다만 사례가 부족해서 MySQL보다 좀더 정보를 찾는데 어려움을 겪을 수는 있다.

성능 면에서는 단순한 쿼리일수록 MySQL이 더 낫고, 복잡해질수록 PostgreSQL이 낫다고 하나, 최신 버전에 대해 객관적으로 비교할 수 있는 벤치마크는 드물다. 필자의 경험에서는 MySQL이 이 잘 돌아갔던 사이트보다 10배 정도 작은 규모의 사이트에서 PostgreSQL로 성능 때문에 고생했던 적이 있다.

MongoDB?

앞서 굳이 NoSQL을 쓸 필요가 없다고 했으나, 그래도 MongoDB는 한 번 검토해볼 가치가 있다. RDBMS가 전반적으로 유리함에도 불구하고 MongoDB가 괜찮을 수 있는 이유로 다음의 이유들을 꼽을 수 있다.

위치정보를 다루기 쉽다.

스키마와 인덱스의 자유도가 높다.

Node.js와 궁합이 좋다.

MongoDB는 기본으로 2차원 인덱스인 2d가 탑재되어 있고, 최근에는 구의 표면 위치를 다룰 수 있는 2dsphere 인덱스가 추가되어 더욱더 정확하게 위치정보를 처리할 수 있다. 위치정보를 다룰 때 중요한 것 중 하나가 현재 위치 주변에서 거리 순서로 정렬한 N개의 결과를 보여주는 KNN 쿼리인데 MongoDB는 이 KNN 쿼리가 문법도 편하고 성능도 가장 좋다. 그래서 데이터베이스를 MySQL로 쓰더라도 위치정보는 따로 MongoDB에 저장하기도 한다. 물론 PostgreSQL도 PostGIS로 지원하긴 하지만 MongoDB가 성능도 더 좋고 더 쉽다.

스키마의 자유도가 높다는 것은 장점일 수도 있고 단점일 수도 있는데, 필자의 경험에서는 Node.js에서 사용할 경우에 자바스크립트 객체를 그대로 데이터베이스에 넣고 쿼리할 수 있어서 상당히 편리했다. 특히 복잡한 구조의 데이터이지만 어떻게 활용할지 정책이 정해지지 않은 상황에서 데이터를 대충 밀어넣고 나중에 인덱스를 걸 수 있다는 점은 장점이다. 예를 들면 위치기반 앱을 만들 때 포스퀘어 연동을 해서 API에서 받은 장소의 데이터를 받았을 경우 RDBMS라면 나중에 이 데이터에서 어떤 부분이 필요할지 미리 예상해서 위치좌표라든가, 카테고리 분류명 등을 따로 필드로 만들어서 빼놓아야 하는데, MongoDB에서는 처음부터 고민할 필요 없이 일단 넣어놓고 나중에 필요해질 때 데이터 구조를 바꾸지 않고 인덱스를 걸 수 있다.

다만, Django에서는 스키마 변경을 자동으로 해줄 수 있기 때문에 상대적으로 스키마 변경의 자유도는 큰 장점이 아닐 수 있다. 그리고 PostgreSQL은 최근에 JSON 타입에 인덱스를 걸 수 있는 기능을 추가해서 결과적으로 MongoDB가 할 수 있는 일은 PostgreSQL도 다 할 수 있게 되었다.

정리하면 다음과 같이 권고할 수 있겠다.

저장하려는 데이터가 단순하고, 데이터베이스에 대한 지식이 적다면 MySQL을 사용하라.

위치정보를 많이 다루고 Node.js를 사용한다면 MongoDB가 장점이 있다.

데이터베이스를 깊이 있게 배워가면서 할 생각이 있다면 PostgreSQL이 좋다.

데이터베이스 (Database)

드디어 우리 웹서비스의 데이터를 저장할 방법을 알아볼 때입니다. 보통 프론트엔드와 백엔드는 오가는 데이터를 처리하면서 일시적인 부분만을 잠깐씩 기억하면서 활용하며, 실제로 오래 보관할 내용은 데이터베이스에 기록합니다.


데이터베이스의 사전적 의미는 “잘 정돈한 데이터의 모음”입니다. 우리가 필요한 데이터를 잘 기록하면서, 필요한 때에 찾아보기 좋게 잘 정돈해 놓는 거지요. 흔히 약자로 DB라고 부르는데, 데이터 모음을 포함해서, 그 데이터 모음을 관리하는 시스템이나 소프트웨어를 뭉뚱그려 부르기도 합니다. 정확하게 말하자면, 후자는 DBMS라고 구분해서 말해야 하는데 그러지 않아도 널리 이해하는 분위기인 것 같습니다.


DB도 종류가 여럿인데, 가장 널리 쓰이는 것은 RDB라고 관계형(Relational) 데이터베이스입니다. MySQL, PostgreSQL, Oracle 등이 RDB이지요. 대부분 RDB를 쓰기에 DB라고만 해도 RDB를 뜻하기도 합니다.


DB에 컬럼, 레코드, 테이블의 구조를 갖춰 데이터를 기록하는데, 이는 우리가 흔히 쓰는 스프레드시트 프로그램의 구조와 비슷합니다. 엑셀이나 구글시트의 시트가 DB의 테이블이고, 각 시트의 행이 레코드이며, 열이 컬럼입니다. 엑셀로 가계부를 정리할 때, 날짜/내역/금액/비고 등의 열을 두고, 각각의 행에 입출금 내역을 적어 놓는 것과 같습니다.


가계부(시트) => 테이블

날짜/내역/금액/비고(열) => 컬럼

입출금 내역(행) => 레코드


영수증을 어딘가에 잘 쌓아두기만 해도 될 텐데, 왜 굳이 엑셀에 힘들게 적어 놓나요? 기초 자료를 바탕으로 잔액이나 총 지출/수입 등을 자동으로 계산할 수 있고, 특정 날짜의 항목을 찾거나, 내역의 텍스트나 금액을 기준으로 검색해서 찾아보기 쉽기 때문 아닌가요? 기록으로 보관하려는 의도도 있고, 계산과 검색이 편한 구조로 남겨두는 목적도 있습니다.


엑셀 등에 담는 시트가 테이블인 셈인데, 관계형 데이터베이스는 그 안의 여러 테이블 사이에 관계를 다루는 연산들이 있습니다. 한 테이블만을 대상으로 해서 계산하거나 검색하는 범위를 넘어서, 두 테이블 이상을 합쳐서 무언가 계산하거나 검색하는 경우도 많습니다.


DB에 연산을 요청하는 내용을 쿼리(query)라고 부릅니다. 우리말로 ‘질의’라고 번역하거나 그냥 쿼리라고 부릅니다. 이 쿼리는 꽤 유연하고 강력한 기능들이 많이 필요하기에, 하나의 언어로 되어있습니다. 이 언어의 표준 격으로 SQL(Structured Query Language, 구조화된 질의 언어)이라는 것이 있고, 각 DB 제품마다 조금씩 다른 방언(dialect)을 씁니다. 서울말을 바탕으로 한 표준어가 있고, 각 지방에서 쓰이는 방언들이 조금씩 다르지만 대개는 의사소통이 되는 것 상황과 비슷합니다. MySQL에서 쓰는 쿼리와, PostgreSQL에서 쓰는 쿼리가 거의 비슷하면서도 세세한 부분이 조금씩 다릅니다.


휴, 여기까지만 해도, 웹 개발을 위해 자바스크맆트, "루비 또는 파이썬", SQL까지 세 개의 복잡해 보이는 언어를 배워야 하게 되었네요. HTML도 사실상 마크업 언어이기 때문에 그런 것까지 언어라고 말하면 금세 더 배워야 할 언어의 수가 늘어납니다. 하지만, 언어라고 해서 너무 겁먹을 필요는 없습니다. 영어나 중국어를 배우는 것처럼 어려운 일은 아닙니다. 문서도 잘 돼있고, 보통 좋은 언어들은 그 표현 자체가 단순하며, 무엇보다 쓰는 순간마다 도와주는 도구가 아주 잘 돼 있어서, 대충 얘기해도 철석같이 잘 알아들을 수 있는 표현으로 바꿔주며, 조금이라도 틀린 표현이 나오면 자동으로 알려줍니다. 내가 콩글리시로 대충 얘기해도 늘 따라다니는 미국인이 그 자리에서 정확한 표현으로 통역해주는 상황이랄까요? 다만, 너무 어긋나면 통역이 불가능하겠지만요.


아무튼, 이쯤에서 DB도 제품을 골라야 하겠습니다. 지금 상황에서는 MySQL이 가장 널리 쓰이는 것 같습니다. 책도 많이 나와있고요. 다만 저 개인적으로는 MySQL이 오라클에 인수됐기 때문에 능동적으로 발전해 나가야 할 이유가 줄어들었다고 생각합니다. 따라서 그냥 마이SQL(MySQL)의 포크(fork)인 마리아DB(MariaDB)를 사용하면 됩니다.


다시 데이터베이스의 이용 측면으로 돌아와서, 웹 개발자 입장에서는 우리가 고른 루비나 파이썬 백엔드 프로그램에서 데이터베이스에 접근해서 새 데이터를 기록하거나, 이미 기록한 데이터를 잘 조회해서 보여주는 일을 합니다. 그때 우리가 만드는 백엔드 소프트웨어(웹서비스)가 DB와 통신하기 위해 사용하는 언어가 SQL입니다. 백엔드가 직접 SQL을 거의 그대로 쓰는 경우는 요새는 별로 없고, 그 사이에 조금 더 편리한 계층이 있습니다. 루비온레일스의 경우에는 액티브레코드(ActiveRecord)라는 라이브러리가 그 일을 합니다. DB서버가 다루는 집합(set) 구조의 레코드와 컬럼을 객채지향 프로그램에서 다루기 좋은 형태로 변환하는 일을 하지요. 이 형태가 아직 통일된 것은 아니라, 각 언어별로 조금씩 다른 구조를 취하기도 합니다. 예를 들어 자바에서는 JPA라는 표준이 있어서 그런 일을 담당합니다. 루비온레일스의 액티브레코드 같은 경우는, 적어도 제가 써 본 것들 중에는 가장 우아하고 강력한 기능을 자랑했습니다. 아무래도 이질적인 무언가를 매개하는 일을 할 때는 보다 유연한 언어가 유리한 것 같습니다.


액티브레코드처럼 훌륭한 지원 도구가 있는 경우에는 SQL을 아주 기본적으로만 알아도 됩니다. 복잡한 구문들을 액티브레코드가 대신 처리해주니까 말이죠. 하지만, 그렇다고 SQL을 몰라도 된다는 뜻은 아닙니다. 복잡하고 번거로운 작업을 아주 편리하게 대신해주는 겁니다.


그래서 DB를 하나 골라서, SQL의 기초를 공부해가며 테이블과 관계를 다루는 법을 익히면서, 우리가 택한 언어에서 널리 쓰이는 DB 접근 레이어를 써서 유연하게 데이터를 다룰 수 있게끔 공부하면 되겠습니다.


DO: 마리아DB(MariaDB)

DON’T: Oracle nor SQL Server


완전히 다른 얘기로, 데이터베이스라는 것이 결국, 우리가 만드는 웹서비스에 잘 정리하고 나중에 찾아볼 데이터를 잘 다룰 수 있으면 되는 겁니다. 그 형태가 꼭 관계형 DB일 필요는 없지요. 만약 그냥 디스크에 파일로 저장하거나 엘라스틱 서치 같은 검색 엔진에 부어 넣고도 내가 원하는 기능을 만들 수 있다면 그렇게 쓰면 됩니다. 그래서 RDB 말고도 MongoDB나 AWS의 DynamoDB를 비롯해서 다양한 형태의 데이터베이스가 널리 쓰이고 있습니다. 어쩌면 사람들이 너무 RDB에 치우쳐 있기에, 경우에 따라 다른 방식의 접근이 더 좋은 경우도 있다는 것을 잊게 되기도 하는 것 같습니다. 그리고 RDB를 쓴다고 해서 반드시 100% 모든 데이터를 RDB에 담아야 하는 것도 아닙니다. 대부분은 RDB에 담고, 경우에 따라서 다른 형태로 저장해도 되지요. 그러니 RDB를 공부한다고 해서, 세상의 데이터베이스가 RDB가 전부다라는 생각으로 굳어지지는 말아야 하겠습니다. 분명, RDB는 오랜 기간 발전하면서 매우 성숙한 제품과 기술들이 함께 진보했기 때문에 가장 안전한 선택입니다만 말이죠.


괜한 딴 얘기를 했네요. 우선 RDB 하나 골라서 공부하며 씁시다! RDB의 단점으로 지적되는 부분들이, 적어도 우리가 목표로 하는 동네 웹서비스 영역에서는 문제점으로 드러날 일은 없다고 생각해요. 나중에 AWS를 언급하면서 RDS 서비스를 말씀 드릴 텐데, MySQL, PostgreSQL 다 편하게 쓸 수 있으니, 고르시기만 하면 됩니다. 거 참 좋은 세상!


요약: 마리아DB(MariaDB)를 고르고, SQL을 공부해 가며, 내가 택한 언어의 DB 접근 라이브러리를 써서 연습한다.


데이터베이스 기술

* 오픈 소스 / 퍼블릭 도메인


자료 구조

(data structures)

자료 구조는 자료를 효과적으로 잘 쓸 수 있도록 잘 정리하는 방법을 부르는 말입니다. 자료가 많지 않을 때야 아무렇게나 보관해도 찾을 수 있겠지만, 분량이 많아지면 나름의 정리 방법이 필요한 상황을 생각해보면 될 것 같아요. 자료를 장 정리해 둔다는 면에서 2편에 말씀드린 “데이터베이스”와 비슷한 영역이라고 볼 수도 있는데, 꼭 그런 건 아니지만, 보통 데이터베이스는 디스크에 저장하는 반영구적(persistent) 데이터를 다루고, 자료구조는 주로 프로그램이 실행되는 동안 메모리에 있는 데이터를 다룬다고 생각하면 이해가 쉬울 것 같습니다. 실상은, 데이터베이스도 내부적으로 갖가지 자료 구조를 활용하고, 디스크에 저장하는 목적의 자료 구조도 많으니 자료 구조가 더 포괄적인 개념이겠지만요.


아무튼, 자료 구조는 데이터를 잘 정리하는 나름의 방법을 말합니다. 예를 들어, 내 방 책장에 책을 꽂을 때야 아무렇게나 대충 꽂아 놓아도, 필요할 때 원하는 책을 찾아서 볼 수 있겠지만, 도서관이나 서점에서는 상황이 달라지잖아요? 크게는 도서 분류별로 구분된 영역에 위치하고 있을 테고, 같은 소분류 내에서도 도서명의 가나다 순으로 정렬되어 있겠지요. 그것만으로도 충분하지 않으니, 곳곳에 도서 검색용 PC가 있어서 원하는 책의 제목이나 저자 이름이나, ISBN 기준 등으로 다양하게 검색하는 방법이 준비돼 있지요.


우리가 작성하는 프로그램으로 다루는 데이터를 잘 보관하는 방법도 그렇습니다. 단순히 아무렇게나 늘어놔 놓고, 필요할 때 일일이 찾아보는 방법도 있고, 아니면 어떤 분류법을 써서 자주 사용하는 패턴에 맞게 효과적으로 찾을 수 있는 형태로 잘 보관하기도 합니다. 어떤 자료 구조로 저장하느냐에 따라 어떤 활용에는 효율적이고, 다른 활용에는 비효율적일 수도 있습니다. 전문 용어로 계산 복잡도(computational complexity)가 다르다고 말합니다. 예를 들어, 명함을 가나다 순으로 정리해 두었다면, 특정 성명으로 전화번호를 찾기에는 좋지만, 어떤 모르는 발신 번호가 떴을 때 그 번호가 누구의 것인지를 찾는 데 쓰기는 어려운 것처럼요.


자료 구조는 데이터를 잘 정돈하고, 또 효과적으로 운용하는 방법과 관련이 커서 흔히 알고리즘과 뗄 수 없는 단어이기도 합니다. 우선은 기본 자료 구조와 그걸 다룰 때의 특성 정도만 알고 있으면 좋겠습니다. 기초 자료 구조는 보통의 프로그래밍 언어에 기본으로 포함돼 있고, 그걸 다루는 알고리즘을 잘 구현해낸 코드도 함께 준비돼 있어서, 우리가 직접 자료 구조를 구현하거나 알고리즘을 코드로 표현할 일은 별로 없습니다. 설령 기초 수준을 넘어서는 고급 자료 구조가 필요하더라도, 누군가 남이 잘 만들어 놓은 것을 가져다 쓰면 됩니다. 하지만, 그 특성과 상황별 효율은 알고 있어야 상황에 맞게 적절한 자료 구조를 골라서 쓸 수 있습니다. 또, 공부하다가 관심이 생긴다면 깊게 파고들어서 직접 만들어 보는 것도 좋은 공부가 되는 것 같습니다. 만약 관심이 있다면 말이죠.


사실 우리가 만들려는 2층 목조 주택 같은 아담한 나만의 웹 서비스를 만드는 경우에는 별다른 자료 구조를 의식하지 않고도 대부분의 일을 처리할 수 있을 텐데요, 그럼에도 이 연재에 한 꼭지 틀고 앉히는 이유를 굳이 꼽아본다면, 우선, 대강이라도 알아두면 어디 가서 개발할 때 쫄리지 않습니다. 혹시나 개발을 본격적으로 시작하신다면 반드시 알아야 할 주제이기도 하고요. 그리고, 은근 어려워 보이지만, 꽤나 재밌는 분야이기도 합니다. 무엇보다, 모든 프로그래밍 언어마다 기본적인 자료 구조를 다루는 내용들이 들어있고 그걸 기반으로 코딩하게 되는데, 그게 당최 뭔 소리인지 알 수 있게 해주기도 하기 때문입니다.


프로그래밍 언어마다, 그 언어 기본으로 제공하는 자료 구조는 조금씩 다르지만, 대개는 아래 나열한 정도가 기본입니다.


배열(array) — 데이터들을 차례로 인덱스를 부여하며 순차적으로 나열

리스트(list) — 데이터들을 서로 줄기로 엮어서 다음 데이터들을 연결

해쉬(Hash, Dictionary) — 데이터의 기준값을 나름의 방법으로 분류해 정리

트리(tree) — 데이터들을 몇 단계로 분류를 거치며 계층적으로 정돈


  • 개알못인 당신이 웹개발을 시작한다면 (4)

https://medium.com/happyprogrammer-in-jeju/%EA%B0%9C%EC%95%8C%EB%AA%BB%EC%9D%B8-%EB%8B%B9%EC%8B%A0%EC%9D%B4-%EC%9B%B9%EA%B0%9C%EB%B0%9C%EC%9D%84-%EC%8B%9C%EC%9E%91%ED%95%9C%EB%8B%A4%EB%A9%B4-4-61d43afbcb53

배열(Array)과 리스트(List)

배열과 리스트는 비슷한 데이터들을 나름의 순서로 나열해 놓는다는 점에서 비슷합니다. 정해진 순서로 늘어놓아도 되고, 꼭 순서가 없어도 무방합니다. 그저 차례로 줄지어 늘어놓은 구조일 뿐입니다. 체육 시간에 운동장에서 뛰노는 학생들을 선생님이 불러서 그냥 아무렇게나 한 줄로 서라고 해서 줄지어 세울 수도 있고, 때에 따라서는 키순으로 서라고 할 때도 있는 것처럼요. 키 순으로 서라고 하면, 제일 작은 학생을 찾기도 편하고, 제일 큰 학생도 찾기 편하고, 중간 키인 학생을 찾기도 편하지요.


배열은 인덱스라고 부르는 숫자를 기준으로 접근하기 쉬운 구조로 되어있습니다. 학교 다닐 때 수학 시간에 배우는 수열과 비슷합니다. 수열을 이루는 구성원을 수열의 항이나 원소라고 하는데, 그 구성원 하나하나를 몇 번째 원소인지 지칭하기 좋잖아요? 그 수열의 길이(length)라는 것도 있고요. 무한수열을 표현할 수도 있습니다만, 보통의 경우 유한 수열로 씁니다. 배열에 정해진 길이 n이 있고, 그 안에 여러 원소(데이터)들을 보관하지요.


예를 들어, 10 이하 양의 짝수를 표현하는 수열 e가 있다면,


e[i] = (2, 4, 6, 8, 10)


이때, 첫 번째 원소는 2이고 마지막 원소는 10이며, 이 배열의 길이(length)는 5입니다. 이걸 프로그램으로 표현한다면, 다섯 개 요소를 보관할 수 있는 정수 배열을 만들고 차례로 짝수들을 보관해 두었다가, 필요할 때 쓸 수 있지요.


수열로 예를 들었지만, 배열 안에 들어가는 것이 반드시 숫자일 필요는 없고요, 우리가 원하는 아무 데이터나 넣으면 됩니다. 필요에 따라 차례로 접근해서 어떤 작업을 하기도 하고, 아니면 임의의 위치를 인덱스로 콕 집어서 찾아 쓰기도 합니다. 배열의 인덱스와 수열의 몇째 항인가 하는 표현이 거의 같은데, 다만 보통 프로그래밍 언어에서는 첨자가 0에서 시작합니다. 첫째 항이 0번 항이고, 둘째 항의 인덱스는 1입니다. 단지 시작 값이 다른 것뿐이에요.


e[0] = 2, e[1] = 4, ... e[4] = 10


한편 (연결) 리스트는 배열과 비슷합니다만, 자료를 보관하는 내부 구조에 인덱스가 있는 것이 아니라, 단지 임의의 순서만 있습니다. 각 값에 그 다음 값이 무언지 연결하는 고리(링크, link)가 있어요. 그래서 리스트의 첫 번째 요소로부터, 그다음 요소를 차례로 따라가면서 원하는 일을 할 수 있어요. 리스트의 첫번째 요소만 잘 갖고 있으면서, 필요할 때 거기서부터 찾아들어갑니다.


리스트도 모든 요소를 차례로 접근하는 것은 똑같이 할 수 있지만, 임의의 몇 번째 요소를 콕 집어서 찾아오는 데에는 배열에 비해 불리합니다. 대신, 리스트는 그 길이를 미리 정할 필요가 없이, 계속 크기를 늘리기 좋습니다. 그리고 중간에 어떤 요소를 끼워넣기도 편리합니다. 반면 배열의 경우 그 배열 중간에 어떤 값을 끼워 넣으려면, 그 뒤 요소들을 다 밀어내야 하는 불편함이 있습니다. 그래서 똑같이 차례로 늘어놓는 비슷한 데이터에 대해서도 어떨 때는 배열이 편리하고, 어떨 때는 리스트가 유리합니다. 효율의 차 이이지, 둘 다 할 수 있다는 점에서는 차이가 없어요. 예를 들어, 리스트라고 해서 몇 번째 요소가 뭔지 찾을 수 없다는 뜻이 아닙니다. 필요할 때, 처음부터 차례로 이동해가면서 몇번 째 요소를 찾아내면 됩니다. 그 길이도 끝까지 한번 가보면 알 수 있지요. 배열도, 배열의 길이를 늘리려면, 더 큰 크기의 배열을 만들어서, 원래 배열의 내용을 복사하면 됩니다.


보통, 원소들의 개수를 미리 알 수 없는 경우에는 리스트를 쓰고, 원소들의 개수가 정해져 있거나 임의의 위치를 콕 집어서 접근할 일이 많을 때는 배열을 씁니다. 또, 언어에 따라서 기본 문법에 배열이 편리한 경우가 많아서, 대부분의 경우 배열을 우선시하기도 합니다.


해시

(Hash, aka. Dictionary)

해시는, 데이터의 순서는 상관없이 어떤 특정 데이터를 빠르게 찾기 좋은 자료 구조입니다. 아마 우리 두뇌 속에 사람 얼굴을 판단하는 구조가 해시와 비슷하지 않을까 합니다. 어떤 사람의 인상착의를 보면, ‘아 저게 누구다’라는 머릿속 데이터를 뿅 하고 순간적으로 아는 상황과 비슷합니다. 인상착의라는 해시 함수가 있는 거고, 거기에 엮인 그 사람에 대한 정보들이 줄기로 엮여 나오지요. 만약 우리 머릿속에 있는 사람에 얼굴에 대한 데이터가 리스트나 배열로 되어있다면, 길을 가다 아는 사람을 만났을 때조차, 매번 일일이 그 인상착의 데이터를 순차적으로 뒤져봐야 한다면 너무 오래 걸려서, 결국 그 사람이 누구였는지는, 그 사람과 헤어지고 나서야 알까 말까 할 정도로 느리겠지요.


해시 구조를 쓰면 인상착의로부터 순간적으로 빨리 원하는 데이터를 찾기는 아주 유용하지만, 대신 이게 순서를 기준으로 찾기는 어렵습니다. 예를 들어, A라는 사람과 아주 비슷하게 생겼는데, 그보다는 조금 눈이 큰 사람이 누구인가? 이런 건 따로 찾을 수 없지요. 그저, 누군가의 얼굴을 딱 봤을 때, “아 내가 아는 사람이다 or 아니다”, “아는 사람인데 그 인간이 어떤 인간이다” 이런 데이터를 찾기(lookup) 좋은 구조입니다. 우리가 알고 있는 얼굴을 모두 찾아내는 것도 어렵습니다.


혹시 "내가 인상착의를 알고 있는 사람이 총 몇 명인가?" 이런 정보 쉽게 생각해 내시는 분 있으면 제보 바랍니다.


해시에는 그 데이터를 대표하는 키 값이라는 것이 있고, 그 키 값으로부터 특정 인덱스를 뽑는 해시 함수(Hash Function)가 있습니다. 키 값에 따라 골고루 이 인덱스를 흩어 놓아서 데이터 공간을 효과적으로 사용할 수 있는 함수가 해시함수에 유용합니다. 조금 전 예를 든 상황에는 인상착의라는 것이 그 사람에 관련한 데이터의 키값인 거고, 그 얼굴로부터 모종의 특징을 추려서 머리속에 보관하는 해시 함수가 우리 본능에 프로그래밍되어 있는 거지요.


가장 이해하기 쉬운 해시 함수는 아마도 영어사전을 찾을 때 쓰는, 알파벳 첫 글자가 아닐까 합니다. programming이라는 단어를 찾고자 한다면, p섹션으로 가서 알파벳 순으로 찾아보잖아요? 이 경우 p를 추출하는 함수가 해시 함수인 셈입니다. p섹션으로 빠르게 이동해서, 거기서 데이터를 찾아보고 있으면 그걸 돌려주면 되고, 없으면 사전에 없는 데이터인 겁니다. 이렇듯 역할이나 활용이 사전과 비슷해서 Dictionary라고도 부르나 봅니다. 사전의 경우, 정확하게 말하자면, 알파벳 순으로 정렬된 리스트/배열의 구조 위에 알파벳 첫 글자를 따는 해시로 인덱스를 부여해서 더 빠르게 찾을 수 있는 구조입니다. 이렇게, 몇몇 자료구조를 병용해서 원하는 활용에 조합해 쓰기도 합니다.


그나저나 최근 종이책 사전을 본 적이...


트리(Tree)

트리는 계층적인 구조를 다룰 때 쓰기 좋은 자료 구조입니다. 나무의 뿌리(root)로 시작해서 여러 가지가 갈라지며 마지막에 나뭇잎(leaf)이 달려있는 모양새를 연상해서 트리라고 이름 지었나 봅니다. 보통의 나무들이 가지가 갈라졌다가 다시 만나는 경우는 없을 텐데요, 트리 구조도 그렇습니다. 보통 그림으로 표현할 때는 거꾸로 루트(root) 노드를 제일 위에 그리고, 아래로 차례로 이어 그립니다.


그리는 표현으로 보자면, 회사나 단체의 조직도와 더 유사합니다. 조직도 제일 위에 회사 사장이 있고, 그 아래에 부문별 이사들이 있고, 이사들 아래에 부장들이 있는 식으로요. 다만 회사에는 겸직이라는 희한한 직책이 있지만, 트리에는 합쳐지는 가지가 없습니다. 암튼, 각각의 요소를 노드(node)라고 부르며, 각 노드는 해당하는 요소(값)와 여러 하위 노드를 가르키는 연결 고리가 있습니다. 리스트의 각 원소가 다음 요소를 가리키는 링크가 있는 것과 비슷한데, 트리의 경우 각 노드 별로 두 개 이상의 연결 고리가 있습니다. 각 노드마다 연결 고리가 최대 두 개까지만 있는 트리를 이진트리(Binary tree)라고 따로 부르기도 합니다.


다소 어렵게 느껴지는 트리를 알아야 하는 이유는, 트리로 무언가 계층적인 구조를 다루기에 편리하고, 계층적인 구조로 무언가를 다루는 일은 개발할 때 여러모로 유용해서, 트리의 쓰임새도 덩달아 많기 때문입니다. HTML을 이미 공부하셨다면, DOM 트리라는 표현도 들어보셨을 텐데요, HTML 문서도 트리로 표현합니다. <ul> 노드가 있고, 그 자식들로 <li> 노드들이 붙어 있는 상황이 딱 트리 구조인 셈이죠. 루트 노드가 <html>이고요. 우리가 루비, 파이썬, 자바스크립트 등의 언어로 프로그래밍할 때의 소스코드(텍스트)도 AST라는 트리 구조로 변환되는 과정이 들어있습니다. 자세히 알 필요는 아직 없지만, 뭐가 됐든 암튼 꽤 많이 쓰인다고 알고 넘어가 보기로 해요. 그리고, 트리 구조로 자료를 정렬해 두면, 대량의 데이터를 검색하는 데에도 매우 효과적으로 활용할 수 있습니다. 그래서 2편에 설명드린 데이터베이스도 내부적으로는 B-tree라는 트리 구조를 활용해서 데이터를 색인(index)해 둡니다. 덕분에 아주 많은 데이터 중에서도 순식간에 데이터를 찾아낼 수 있습니다.


트리는 그 쓰임새도 다양하고, 또 그만큼 종류도 다양합니다. 우선은 이 정도로만 알고, 기회가 되면 자세히 알아보기로 해요. (솔직히 말해 제가 잘 설명할 자신이 없네요)

계산 복잡도

(Computational Complexity)

어떤 자료 구조를 쓰면서 특정 연산을 하는데 얼마나 복잡한가를 평가하고 예측하는 것이 ‘계산 복잡도’입니다. 얼마나 복잡한지를 알 수 있으니, 덜 복잡한 구조로 되어 있다면, 반대로 말해 효율적이라는 얘기입니다. 앞서도 언급했듯, 그 자료구조를 활용하는 알고리즘과 직결된 내용이라서, 알고리즘 책에서 배울 수 있는 내용입니다.


원하는 작업을 하는데, 얼마만큼의 메모리나 디스크 공간을 필요로 하는지를 ‘공간 복잡도’(space complexity)라고 하고, 얼마나 빠르게 처리할 수 있는지를 ‘시간 복잡도’(time complexity)라고 말합니다. 어떤 자료 구조를 쓰는 어떤 알고리즘은 시간은 빠르지만 메모리를 많이 쓴다거나, 반대로 어떤 알고리즘은 원하는 일을 하는 시간은 매우 오래 걸리지만, 아주 적은 메모리로도 원하는 작업을 끝낼 수 있기도 해서 둘 다를 고려하기도 합니다. 하지만 별도로 굳이 언급하지 않는다면, 보통 ‘시간 복잡도’를 얘기하는 편입니다. 즉, ‘계산 복잡도’라고 하면, 어떤 데이터로 어떤 작업을 하는데 걸리는 시간의 정도라고 생각하시면 크게 어긋나지는 않을 것 같습니다.


이 복잡도를 평가하고 예측하는 기준으로, 빅 오 표기법(Big O notation)을 씁니다. 언뜻 보기엔 단순히 정해진 테스트 작업을 두고 몇 초에 다 처리할 수 있는가 같은 기준을 쓰면 될 것 같지만, 그러면 해당 자료구조나 알고리즘을 어떤 프로그래밍 언어로 어떤 하드웨어에서 구현해 실행하는가에 따라 수시로 달라지기 때문에 유용한 잣대가 되지 않습니다. 그래서 몇 가지 기준을 정해서 쓰는데, 그중 하나가 빅 오 표기법입니다. 알파벳 대문자에 이어 괄호를 열고 수식 같은 게 들어 있습니다.


O(1), O(log n), O(n), O(n log n), O(n^2), O(2^n), O(n!)


이런 식으로요. 다른 개발자들과 말할 때는 오 원, 오 로그 엔, 오 엔, 오 엔 로그 엔, 오 엔 스퀘어, 오 엔 팩토리얼로 읽습니다. 2^n은 뭐라고 읽는지 모르겠습니다. 지수 시간이 걸린다고도 하고, exponential(기하급수적)이라고도 하는데, 정식으로는 뭐라고 부르는지 모르겠네요. 그리고, 우리말로 오 일, 오 엔 제곱 등으로 얘기해도 다른 사람이 알아는 듣겠습니다만, 꽤 생소해할 거예요. 이 표기법은, 데이터가 꽤 많이 있을 때, 자료의 건수에 비해 어느 정도로 오래 걸리는가를 의미하는데요, 예를 들어, O(n)의 경우는 데이터가 n건 있을 때 n만큼의 시간이 걸린다는 뜻으로, 데이터 분량에 비례해서 점점 오래 걸린다는 뜻입니다. O(1)의 경우는 데이터의 건수와 상관없이 늘 똑같은 시간이 걸린다는 뜻으로, 아주 효과적임을 뜻합니다. O(log n) 같은 경우 로그 n에 비례하는 시간이 걸린다는 뜻이라서, 데이터가 아주 많아도 꽤 효과적으로 일을 할 수 있습니다. 이진 검색처럼 log의 밑수가 2인 경우가 많아서 O(log n)이라고 하면 흔히 지수가 2인 로그를 뜻하기도 합니다.


뭐가 뭔지 어렵다면, 일단 O(1) = 아주 빠른 것에서부터 뒤로 갈수록 더 느려지는 거라고 생각하셔도 됩니다.


O(1) < O(log n) < O(n) < O(n log n)


이 정도만이라도 기억하면 좋고요, 앞서 자료 구조에 대해서 몇 가지 주요 연산에 대해서만이라도 빅 오 표기법으로 대략 알면, 당장은 충분한 수준인 거죠.


배열(Array)에서 몇 번째 데이터를 가져오는 연산은, 배열은 이미 인덱스가 갖춰져 있기 때문에 O(1)에 빠르게 끝낼 수 있습니다. 그러나 배열의 중간, 예를 들어 두 번째, 자리에 어떤 데이터를 넣는 연산은, 그 원래 있던 두 번째 자리 데이터와 그 뒤의 데이터들을 차례로 다 밀어내야 해서 O(n)의 시간이 필요합니다. 데이터 건수에 비례하는 시간이 걸리는 거지요.


반대로 리스트의 경우 특정 위치에, 특히 맨 앞에, 값을 추가하는 일은 아주 간단합니다. 그저 원하는 위치에 데이터를 넣고 앞뒤 데이터의 연결고리만 잘 연결지으면 나머지는 그대로 놔둬도 됩니다. O(1)에 끝낼 수 있지요. 하지만, 전체 데이터의 건수를 센다거나, 특정 몇 번째 요소를 찾고자 하는 일은 데이터를 일일이 순회해야 하기 때문에 O(n)의 시간이 걸립니다.


해시의 경우 어떤 자료구조로 구현하느냐에 따라 조금 달라지기도 합니다만, 보통은 해시함수를 한번 거쳐서 원하는 위치를 배열처럼 뿅 찾아가기에 O(1)의 아주 빠른 속도로 원하는 데이터가 있는지 없는지, 있다면 무엇인지 알 수 있습니다. 실상은 해시 충돌(collision)이라는 게 있어서 정확하지는 않지만 일단 O(1)이라고 보면 됩니다. 대신 순서상 몇 번째 데이터를 찾는다거나 전체 건수를 알기는 어렵습니다.


그리고 트리는, 만약 정렬해둔 이진트리라면 밑수가 2인 로그 n에 비례해서, 아주 데이터가 많더라도 아주 빠르게 데이터를 검색할 수 있는 구조입니다. 그리고 데이터를 추가하거나 삭제하는 시간도 매우 빨라서 대량의 데이터를 다루는 데에 유용합니다.


마무리

이제껏 설명드린 주제들 중에 어쩌면 가장 어려운 내용일지도 모르겠습니다. 아니면 단지 제가 쉽게 설명할 내공이 없어서 그럴지도 모르고요. 유독 틀린 내용이 많을 것 같기는 한데, 부담 없이 지적해주세요. 저도 공부하는 의미가 될 테니 감사한 일이죠.


마무리로, 이 연재의 하이라이트, 할 것과 하지 말 것을 정리하겠습니다.


Do: 배열, 리스트, 해시, 트리, 그리고 그 시간 복잡도

Don’t: 알고리즘 컨테스트 공부, 코딩 인터뷰 준비 등


물론, 취업이나 이직을 목표로 하고 있다면, 알고리즘 컨테스트나 코닝 인터뷰 문제 풀이가 아주 큰 도움이 되겠습니다만, 만약 제 연재의 컨셉인 간단한 웹서비스 직접 만들기에는 전혀 도움이 되지 않으므로, 무시하고 넘어가도록 합시다.

ORM

(Object-Relational Mappings)


  • ORM 이란 무엇인가?

ORM(Object-Relational Mappings)라는 건 과연 무엇일까? 근래 많이 보고 듣는 단어이고 ORM Framework이나 Tool이니 하면서 Hibernate나 iBatis, Toplink등등의 이름들도 많이 듣게 된다. 과연 이 ORM이라는 것이 무엇이길래 왜 이렇게 많은 사람들의 입에 오르내리는 것일까?

http://civan.tistory.com/156


  • ORM (Object Relational Mapping) 과 SQL Mapper 정의

http://beji.tistory.com/entry/ORM-Object-Relational-Mapping-%EA%B3%BC-SQL-Mapper-%EC%A0%95%EC%9D%98


  • ORM의 사실과 오해

https://okky.kr/article/286812

역사

프로세서, 컴퓨터 메모리, 컴퓨터 스토리지, 컴퓨터 네트워크 분야에서 기술이 진전됨에 따라, 등급 순으로 데이터베이스 및 각 DBMS의 크기, 기능, 성능이 상승해왔다. 데이터베이스 기술의 발전은 데이터 모델이나 구조에 따라 세 개의 시대로 나뉜다: 내비게이셔널 데이터베이스,Template:Sfn SQL/관계형 데이터베이스, 관계형 이후 데이터베이스.

주가 되는 2개의 내비게이셔널 데이터 모델은 IBM의 IMS 시스템의 전형적 본보기가 되는 계층형 모델, 그리고 IDMS와 같은 수많은 제품들에 구현된 CODASYL 모델 (네트워크 모델)이다.

1970년에 에드거 F. 커드가 처음 제안한 관계형 모델은 응용 프로그램들이 뒷따르는 링크가 아닌 내용을 기준으로 데이터를 검색해야 한다고 주장하면서 이러한 전통에서 출발했다. 관계형 모델은 금전출납부 스타일의 표들의 모임을 이용하며, 각각은 다른 타입의 엔티티를 위해 사용된다. 1980년대 들어서야 컴퓨팅 하드웨어가 비로소 관계형 시스템(DBMS + 애플리케이션)의 폭넓은 배치를 가능케 할 만큼 강력해졌다. 그러나 1990년대 초 들어서 모든 대형 데이터 처리 애플리케이션을 관계형 시스템들이 지배하게 되었으며 2015년 기준으로 여전히 상황은 동일하다. : IBM DB2, 오라클, MySQL, 마이크로소프트 SQL 서버는 최상위 DBMS이다.[2] 지배적인 데이터베이스 언어, 곧 관계형 모델을 위한 표준화된 SQL은 다른 데이터 모델의 데이터베이스 언어들에 영향을 미쳤다.

객체 지향 데이터베이스객체 지향 임피던스 불일치의 불편함을 극복하고자 1980년대에 개발되었으며, 이로 인해 "관계형 이후"(post-relational)라는 용어가 만들어졌고 하이브리드 객체 관계 데이터베이스의 개발로도 이어졌다.

2000년대 말에 관계형 이후의 차세대 데이터베이스는 NoSQL 데이터베이스로 알려지게 되었으며, 고속의 키-값 스토어, 도큐먼트 지향 데이터베이스를 도입하였다. NewSQL 데이터베이스라는 경쟁력 있는 차세대 데이터베이스는 상용 관계형 DBMS 대비 NoSQL의 높은 성능에 부합하면서 관계형/SQL 모델을 보유하는 새로운 구현을 시도하였다.

데이터베이스의 개념

여러 사람들이 공유하고 사용할 목적으로 통합 관리되는 정보의 집합이다. 논리적으로 연관된 하나 이상의 자료의 모음으로 그 내용을 고도로 구조화함으로써 검색과 갱신의 효율화를 꾀한 것이다. 즉, 몇 개의 자료 파일을 조직적으로 통합하여 자료 항목의 중복을 없애고 자료를 구조화하여 기억시켜 놓은 자료의 집합체라고 할 수 있다.

공동 자료로서 각 사용자는 같은 데이터라 할지라도 각자의 응용 목적에 따라 다르게 사용할 수 있다.

  • 데이터베이스의 특징
  1. 실시간 접근성
  2. 지속적인 변화
  3. 동시 공유
  4. 내용에 대한 참조
  5. 데이터 논리적 독립성

데이터베이스의 장단점

  • 데이터베이스 장점
  1. 데이터 중복 최소화
  2. 데이터 공유
  3. 일관성, 무결성, 보안성 유지
  4. 최신의 데이터 유지
  5. 데이터의 표준화 가능
  6. 데이터의 논리적, 물리적 독립성
  7. 용이한 데이터 접근
  8. 데이터 저장 공간 절약
  • 데이터베이스 단점
  1. 데이터베이스 전문가 필요
  2. 많은 비용 부담
  3. 데이터 백업과 복구가 어려움
  4. 시스템의 복잡함
  5. 대용량 디스크로 엑세스가 집중되면 과부하 발생

데이터베이스 모델

Template:본문 실제적인 데이터베이스 구현을 위한 현재 몇몇 개념화된 논리적 데이터 모델은 다음과 같다:

관계 데이터 모델

Template:본문 관계 데이터모델 (relational datamodel)은 데이터 모델 중에서 가장 개념이 간단한 모델이다. IBM 연구소에서 근무하던 코드(E.F.Codd)가 1970년에 제안했다. 이 모델은 상대 수학적인 이론을 기반으로 한다. 코드가 수학자였기 때문에 수학 분야, 특히 집합론과 논리분야의 개념을 사용했다. 데이터 모델을 개발하기 위해서 테이블 관계로 묘사하는 이론적 모델 과정이 발생하는데 이를 개체관계모델(영어:entity relational model)이라고 한다. 이 관계 데이터베이스를 위한 설계과정은 이론적으로 관계수학에 기초한 실지 구현이라 보면 된다. 현실 세계는 객체관계 그림(diagram)으로 표현되며, 개체와 그 관계는 각기 사각과 선으로 그려진다.

SQL

개체 관계형 데이터베이스를 지원하기 위해 1974년 IBM 연구소에서 만든 SQL(Structured Query Language)(원어(SEQUEL):Structured English Query Language)가 창안되었으며, 이 언어는 수학적 관계 대수관계 논리(relational calculus)에 기반을 두고 있다. 데이터 모델은 데이터를 조작하기 위한 연산집합을 가져야 한다. 왜냐하면 그것은 데이터베이스 구조와 제약 조건을 정의하기 때문이다. 다시 말해, 관계 데이터모델 연산집합(a set of operations)은 관계대수로 표현되고, 그 연산은 사용자에게 여러 질의를 가능하게 한다.

데이터베이스 관리 시스템 선택

데이터베이스 설계 후 데이터베이스 관리 시스템을 사용해야 한다. 여러가지 데이터베이스 관리 시스템 선택 사항(DBMS)이 존재한다.

데이터베이스 관리 시스템으로 현재에는 많이 사용하지 않으나 IBM 메인프레임 환경 하에서 운영되는 'IMS'가 있다. IMS는 정보 관리 시스템(Information Management System)의 약자로 DBMS와 DC 기능을 수행한다. IMS가 관리하는 DB 종류에는 'DEDB'와 'MSDB'가 있다. DEDB는 Data Entry DB로 전통적인 계층형 DB이며 MSDB는 주기억 DB로 시스템 가동시 주 메모리에 상주하는 DB로 빠른 접근이 필요한 업무에 사용된다. 다만, 접근 속도가 매우 빠른 반면 메모리에 상주하기 때문에 용량 및 구조에 제한이 많다.

DBMS 언어 선택

데이터베이스 언어는 다음과 같이 이루어져 있다.

트랜잭션

Template:본문 트랜잭션은 하나의 논리적 단위를 구성하는 데이터베이스 연산의 모임이다. 동시에 여러 트랜잭션이 수행되기 위해서 데이터베이스의 일관성이 보장되어야 하며 이를 위해 동시성 제어(concurrency control)와 회복 제어(recovery control)를 위한 모듈이 있으며 이 둘을 합쳐 트랜잭션 관리 모듈(transaction management module)이라고 한다.

  1. 동시성제어 모듈(concurreny control module): 데이터베이스를 일관성 있게 유지하기 위하여 동시에 수행되는 트랜잭션들 사이의 상호작용을 제어한다.
  2. 회복제어 모듈(recovery control module): 데이터베이스를 일관성 있게 유지하기 위하여 업데이트를 하는 동안 시스템 장애에도 데이터베이스의 기존 상태가 유지된다.

트랜잭션 스케줄링은 다음과 같은 3가지 개념을 가진다.

  1. 직렬 스케줄링(serial scheduling): 트랜잭션 연산들을 각 트랜잭션별로 연속적으로 실행하는 방법
  2. 비직렬 스케줄링(nonserial scheduling): 트랜잭션 연산들을 상호적(interleaving)으로 병행 실행하는 밥법
  3. 직렬 가능 스케줄링(serializable schedlung): 비직렬 스케줄링 S가 항상 직렬 스케줄링 SS에 대해서 같은 결과를 가질 때 "S를 직렬가능"하다고 한다.

직렬가능 트랜잭션을 보장하기 위한 규약(protocol)이 있는데 잠금(locking) 방법과 시간표(timestamp)가 바로 그것이다.

데이터베이스 자료구조

인덱싱

데이터베이스는 흔히 다음과 같은 ACID 규칙을 만족해야 한다.

  • 원자성 (原子性, Atomicity): 한 트랜잭션의 모든 작업이 수행되든지, 아니면 하나도 수행되지 않아야 한다. 트랜잭션이 제대로 실행되지 않았으면 롤백(roll back)한다.
  • 일관성 (一貫性, Consistency): 모든 트랜잭션은 데이터베이스에서 정한 무결성 (無缺性, integrity) 조건을 만족해야 한다.
  • 격리성 (隔離性, Isolation): 두 개의 트랜잭션이 서로에게 영향을 미칠 수 없다. 트랜잭션이 실행되는 동안의 값은 다른 트랜잭션이 접근할 수 없어야 한다.
  • 내구성 (耐久性, Durability): 트랜잭션이 성공적으로 끝난 뒤에는, (시스템 실패가 일어나더라도) 그 결과가 데이터베이스에 계속 유지되어야 한다.

병행제어 (竝行制御, concurrency control)는 트랜잭션을 안전하게 처리하고 ACID 규칙을 만족시키는 기술이다.

데이터베이스의 수요

2012년 한국의 국내 DB산업은 DB구축 시장, DB컨설팅·솔루션 시장, DB서비스 시장 등 모든 분야에서 전년 대비 높은 성장세를 나타내고 있다. 특히 전 산업에서의 정보통신기술(ICT) 융합과 스마트 환경 확산, 빅데이터 관련 수요가 증가하면서 향후 그 성장세는 계속될 것으로 내다봤다. 보고서에서는 DB산업의 성장을 내다보는 주요 요인으로 빅데이터 분석·활용을 위한 기업의 신규 수요 증가, DB자산 가치 인식 증대로 인한 DB구축 투자 증가, 스마트 기반의 모바일 서비스 확산 등을 꼽고 있다.[3]

각주

참고 문헌

  • Elmasri, Navathe:Fundamentals of database systems, Addision Wesley.

바깥 고리

Template:데이터베이스 Template:Authority control