반응형

NoSQL이란? 
NoSQL은 SQL만을 사용하지 않는 데이터 베이스로 관계형 데이터 베이스와는 다른 방식으로 데이터를 저장한다. 다만, NoSQL의 경우 한 가지로 정의하기엔 힘든 부분이 RDBMS의 경우 쿼리 언어가 비슷한 반면, NoSQL의 경우 각 SQL에서 사용하는 쿼리 언어들이 다른 편이기 때문에 NoSQL로 엮여있는 데이터 베이스라고 하더라도 각각의 성격이 조금씩은 차이가 나는 경우들이 많다. 그렇기에 조금씩 성격은 다르지만, 대부분이 Schema-less 데이터베이스라는 점에선 동일하다.

 

MongoDB란?

큰 분류로는 Key-value, Document, Column-family, Graph 모델로 나뉘는데, 그 중 도큐먼트 지향 데이터베이스 시스템이 MongoDB이다. 그 외에도 Couchbase나 CouchDB 등이 도큐먼트 데이터베이스 시스템을 이용하고 있다.

Document Database의 경우, Key-Value Database와는 달리 값을 document 형태 (json, xml 등의 표준 형식) 로 저장한다는 점에서 차이가 존재한다.

[데이터 형식]

{
  "_id" : "507f191e810c19729de860ea",
  "name" : "테스트",
  "phones" : ["010-1111-2222", "010-3333-4444"]
}

MongoDB에서는 별도의 ObjectID를 입력하지 않은 이상은 위와같은 _id 형태로 자동으로 값이 부여가되서 저장이 되는데 ObjectID는 12byte 크기의 문자와 숫자로 구성된 값으로, 이 값은 각각의 의미를 가지고 있다.

4byte는 유닉스 타임스탬프, 5byte는 프로세스별로 생성되는 랜덤 값, 3byte는 자동으로 증가하는 카운터 로 구성되어 있다.
다만, ObjectID의 경우는 RDBMS의 서버와는 다르게, 분산 환경 지원을 위해 서버가 아닌 클라이언트에서 해당 키를 생성하는 차이점이 존재한다. (클라이언트에서 키를 생성하기 때문에 중복된 값을 생성할 가능성 자체는 존재하나 해당 부분은 낮추기 위해 ObjectID의 패턴이 존재, 또한 상당히 낮은 편)

[ObjectId 구조]

ObjectId('507f191e / 810c19729d / e860ea')
-- 507f191e : UNIX Timestamp
-- 810c19729d : Random Value
-- e860ea : Count

 

주요 특징 (기술 요소)

RDBMS의 ACID와는 다른 BASE를 채용하였는데, ACID를 채용한 RDBMS는 데이터의 일관성을 BASE를 채용한 NoSQL의 경우 데이터의 가용성을 중시하여, 시스템이 서비스를 정상적으로 제공할 수 있는 상태를 우선시한다. 해당 내용은 CAP (Consistency - 일관성, Availbity - 가용성, Partition tolerance - 분할 내성)을 기반으로 하고 있으며, 세부 내용은 아래와 같다.
  - Basically Available (가용성) : 언제든지 사용할 수 있다 (무중단 서비스 가능)

  - Soft State (소프트 상태) : 외부의 개입이 없어도 정보 변경 가능 (각각의 데이터가 도달한 시점에 데이터가 갱신)

  - Eventually Consistent (결과적 일관성) : 일시적으로 일관적이지 않아도 최종적으론 일관적인 상태가 되어야함 (복제 메커니즘에 의해 모든 서버에 데이터 복제가 동시에 실행될 순 없으나, 최종적으로는 모든 서버에 데이터가 복제)

주요 특징 (데이터 형식)
MongoDB의 경우 데이터를 관리하기 위한 형식으로 JSON (JavaScript Object Notation)과 BSON (Binary JSON) 형식을 사용하고 있다.
두 형식을 사용하는 이유는 JSON의 경우 텍스트 기반으로 구문 분석이 느리고, 공간 효율성이 상대적으로 나쁜편이기 때문에 JSON 구조를 가져가면서 기계가 읽기 쉬운 형태인 binary 형태로 변경하여 저장하는 형식으로 해당 문제를 해결하였다.
JSON의 경우는 Javascript에서 객체 생성 시 사용하는 표현식으로 {"hello": "world"} 형식과 같이 Key : value 형태의 데이터를 가지고 있고, BSON의 경우 JSON을 이진 형식으로 인코딩한 형식으로 \x16\x00\x00\x00\x02hello\x00\x06\x00\x00\x00world\x00\x00 와 같은 구조를 지닌다.
데이터 입출력시에는 JSON을 사용하며, 데이터 저장 시에는 BSON을 사용한다. 이와 같은 구조는 실제로는 데이터베이스 내부에서 처리가 이루어지기 때문에 표면적으로는 구조를 확인하는 일은 드문편이다.

주요 특징 (용어)

MongoDB의 경우 Document 기반 데이터 베이스로, RDBMS와 명칭적인 차이는 존재하나 비슷한 역할을 가진다.

MongoDB RDBMS
데이터베이스 (Database) 데이터베이스 (Database)
컬렉션 (Collection) 테이블 (Table)
도큐먼트 (Document) 로우 (Row)
필드 (Field) 칼럼 (Column)

 

주 사용처
MongoDB와 같은 NoSQL의 경우, 대용량 데이터에서도 원하는 데이터를 빠르게 찾을 수 있고 스키마가 존재하지 않기 때문에 정형 혹은 비정형의 대용량 로그성 데이터와 제일 궁합이 잘 맞는 편이다. 필요에 따라서, 샤드 클러스터를 구성하여 데이터 분산과 Scale-out 등을 통해 지속적인 유지보수 또한 쉬운 편이다.
다만, 이러한 로그성 데이터뿐만 아니라 여러 서비스에서 조금씩 다르게 사용하는 공용 데이터나 조금씩 다른 형태로 들어오는 데이터 등 스키마가 존재하지 않는 자유로움으로 인해 여러면에서 활용성은 점점 늘어나는 추세이다. 해당 부분은 각 데이터베이스 특성을 활용하여 설계하면 효율적인 활용이 가능하다.

마치며

이전에는 몽고 DB 쓰지 마세요 라는 기사와 검색이 있을 정도로 여러가지 이슈가 존재하였으나, 현재는 전통적인 RDBMS를 제외하면 가장 많이 사용되는 데이터베이스기도하고 데이터가 점점 다량화되어가는 추세에 있어서는 RDBMS와 NoSQL을 혼용하여 사용하는 것이 좋은 선택지임은 분명하다.

출처 : https://db-engines.com/en/ranking

 

DB-Engines Ranking

Popularity ranking of database management systems.

db-engines.com

 

반응형
반응형

H2 Database 란?
자바로 작성된 관계형 데이터베이스 관리 시스템이다.

서버 (Server) 모드와 임베디드 (Embedded) 모드의 인메모리 DB를 제공하며, 브라우저 기반의 콘솔 모드를 사용할 수 있기 때문에, 과제형 코딩테스트나 개발 단계의 테스트 DB로써 많이 이용된다.


사용법

우선, 사용할 버전을 확인 후, pom.xml이나 build.gradle에 추가하면 된다.

https://mvnrepository.com/artifact/com.h2database/h2

// Maven - pom.xml
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>2.1.214</version>
    <scope>test</scope>
</dependency>

// Gradle - build.gradle
testImplementation group: 'com.h2database', name: 'h2', version: '2.1.214'

 

application.yml or application.properties 설정

그 뒤엔 본인의 사용환경에 맞게 application을 설정해주면 된다.

// DB (2개중 택 1)
spring.datasource.url= jdbc:h2:~/test // 임베디드 모드 (인메모리)
spring.datasource.url= jdbc:h2:tcp://localhost/~/test // 서버 모드

spring.datasource.driver-class-name= org.h2.Driver // 데이터 베이스 설정
spring.datasource.username= sa // 접속 시 사용할 유저명
spring.datasource.password= // 접속 시 사용할 패스워드

// 데이터 설정
spring.sql.init.mode= always // 데이터베이스 초기화 (기본 never)
spring.sql.init.schema-locations= classpath:db/schema.sql // 첫 실행시 실행 할 DDL 데이터
spring.sql.init.data-locations= classpath:db/data.sql // 첫 실행시 실행 할 DML 명령

// H2 DB 콘솔
spring.h2.console.enabled= true // 콘솔 사용 여부
spring.h2.console.path= /h2-console // 콘솔 주소

 

브라우저 콘솔 접속

spring.h2.console.path로 설정한 위치로 접속하면 해당 콘솔을 확인하여, 접속할 수 있다.

 

 

접속하면 schema.sql, data.sql 에서 설정한 바와 같이 미리 테이블과 데이터가 입력되고, SQL문을 사용하여 데이터를 확인 가능하다.

 

 

반응형
반응형

자동 증가 값 생성 (IDENTITY)

DB를 설계하는데 있어서 데이터가 생성될 때마다 자동으로 값이 증가하는 컬럼을 생성해야 하는 경우가 존재한다. 이럴 때 주로 사용하는 것이, MSSQL에서는 IDENTITY이다.

사용법

IDENTITY는 아래와 같은 방법으로 테이블을 생성할 때 사용한다.

CREATE TABLE test (
	idx int identity (1, 1) -- (초기값, 증가값)
)

identity (초기값, 증가값) 을 입력하여 초기값과 증가 값을 조절할 수 있으며, 아예 입력을 하지 않은 경우에는 기본 값으로 1부터 하나씩 증가하도록 되어있다.

CREATE TABLE test (
	idx int identity
)

 

임의 지정 및 초기화

기본적으로 identity를 설정하면, 증가값을 설정된 값으로 증가 값을 자동으로 생성한다. 그렇기 때문에, 중간에 데이터가 삭제되는 경우 해당 증가 값을 뛰어 넘어서 생긴다. 이렇게 중간에 비는 데이터를 채워 넣거나 기존 시작 값을 변경하고 싶은 경우에 해당 방법을 사용할 수 있다.

-- 증가값 자동 지정 (기본 설정)
SET IDENTITY INSERT test OFF; -- test : 테이블명

-- 증가값 수동 지정
SET IDENTITY INSERT test ON;

-- 시작값 재지정
DBCC CHECKIDENT ('test', RESEED, 0) -- 0 : 시작값

증가 값은 기본적으로 자동 지정으로 설정되어 있으며, 이 상태의 경우 데이터를 강제적으로 insert해도 값을 넣을 수 없고, 아래와 같은 에러를 볼 수 있다. 

[S001][544] IDENTITY_INSERT가 OFF로 설정되면 테이블 'test'의 ID 열에 명시적 값을 삽입할 수 없습니다.

그렇기 때문에 중간에 비는 데이터를 다시 채워 넣고 싶은 경우 IDENTITY_INSERT를 ON으로 설정한 뒤에 데이터를 입력하여야 정상적으로 처리할 수 있다.

초기화의 경우 DBCC CHECKIDENT를 사용하여, 진행할 수 있다. 데이터를 전부 삭제하여도 기존에 증가 값에 대한 값은 초기화하지 않으면 삭제된 상태로 유지되기 때문에, 다시 기존 초기값부터 재설정하여야 원하는 대로 데이터 처리가 가능하다.

 

자동 증가값 조회

프로시저에서 Insert 한 뒤 자동으로 증가한 IDENTITY 값을 조회하여야 하는 경우 사용한다.

주로, @@IDENTITY, IDENT_CURRENT(), SCOPE_IDENTITY() 세 방법을 사용하며 각각 사용처가 다르게 사용된다.

-- 현재 세션의 테이블에서 생성된 마지막 ID 값 반환 (제한 x)
SELECT @@IDENTITY

-- 현재 세션의 테이블에서 생성된 마지막 ID 값 반환 (현재 범위만)
SELECT SCOPE_IDENTITY()

-- 지정된 테이블에서 생성된 마지막 ID 값 반환
SELECT IDENT_CURRENT('test') -- 테이블명(test)

오류가 발생하거나 개체를 볼 수 있는 권한이 없으면 NULL을 반환하며, 주로 특정 테이블의 마지막 ID 반환에는 IDENT_CURRENT를 사용하고 현재 세션 내의 작업만을 대상으로 하는지 여부에 따라 @@IDENTITY와 SCOPE_IDENTITY가 다르게 사용된다고 생각되면 조금 이해가 편하다.

반응형
반응형

변수란?
임시 저장 영역으로, 값을 담아두는 공간이다.

기본적인 프로그래밍 영역에서 사용하듯이 저장 프로시저에서도 동일하게 사용 가능하다.

 

변수 선언

변수 선언 시에는 DECLARE를 사용하며, 사용법은 아래와 같다.

-- 단일 형태의 변수 생성
DECLARE @name nvarchar(10), @age int -- @name, @age 필요한 변수명 사용

-- 테이블 형태의 변수 생성
DECLARE @data table (name nvarchar(10), age int)

각각 필요한 데이터 형태에 따라서 단일 형태로 선언하거나, 테이블 형태로 여러 행의 변수를 담을 수도 있다.

 

변수 값 대입

변수는 초기 생성 시 null 값을 가지고 있으며, 변수에 값을 대입하여 사용할 수 있다.

주로, SET이나 SELECT 하여 특정 데이터를 변수에 담을 수 있으며 사용법은 아래와 같다.

-- 변수 선언
DECLARE @name nvarchar(10)

-- SET을 통한 변수 값 대입
SET @name = '개발새발'

-- SELECT를 통한 변수 값 대입
SELECT @name = name FROM test WHERE name = '개발새발'

기본적으로는 두가지 방법을 사용하지만, SET 결과에 SELECT 쿼리를 사용하거나 하는 등의 변형도 가능하다.

반응형
반응형

IF EXISTS 란

프로시저를 활용하다 보면, 데이터를 확인하여 특정 조건에 따라 다른 조건의 쿼리를 실행해야 하는 경우가 생긴다.

이럴 때 주로 활용하는 조건문이 IF EXISTS이다.

 

문법

기본적인 문법은 다음과 같으며, 조건문에 값의 유무에 따라 실행되는 쿼리를 다르게 실행할 수 있다.

 

IF EXISTS (
	-- 조건문
	SELECT 1 FROM TEST WHERE TEST_NAME = '개발새발'
    )
	BEGIN
    	-- 조건문에 값이 있는 경우 실행
    	UPDATE TEST SET TEST_TIME = GETDATE()
    END
ELSE
	BEGIN
    	-- 조건문에 값이 없는 경우 실행
    	INSERT INTO TEST (TEST_NAME, TEST_TIME) VALUES ('개발새발', GETDATE())
    END

 

IF EXISTS 문법과 다르게, 조건 결과가 없을 때의 경우도 사용할 수 있으며, 문법은 다음과 같다.

 

IF NOT EXISTS (
	-- 조건문
	SELECT 1 FROM TEST WHERE TEST_NAME = '개발새발'
    )
	BEGIN
    	-- 조건문에 값이 없는 경우 실행
    	INSERT INTO TEST (TEST_NAME, TEST_TIME) VALUES ('개발새발', GETDATE())
    END
ELSE
	BEGIN
    	-- 조건문에 값이 있는 경우 실행
        UPDATE TEST SET TEST_TIME = GETDATE()
    END

 

 

 

해당 함수의 경우 조건에 따라 다양하게 사용되며, 코드단에서 데이터를 두 번 이상 호출하지 않아도 되기 때문에 경우에 따라 유용하게 활용할 수 있는 함수이다.

반응형
반응형

저장 프로시저 (Stored Procedure) 

프로시저는 SQL Server에서 제공되는 프로그래밍 기능이며, 쿼리 문의 집합체라고 볼 수 있다.

간단하게로는 SELECT, INSERT, UPDATE, DELETE 등의 DQL, DML을 사용할 수 있으며,

조금 더 나아가서 IF 문이나 DECLARE, SET 등의 프로그래밍 문법을 사용할 수도 있다.

 

장점 및 단점

장점

  • 보안성 향상
    • 프로시저 단위로 실행 권한을 부여할 수 있기 때문에, 기본적인 보안 사고에 대처가 유연한 편이다.
  • 네트워크 소요 시간 절감
    • 쿼리를 다중으로 실행하는 경우, 한번의 호출을 통해 다중의 쿼리가 실행되기 때문에 네트워크에 대한 부담과 소요 시간을 줄일 수 있다.
  • 운영 배포 용이성
    • 별도의 WAS 서버 재기동 없이 SP 수정으로 조회, 수정, 추가 등의 가벼운 소스 변경 등이 가능하여, 긴급 배포 등이 용이하다.

단점

  • 낮은 처리 성능
    • 프로시저의 경우 성능이나 최적화가 부족하여 수행 능력이 떨어지며, 특히 문자열이나 숫자 연산에 사용하면 JAVA, C 등에 비해서 효율이 좋지 않다.
  • 디버깅 및 유지보수의 어려움
    • 배포, 버전 관리 등에 대한 이력 관리가 힘들다. (별도의 Description 사용)
    • SP가 수정되는 경우 현재 운영 중인 서비스에 영향도 분석이 어렵다.
    • APP에서 SP를 호출하여 사용하는 경우 문제가 생겨도 해당 이슈에 대한 추적이 힘들다. (별도의 에러 테이블 사용)

프로시저 생성, 수정, 삭제

기본적인 생성 방식은 다음과 같다.

 

USE [DB명]
GO

CREATE PROCEDURE [dbo].[프로시저명] (@파라미터명 NVARCHAR(10), @파라미터명2 int)
AS
BEGIN
    -- 사용할 쿼리
    SELECT 1 FROM test
END
GO

 

사용할 DB명과 프로시저명을 입력하여 사용하며, 파라미터의 경우 필요한 경우 자료형과 함께 입력하여 사용한다.

BEGIN과 END 사이에는 사용할 쿼리나, 프로그래밍 문법을 사용하여 실행할 수 있다.

 

수정의 경우, 생성과 기본 방식은 동일하며, CREATE가 아닌 ALTER를 사용하여 수정한다.

다만, 해당 SP의 경우 가장 기본적인 문법으로 현업에서는 아래와 같은 디스크립션을 추가하기도 한다.

 

USE [DB명]
GO

/*=============================================
    작성자: 개발새발
    생성날짜: 2021-09-13
    업데이트날짜: 2021-09-13
    설명: 프로시저 기본 생성 방식
    exec 프로시저명 'TEST', 1
=============================================*/

ALTER PROCEDURE [dbo].[프로시저명] (@파라미터명 NVARCHAR(10), @파라미터명2 int)
AS
BEGIN
    -- 사용할 쿼리
    SELECT 1 FROM test
END
GO

 

삭제는 DROP 구문을 사용하여 삭제할 수 있다.

 

DROP PROCEDURE 프로시저명

 

프로시저 조회 및 실행

프로시저 조회는 sp_helptext를 사용하여, 텍스트 형식으로 결과를 표기할 수 있다.

 

sp_helptext 프로시저명

 

어떤 툴에서 DB를 연결하여 사용하느냐에 따라 다른데, 기본적으로 사용하는 SSMS (SQL Server Management Studio)에서는 GUI를 통해 저장 프로시저 스크립팅으로 CREATE, ALTER, DROP 등의 문법을 자동으로 생성해주며,

인텔리제이에서 데이터베이스를 연결하는 경우 SQL Generator (Ctrl + Alt + G) 통해 프로시저를 조회하는 것이 더 간단하다.

 

프로시저 실행은 exec 구문을 사용하여 해당 프로시저를 사용할 수 있다. 실행할 SP의 입력할 파라미터가 존재하는 경우, 순차적으로 해당 파라미터를 입력하면 정상적으로 실행된다.

 

exec 프로시저명 'TEST', 1
반응형
반응형

DB에서 데이터를 제거할 때 사용하는 것은 주로 DELETE, TRUNCATE, DROP 세 개의 명령어를 사용한다.

 

우선 사용 방법에 대해서 먼저 알아보자면, 아래와 같다.

 

DELETE

 

DELETE TABLE [테이블명] WHERE [컬럼명] = [컬럼]

 

TRUNCATE

 

TRUNCATE TABLE [테이블명]

 

DROP

 

DROP TABLE [테이블명]

 

사용 방법은 매우 간단한 편이고 모두 데이터 삭제를 위한 명령어지만 각각 차이점이 존재한다.

 

DELETE

데이터는 지워지지만 테이블 용량이 줄어들지 않는다.

조건 식을 통해 원하는 데이터만 삭제가 가능하다.

COMMIT 명령어를 사용하기 전이라면, ROLLBACK을 통해 데이터 복구가 가능하다.

내부적으로 한 줄씩 제거하기 때문에, 처리 속도가 상대적으로 느리다.

삭제 행수를 반환한다.

 

TRUNCATE

용량이 줄어들고, 인덱스 등도 삭제된다.

테이블은 삭제되지 않고 데이터만 삭제된다.

조건 식이 불가능하며, 데이터 전체를 삭제한다.

자동 COMMIT이 되는 명령어이기 때문에, 데이터 복구가 불가능하다.

삭제 행수를 반환하지 않는다.

 

DROP

테이블 자체를 제거한다.

자동 COMMIT이 되는 명령어이기 떄문에, 데이터 복구가 불가능하다.

 

위와 같은 차이 때문에, 각 명령어는 상황에 맞는 활용이 필요하며 운영 서버에서 사용 시 각별한 주의를 요구한다.

반응형

'데이터베이스 > Mysql' 카테고리의 다른 글

Auto Increment 설정 및 값 초기화  (0) 2021.05.18
반응형

RDBMS에선 데이터를 쌓는데 Primary Key가 설정된 컬럼에 한하여 데이터 생성 시, 자동으로 숫자가 증가하게 하는 설정이 가능하다.

설정하는 방법은 간단하며, 테이블 생성 시 증가될 컬럼에 auto_increment를 입력하면 된다.

 

테이블을 생성할 DB에 아래와 같은 형식으로 auto_increment를 설정할 수 있다.

다만, 여기서 주의할 사항은 auto_increment의 경우는 PK로 지정된 컬럼만 사용 가능하고 그 외에는 에러가 발생한다.

CREATE TABLE land.`user` (
	idx bigint(20) auto_increment NULL,
	CONSTRAINT user_pk PRIMARY KEY (idx)
)

 

이런 형태로 테이블을 생성하여, 데이터를 쌓다보면 idx (키 값)이 1씩 늘어나는 것을 볼 수 있는데,
1, 2, 3 중에 3을 삭제하고 재 생성하는 경우 3이 생성되는 게 아닌 4부터 데이터가 생성되는 것을 볼 수 있다.

이러한 것을 방지하거나 혹은 재정리하기 위해 auto_increment 값을 초기화할 필요가 있다.

ALTER TABLE land.user AUTO_INCREMENT = 3;

해당 문장같은 형태로 ALTER문을 사용하여, 강제로 원하는 키 값을 지정해줄 수 있다.

ALTER TABLE land.user AUTO_INCREMENT = 1;
SET@COUNT = 0;
UPDATE land.USER SET idx = @COUNT:=@COUNT+1

다른 방식으로 auto_increment를 1부터 재조정하면서 여태 idx 값들을 전체적으로 재조정할 수도 있다.

 

크게 어려운 방법은 아니지만 idx 값은 현업에서는 다른 테이블과 연동될 수 있기 때문에, 전체적인 값 조정은 데이터를 매핑시키는데 조금 위험도가 존재하므로 조심스럽게 다룰 필요가 있다.

반응형

'데이터베이스 > Mysql' 카테고리의 다른 글

데이터 삭제 (DELETE, TRUNCATE, DROP)  (0) 2021.05.20

+ Recent posts