TigerCow.Door




안녕하세요. 문범우입니다.

이번에는 Data Base에서 데이터 모델링(Data Modeling)에 대해서 알아보도록 하겠습니다.

데이터 모델링을 보다 잘 이해하려면 앞에서 학습한 엔터티, 속성, 관계, 식별자에 대한 이해가 필요하므로 각 개념에 대해 이해가 가지 않는 부분이 있다면 아래 링크를 통해서 다시 한번 확인하면 좋습니다.




1. 모델링


1-1. 모델링이란?


모델링이라는 것은 우리 주변에 있는 사람, 사물, 개념 등 다양한 현상을 발생시키는 것들을 일정한 표기법에 의해 나타내는 것을 이야기 한다.

모델링에 대한 사전적 정의로는 아래와 같이 다양하게 존재한다.


- 가설적 또는 일정 양식에 맞춘 표현

- 어떤 것에 대한 예비표현으로 그로부터 최종대상이 구축되도록 하는 계획으로서 기여하는 것

- 복잡한 '현실세계'를 단순화시켜 표현하는 것



1-2. 모델링의 특징


모델링의 특징으로는 다음과 같이 대표적으로 3가지, 추상화, 단순화, 명확화 3가지로 요약할 수 있다.


1-2-1. 추상화(모형화, 가설적)

추상화는 현실세계를 일정한 형식에 맞추어 표현을 한다는 의미이다. 다양한 현상을 일정한 양식인 표기법에 의해 표현한다는 것이다.


1-2-2. 단순화

단순화는 복잡한 현실세계를 약속된 규약에 의해 제한된 표기법이나 언어로 표현하여 현실세계를 보다 쉽게 이해할 수 있도록 하는 개념을 의미한다.


1-2-3. 명확화

명확화란 누구나 이해하기 쉽도록 대상에 대한 애매모호함을 제거하고 보다 정확하게 현상을 기술하는 것을 의미한다.



1-3. 모델링의 3가지 관점


시스템의 대상이 되는 업무를 분석하여 정보시스템으로 구성하는 과정에서 업무의 내용과 정보시스템의 모습을 적절한 표기법으로 표현하는 것을 모델링이라고 한다면, 이러한 모델링은 크게 3가지 관점, 데이터관점, 프로세스관점, 데이터와 프로세스의 상관관점으로 구분할 수 있다.


1-3-1. 데이터 관점(What)

업무가 어떤 데이터와 관련이 있는지 또는 데이터간의 관계는 무엇인지에 대해서 모델링하는 방법


1-3-2. 프로세스 관점(How)

업무가 실제하고 있는 일은 무엇인지 또는 무엇을 해야 하는지를 모델링하는 방법


1-3-3. 데이터와 프로세스의 상관관점

업무가 처리하는 일의 방법에 따라 데이터는 어떻게 영향을 받고 있는지 모델링하는 방법



2. 데이터 모델링


2-1. 데이터 모델링이란


우선, 데이터 모델링의 기반이 되는 데이터 모델은 데이터베이스의 골격을 이해하고 그 이해를 바탕으로 SQL문장을 기능과 성능적인 측면에서 효율적으로 작성하기 위해 꼭 알아야 하는 핵심요소이다. 이러한 데이터 모델을 만드는 데이터 모델링은 다음과 같이 정의 될 수 있다.


- 정보시스템을 구축하기 윟나 데이터관점의 업무 분석 기법

- 현실세계의 데이터(What)에 대해 약속된 표기법으로 표현하는 과정

- 데이터베이스를 구축하기 위한 분석/설계 과정



2-2. 데이터 모델이 제공하는 기능


업무를 분석하는 관점에 있어서 데이터 모델은 다음과 같은 기능을 제공한다.


- 시스템을 현재 또는 원하는 모습으로 가시화하도록 도와준다.

- 시스템의 구조와 행동을 명세화 할 수 있게 한다.

- 시스템을 구축하는 구조화된 틀을 제공한다.

- 시스템을 구축하는 과정에서 결정한 것을 문서화한다.

- 다양한 영역에 집중하기 위해 다른 영역의 세부 사항은 숨기는 다양한 관점을 제공한다.

- 특정 목표에 따라 구체화된 상세 수준의 표현방법을 제공한다.



2-3. 데이터 모델링의 중요성과 유의점


데이터 모델링이 중요한 이유는 파급효과(Leverage), 복잡한 정보 요구사항의 간결한 표현(Conciseness), 데이터 품질(Data Quality)로 정리할 수 있다.


- 파급효과(Leverage)

데이터 모델링이 초기에 제대로 이루어지지 않는다면, 시스템이 구현되고 테스트 하는 과정 중 그 문제점이 나타날 수 있다. 일반적으로 단위테스트, 통합테스트 등 다양한 단계의 테스트를 진행하는데 데이터 모델링의 문제가 발생해 데이터 모델을 변경해야 하는 상황이 온다면 데이터 모델, 구조 변경에 따른 표준 영향 분석, 응용 변경 영향 분석 등 다양한 분석이 필요해진다. 또한 그 이후의 실질적 구조 변경 작업이 진행되어야 한다.


- 복잡한 정보 요구사항의 간결한 표현(Conciseness)

데이터 모델은 구축할 시스템의 정보 요구사항과 한계를 가장 명확하고 간결하게 표현할 수 있는 도구이다. 정보 요구사항이 정확하고 간결하게 표현되어야 해당 데이터 모델과 관련된 시스템을 구축하는 많은 사람들이 설계자의 생각대로 정보 요구사항을 이해할 수 있을 것이고, 이를 운용할 수 있는 서비스/어플리케이션을 개발하며 데이터 정합성을 유지할 수 있다.


- 데이터 품질(Data Quality)

데이터베이스에 담겨 있는 데이터는 기업/단체의 중요한 자산이다. 특정 데이터에 대해서는 그 기간이 늘어날 수록 활용가치가 더 높아지기도 한다. 헌데, 그러한 데이터의 정확성이 떨어지는 등 데이터 품질이 낮아진다면 어떨까? 이는 해당 데이터로 얻을 수 있었던 비즈니스 기회를 상실할 수도 있는 문제가 된다.

데이터 품질에 대한 고찰은 데이터가 쌓이는 초기에는 쉽게 인지를 못하는 경우가 대부분이기에 초기 부터 오랜 기간 숙성된 데이터를 전략적으로 활용하기 위해 데이터 품질에 대한 중요성을 기억해야 한다.



또한 위와 같은 중요성을 지키기에 앞서, 데이터 모델링을 할때 유의해야 할 점은 다음과 같다.


- 중복(Duplication)

데이터 모델은 같은 데이터를 사용하는 사람, 시간, 그리고 장소를 파악하는데 도움을 준다. 이러한 자식 응용은 데이터베이스가 여러 장소에 같은 정보를 저장하는 잘못을 하지 않도록 한다.


- 비유연성(Inflexibility)

데이터 모델을 어떻게 설계했느냐에 따라 사소한 업무변화에도 데이터 모델이 수시로 변경됨으로써 유지보수의 어려움을 가중시킬 수 있다. 데이터의 정의를 데이터의 사용 프로세스와 분리함으로써 데이터 모델링은 데이터 혹은 프로세스의 작은 변화가 애플리케이션과 데이터베이스에 중대한 변화를 일으킬 수 있는 가능성을 줄인다.


- 비일관성(Inconsistency)

데이터의 중복이 없더라도 비일관성은 발생할 수 있다. 예를 들어 신용 상태에 대한 갱신 없이 고객의 납부 이력 정보를 갱신하는 것이다. 개발자가 다른 데이터와 모순된다는 고려 없이 일련의 데이터를 수정할 수 있기 때문이다. 데이터 모델링을 할 때 데이터와 데이터간 상호 연관 관계에 대한 명확한 정의는 이러한 위험을 사전에 예방할 수 있도록 해준다.



2-4. 데이터 모델링의 3단계


데이터 모델링을 하는데에 있어서는 시간에 따라 진행되는 3가지 과정이 있다. 이는 추상화 수준에 따라 달라지며 개념적 데이터 모델링, 논리적 데이터 모델링, 물리적 데이터 모델링으로 정리 된다.





2-4-1. 개념적 데이터 모델링

추상화 수준이 높으며 업무 중심적이고 포괄적인 수준의 모델링을 진행한다. 전사적 데이터 모델링으로도 사용되며 EA 수립시에도 많이 이용한다.

어떠한 자료가 중요하고, 어떠한 자료가 유지되어야 하는지를 결정하는 내용도 포함된다. 이 단계에 있어서 주요한 활동은 핵심 엔터티와 그들 간의 관계를 발견하고, 그것을 표현하기 위해 엔터티-관계 다이어그램을 생성하는 것이다. 


개념적 데이터 모델링을 통해 조직의 데이터 요구를 공식화 하는 것은 두 가지의 중요한 기능을 지원한다.

1. 개념적 데이터 모델은 사용자와 시스템 개발자가 데이터 요구 사항을 발견할 수 있도록 지원한다.

2. 개념 데이터 모델은 현 시스템이 어떻게 변형되어야 하는가를 이해하는데 유용하다.



2-4-2. 논리적 데이터 모델링

시스템으로 구축하고자 하는 업무에 대해 Key, 속성, 관계 등을 정확하게 표현하는 단계의 모델링이다. 재사용성이 높은 특징을 갖는다.

이러한 논리적 데이터 모델링은 데이터베이스 설계 프로세스의 Input으로써 비즈니스 정보의 논리적인 구조와 규칙을 명확하게 표현하는 과정이다. 데이터 모델링 과정에서 가장 핵심이 되는 부분이기도 하다.

논리적 데이터 모델링에서 진행되는 중요한 과정 중에 하나는 정규화이다. 정규화는 논리적 데이터 모델 상세화 과정의 대표적인 활동으로, 논리적 데이터 모델의 일관성을 확보하고 중복을 제거하여 속성들이 가장 적절한 엔터티에 배치되도록 함으로써 보다 신뢰성있는 데이터 구조를 얻는데 목적이 있다.

논리적 데이터 모델의 상세화는 식별자 확정, 정규화, M:M 관계 해소, 참조 무결성 규칙 정의 등을 들 수 있으며, 추가적으로 이력 관리에 대한 전략을 정의한다.



2-4-3. 물리적 데이터 모델링

실제로 데이터베이스에 이식할 수 있도록 성능, 저장 등 물리적인 성격을 고려하여 설계하는 단계의 모델링이다.

데이터가 물리적으로 컴퓨터에 어떻게 저장될 것인가에 대한 정의를 진행하는 단계이며 이 단계에서 테이블, 칼럼 등으로 표현되는 물리적인 저장구조와 사용될 저장 장치, 자료를 추출하기 위해 사용될 접근 방법 등을 결정한다.



2-5. 데이터 독립성


일체적 구성에서 기능화된 구성의 가장 큰 목적은 상호간 영향에서 벗어나 개별 형식이 가지는 고유의 기능을 유지시키며 그 기능을 극대화하는 것이다. 이를 위해 데이터 모델링 과정에서는 데이터 독립성을 중요시 한다.



2-5-1. 데이터 독립성의 필요성


데이터 독립성은, 끊임없이 요구되는 사용자 요구사항에 대해 화면과 데이터베이스 간에 서로 독립성을 유지하기 위한 목적으로 개념이 출현했다고 할 수 있다. 즉, 구조화 된 시스템이 시간이 지날수록 유지보수 비용이 증가하고, 데이터복잡도가 증가하며, 데이터 중복성 또한 증가 함에 따라서 데이터 독립성의 필요성이 대두된 것이다.

이러한 데이터 독립성이 확보되면 다음과 같은 효과를 얻을 수 있다.


- 각 View의 독립성을 유지하고 계층별 View에 영향을 주지 않고 변경이 가능한다.

- 단계별 스키마에 따라 데이터 정의어와 데이터 조작어가 다름을 제공한다.



2-5-2. 데이터베이스의 3단계 구조


데이터 독립성을 가지는 모델은 다음과 같이 외부단계, 개념적단계, 내부적 단계로 서로 간섭되지 않는 모델을 제시한다.



- 외부 단계(외부 스키마, External Schema)

View 단계 여러 개의 사용자 관점으로 구성한다. 즉, 개개인의 사용자 단계로서 개개인의 사용자가 보는 개인적인 DB 스키마이다. 이에 따라 DB의 개개인 사용자나 응용 프로그래머가 접근하는 DB를 정의한다.


- 개념적 단계(개념 스키마, Conceptual Schema)

개념단계 하나의 개념적 스키마로 구성되는 모든 사용자 관점을 통합한 조직 전체의 DB를 기술하는 것이다. 모든 응용시스템들이나 사용자들이 필요로 하는 데이터를 통합한 조직 전체의 DB를 기술한 것으로 DB에 저장되는 데이터와 그들간의 관계를 표현하는 스키마이다.


- 내부적 단계(내부 스키마, Internal Schema)

DB가 물리적으로 저장된 형식을 나타낸다. 물리적 장치에서 데이터가 실제적으로 저장되는 방법을 표현한다.



2-6. 데이터 모델링의 3가지 요소


데이터 모델링을 구성하는 중요한 개념 3가지가 있는데 이것은 데이터 모델에 대한 이해의 근간이 되므로 반드시 기억할 필요가 있다.


1. 업무가 관여하는 어떤 것(Things)

2. 어떤 것이 가지는 성격(Attributes)

3. 업무가 관여하는 어떤 것 간의 관계(Relationship)


위 3가지는 데이터 모델링을 완성해가는 개념이며 결국 우리가 앞에서 공부했던 엔터티, 속성, 관계를 나타낸다.



2-7. 좋은 데이터 모델의 요소


그럼, 데이터 모델링을 통해 도출된 데이터 모델에 대한 객관적 평가는 어떠한 것을 중심으로 진행될까? 일반적으로 좋은 데이터 모델을 평가하기 위해서는 다음과 같은 요소들을 고려한다.


2-7-1. 완전성(Completeness)

업무에서 필요로 하는 모든 데이터가 데이터 모델에 정의되어 있는지를 확인하는 요소이다. 사실상 데이터 모델을 검증하기 위해 제일 먼저 확인이 이루어져야 하는 요소이다. 


2-7-2. 중복배제(Non-Redundancy)

하나의 데이터베이스에 동일한 사실은 반드시 한번만 기록되어야 한다. 데이터에 대한 중복이 있다면 필요하지 않은 데이터에 대한 관리가 필요하다. 즉 저장공간의 낭비, 데이터 유지를 위한 비용 지불, 데이터의 일관성을 유지하기 위한 추가적인 조치 등이 대표적으로 낭비되는 비용이다.


2-7-3. 업무규칙(Business Rules)

데이터 모델링 과정을 통해 도출되고 규명되는 수많은 업무규칙은 데이터 모델에 잘 표현되어야 하고, 이를 해당 데이터 모델을 활용하는 모든 사용자가 공유할 수 있도록 제공되어야 한다. 특히, 데이터 아키텍처에서 언급되는 논리 데이터 모델에서 이러한 요소들이 포함되어야 하는 점은 매우 중요하다.


2-7-4. 데이터 재사용(Data Reusability)

데이터의 통합성과 독립성에 대해서 충분히 고려가 된다면 데이터 재사용성을 향상시킬 수 있다. 데이터 재사용성을 높임으로써 시스템 유지보수 뿐 아니라, 신규 시스템을 구축하는 데에 있어서도 매우 유리하게 작용될 수 있다.


2-7-5. 의사소통(Communication)

데이터 모델은 대상으로 하는 업무를 데이터 관점에서 분석하고 이를 설계하여 나오는 최종 산출물이다. 그리고 그 과정에서는 자연스럽게 많은 업무 규칙들이 도출된다. 그러한 업무 규칙들에 대해서 해당 정보시스템을 운용, 관리하는 많은 관련자들이 설계자가 정의한 업무 규칙들을 동일한 의미로 받아들이고 정보시스템을 활용할 수 있도록 의사소통 역할을 하는 것이 데이터 모델이다.


2-7-6. 통합성(Integration)

물론 성능 등의 부가적인 목적때문에 의도적으로 데이터를 중복시키는 경우는 존재할 수 있다. 그러한 경우가 아니라면 동일한 데이터가 다양한 곳에 존재하는 것은 또 하나의 낭비일 수 있다. 따라서 데이터 모델링을 진행하는 과정에 있어 동일한 성격의 데이터를 한 번만 정의함으로써 공유 데이터에 대한 구조를 여러 업무 영역에서 공동으로 사용하기 용이하도록 해야 한다.



Q. 데이터 모델링 관련 문제


1. 다음 설명 중 데이터 모델링이 필요한 주요 이유로 가장 부적절한 것은?


⑴ 업무정보를 구성하는 기초가 되는 정보들에 대해 일정한 표기법에 의해 표현한다.

⑵ 분석된 모델을 가지고 데이터베이스를 생성하여 개발 및 데이터관리에 사용하기 위한 것이다.

⑶ 데이터베이스를 구축하기 위한 용도를 위해 데이터모델링을 수행하고 업무에 대한 설명은 별도의 표기법을 이용한다.

 데이터모델링 자체로서 업무의 흐름을 설명하고 분석하는 부분에 의미를 가지고 있다.




2. 다음 중 ANSI-SPARC에서 정의한 3단계구조(three-level architecture)에서 아래 내용이 설명하는 스키마구조로 가장 적절한 것은?


- 모든 사용자 관점을 통합한 조직 전체 관점의 통합적 표현

- 모든 응용시스템들이나 사용자들이 필요로 하는 데이터를 통합한 조직 전체의 DB를 기술한 것으로 DB에 저장되는 데이터와 그들간의 관계를 표현하는 스키마


⑴ 외부스키마(External Schema)

⑵ 개념스키마(Conceptual Schema)

⑶ 내부스키마(Internal Schema)

⑷ 논리스키마(Logical Schema)




추가적으로 궁금한 사항이나 잘 이해가 되지 않는 부분들은 이메일 또는 카카오톡으로 연락주시면 답변드리겠습니다.

블로그 이미지

Tigercow.Door

Back-end / Python / Database / AI / Algorithm / DeepLearning / etc

댓글을 달아 주세요


안녕하세요. 문범우입니다.

이번 포스팅에서는 이중 not exists에 관해 예제를 다뤄보도록 하겠습니다.

이번에 다루게 되는 내용에 대해서는 기본적으로 not exists에 대해 동작 방식을 이해해야 수월하게 따라올 수 있습니다.

not exists에 대해 아직 헷갈린다면 아래 글을 먼저 확인해주세요.


[MS SQL Server] #11_ IN / EXISTS / NOT IN / NOT EXISTS 비교


특별히 이번 예제는 블로그를 통해서 연락주신 분에 의해서 다루게 되었습니다.



1. 테이블 정의 및 데이터 정의


먼저 예제를 소개하기에 앞서 사용될 테이블과 데이터를 정의합니다.

총 3개의 테이블(sailors, boats, reserved)을 사용하며 각 테이블에 있는 데이터는 아래 사진과 같습니다.


sailors tablesailors table


boats tableboats table


reserved tablereserved table



테이블에 대해 간략히 소개를 드리자면,

sailors 테이블은 5명의 사람데이터가 입력되어 있습니다. 각 사람에게는 sid라는 고유번호가 주어져 있으며 name값으로 이름이 주어집니다.

boats 테이블은 총 3개의 보트데이터가 입력되어 있습니다. 각 보트에는 bid라는 고유번호가 주어지며 boat_name값으로 이름이 주어집니다.

reserved 테이블은 어떤 사람이 어떤 보트를 예약했는지에 대한 정보를 가진 테이블입니다. 즉 sid에 해당하는 사람이 bid에 해당하는 보트를 예약한 것입니다.



2. 이중 not exists 예제


위와 같은 테이블과 데이터를 기반으로 우리의 목표는 boats 테이블에 있는 모든 보트를 예약한 사람을 구하는 것입니다. 물론 쉽게 알 수 있듯이 sid = 1인, sailor_1이 그 답이 되겠죠.

이 답을 찾기 위해 다음과 같은 쿼리를 사용할 수 있습니다.



위의 쿼리에서는 두번 중첩된 not exists 문, 즉 이중 not exists 문을 이용하여 답을 구하였습니다.


이번 포스팅에서는 위와 같은 쿼리가 어떤 과정으로 답을 도출해내는지 알아보려고 합니다.



3. 이중 not exists 분석


먼저 보다 쉽게 설명하기 위해서 위의 쿼리를 아래와 같이 3개로 나눠보도록 하겠습니다.



위의 그림과 같이 가장 바깥에 있는 쿼리 전체를 1번 쿼리, 그리고 1번 쿼리의 where 문에 있는 서브쿼리를 2번 쿼리, 마지막으로 2번 쿼리의 where 문에 있는 서브쿼리를 3번 쿼리라고 하겠습니다.


not exists문에 대해서 기본적인 내용을 이해한 상태라면 not exists문은 이하 서브쿼리에 값이 아무것도 존재하지 않아야 참이 됩니다.

그럼 데이터 하나씩 그 과정을 자세하게 살펴보도록 하겠습니다.

(아래 모든 그림들에서 3번째 테이블의 pid는 오타입니다. pid가 아닌 sid가 맞습니다.)



쿼리는 위와 같은 3개의 테이블에 대해서 하나씩 데이터를 꺼내 where문에 대해 비교를 실시합니다. 먼저 1번쿼리에 의해서 아래와 같이 sid=1, name=sailor_1인 데이터에 대해 where문 비교를 실시하겠죠.



1번 쿼리의 where문을 비교하기 위해 2번쿼리로 진입합니다. 2번쿼리에서 아래와 같이 bid=101, boat_name=boat_1인 데이터를 대해서 where문을 비교합니다.



이번에는 2번쿼리의 where문을 확인하기 위해 3번 쿼리로 진입합니다. 마지막 3번 쿼리에서는 where을 비교하기 위해 아래와 같이 bid=101, sid=1에 대한 데이터를 비교하기 시작합니다.



그런데 3번 쿼리에서 bid=101, sid=1인 데이터와 1번 쿼리에서 온 sid=1, name=sailor_1, 2번 쿼리에서온 bid=101, boat_name=boat_1인 데이터를 통해 where문을 확인하면 s.sid=r.sid와 b.bid=r.bid 가 모두 참이기 때문에 3번쿼리의 where문이 참이 됩니다. 따라서 3번쿼리에 따른 결과가 아래와 같이 출력됩니다.



이제 다시 2번쿼리로 올라가봅니다. 2번 쿼리의 where문을 보면 not exists(3번쿼리) 입니다. 헌데 방금 위에서 확인하였듯이 3번쿼리에 대한 결과 값이 존재하기 때문에 2번 쿼리의 where문은 거짓이 되죠. 따라서 2번쿼리에서 비교한 bid=101, boat_name=boat_1에 대해서는 2번 쿼리의 결과가 NULL입니다. 이번에는 2번쿼리에서 아래와 같이 bid=102, boat_name=boat_2에 대해서 동일하게 3번쿼리의 비교를 시작합니다.



이번 비교 또한 위와 같이 3번쿼리에서 where문이 참으로 3번쿼리에 대한 결과가 도출 됩니다. 따라서 2번 쿼리에서 비교한 bid=102, boat_name=boat_2에 대해서도 결과가 NULL입니다. 마지막으로 2번쿼리에서 bid=103, boat_name=boat_3에 대해서 비교를 해도 아래와 같이 결과는 같습니다.



즉 이를 통해 2번쿼리에 대해서 모든 데이터의 결과가 NULL입니다.

여기까지의 결과에 한정해서 현재 쿼리 상태를 보면 아래와 같습니다.


위의 그림에서 빨간색으로 나타난 글자와 같이 현재 위의 쿼리는 sailors 테이블의 sid=1, name=sailor_1인 데이터에 대해서 1번쿼리의 서브쿼리 결과를 보다 확인하기 쉽게 나타내주고 있습니다. 위의 쿼리에서 where not exists 이하가 모두 NULL이기 때문에 where문은 결국 참이 됩니다. 따라서, sid=1, name=sailor_1인 데이터는 1번 쿼리의 결과로써 출력이 되는 것 입니다.


동일한 방법으로 1번쿼리에서 두번째 데이터는 왜 출력이 되지 않는지 확인해보겠습니다.



우선 위에서 했던 것과 동일한 방식으로 1번 쿼리에서는 sid=2, name=sailor_2인 데이터에 대해 비교를 시작하며 where문의 서브쿼리인 2번 쿼리로 진입합니다. 2번 쿼리에서는 bid=101, boat_name=boat_1 데이터에 대해서 3번쿼리로 진입하고, 3번 쿼리의 where문에서 참이 되기 때문에 3번 쿼리에 대한 결과는 bid=101, sid=2가 나오게 됩니다. 이에 따라 bid=101, boat_name=boat_1 데이터에 대한 2번 쿼리의 결과는 NULL 입니다.


하지만 위와 같이 2번 쿼리에서 bid=102, boat_name=boat_2인 데이터에 대해서 확인하면 3번 쿼리에서 where문을 참으로 하는 3번째 테이블의 데이터가 없기 때문에 3번 테이블의 결과가 NULL이 됩니다. 이에 따라 2번 쿼리의 where문은 참이 되고, 2번 쿼리에서 bid=102, boat_name=boat_2인 데이터에 대한 결과는 이전과 달리 NULL이 아니라 해당 데이터가 출력되게 됩니다.



위와 같이 2번 쿼리에서 bid=3, boat_name=boat_3인 데이터에 대해 비교했을 때도 동일한 결과가 나와서 해당 데이터에 대한 2번 쿼리의 결과는 NULL이 아니라 bid=103, boat_name=boat_3인 데이터가 나오게 됩니다.

여기까지의 결과를 이전과 같이 한정적으로 쿼리로 살펴보면 다음과 같습니다.



물론 위의 쿼리는 sailors 테이블의 sid=2, name=sailor_2인 데이터에 대해 한정적인 쿼리입니다. 위의 쿼리를 보면 where not exists 이하에 NULL이 아닌 값이 존재합니다. 따라서 where문 이가 거짓이 되어 sid=2, name=sailor_2인 데이터는 출력되지 않습니다.


이후 sailors 테이블의 다른 데이터를 동일한 방법으로 비교하였을 때에도 방금과 같은 이유로 출력되지 않습니다.

즉 처음에 살펴본 sid=1, name=sailor_1인 데이터만 출력되는 것이죠.



이렇게 이번에는 특정 결과를 도출하기 위해 쿼리를 만드는 것을 목적으로 하기 보다 하나의 쿼리에 대해서 그 동작방식을 자세히 알아보았습니다. 특히 이번에 알아본 이중 not exists문에 대해서는 동작방식을 이해하고 살펴보면 쉽게 결과를 예측할 수 있습니다.

물론 특정 결과를 위해 쿼리를 만드는 학습도 중요하지만 이와 같이 특정 쿼리를 보다 자세하게 분석하는 학습 또한 중요합니다.

추가적으로 궁금한 사항이나 잘못된 점은 언제나 댓글 및 이메일로 연락주시면 감사하겠습니다.

블로그 이미지

Tigercow.Door

Back-end / Python / Database / AI / Algorithm / DeepLearning / etc

댓글을 달아 주세요

  • WOW 2020.03.19 02:15  댓글주소  수정/삭제  댓글쓰기

    WOW 미쳤다 완벽한 설명 ...

  • 와우 2020.04.09 16:57  댓글주소  수정/삭제  댓글쓰기

    와우 좋아요

  • Lee 2020.06.08 10:10  댓글주소  수정/삭제  댓글쓰기

    첫번째 쿼리 결과와 두번째 쿼리결과를 비교하려면 공통속성이 있어야 하지 않나요? 아니면 동작상으로 처음에 모든 테이블을 곱해서 모든 카디널리티를 구하고 각 행을 where조건으로 뽑거나 소거하고 마지막 셀렉션은 통합테이블에서 해당 속성만 프로젝션되는 건가요? 실제 연산과 개념적인 연산을 매핑하고 싶은데 독학하려니 막히는 부분이 많네요ㅠㅠ

  • SQL 2020.06.23 21:19  댓글주소  수정/삭제  댓글쓰기

    설명 감사합니다.
    중간에 WHERE NOT EXISTS(NULL,NULL,NULL) 중에 (NULL,NULL,NULL)이라는 표현은 실제로 있는 표현인지,
    글쓴이분께서 이해를 돕기 위해 개념적으로 삽입한 것인지 궁금합니다.!


안녕하세요. 문범우입니다.

지난 글에서 기초적인 SELECT문을 통해 데이터를 조회하는 방법에 대해서 알아보았습니다.

이번 포스팅에서는 SELECT문에 WHERE절을 추가하여 특정 조건에 부합하는 데이터들만 조회하는 방법에 대해서 알아보도록 하겠습니다.


데이터베이스 및 테이블들은 지난 글에서 만든 샘플데이터를 그대로 이용합니다. 해당 샘플 데이터가 없는 분들은 아래 글에서 쿼리를 통해 샘플데이터를 생성하고 진행해주세요.


[MS SQL Server] #5_SELECT문 기초



1. WHERE문 기초


먼저 아래와 같은 기본 SELECT문을 통해서 employee 테이블의 모든 데이터를 조회해보도록 합시다.


SELECT * FROM employee;


그런데 만약 위와 같이 모든 정보를 얻고 싶은 것이 아니라, job의 값이 '사원'인 데이터에 대해서만 조회하고 싶을 때는 어떻게 할까요?

또는 salary가 500 이상인 데이터만 조회하고 싶을 때는 어떻게 해야 할까요?


이와 같이 테이블에서 특정 조건에 부합하는 데이터만 조회하고 싶을 때 사용하는 것이 WHERE절 입니다.


그럼 바로 WHERE절을 사용해보도록 합시다.

먼저 job이 사원인 데이터만 조회하는 쿼리는 다음과 같습니다.


SELECT * FROM employee

WHERE job = '사원';



위의 결과와 같이 job이 '사원'인 데이터만 조회되었습니다.


그럼 같은 방법으로 salary가 500 이상인 데이터도 조회해보도록 합시다.


SELECT * FROM employee

WHERE salary >= 500;



위와 같이 salary가 500이상인 데이터만 조회되었습니다.


WHERE 절에서 사용되는 기본적인 연산자는 다음과 같습니다.


대소를 비교할 때 사용되는 >, <, >=, <= 와 같은 것들이 있으며,

같음을 나타내는 = 와 서로 다름을 나타내는 != 또는 <>이 있습니다.


그런데 여러개의 조건을 함께 사용해야 하는 경우는 어떻게 해야할까요?



2. 논리연산자(and / or)의 사용


여러개의 조건을 함께 사용해야 한다는 것은 다음과 같은 상황일 것 입니다.


'사장' 직급이 아니면서, salary가 500 이상인 데이터에 대해서 조회하시오. 또는

commission을 포함한 연봉이 5500만원 이하이거나 '사원' 직급인 데이터를 조회하시오.


이러한 경우는 어떻게 할까요?

바로 여러개의 조건을 동시에 사용하면 되는데, 이럴 때 사용하는 것이 논리 연산자 입니다.

and 논리 연산자는 좌,우측의 조건을 동시에 만족해야 할 때 사용되며,

or 논리 연산자는 좌,우측의 조건중 하나만 만족하면 될 때 사용합니다.


그럼 바로 쿼리문으로 확인해보도록 하겠습니다.

'사장' 직급이 아니면서, salary가 500 이상인 데이터에 대해서 조회하는 쿼리는 다음과 같습니다.


SELECT * FROM employee

WHERE job != '사장'

AND salary >= 500;



위와 같이 우리가 기대한 결과가 잘 나온 것을 확인할 수 있습니다.


그럼 이번에는 OR연산자를 이용해보도록 합시다.

commission을 포함한 연봉이 5500만원 이하이거나 '사원' 직급인 데이터를 조회하는 쿼리는 다음과 같습니다.


SELECT * FROM employee

WHERE (salary * 12) + isnull(commission,0) <= 5500

OR job = '사원';



위의 쿼리에서는 지난 시간에 배운 isnull() 함수를 이용하여 연봉을 계산하고 해당 값을 WHERE절 에서 그대로 사용하였습니다.

위와 같이 WHERE절에서 연산도 가능하니 참고하시기를 바랍니다.



3. BETWEEN A AND B


이번에 배워볼 것은 위와 같이 WHERE절에서 사용되는 BETWEEN A AND B 구문입니다.

만약 salary가 300이상 500이하인 데이터에 대해서 조회하려면 어떻게 해야할까요?

우리가 위에서 배운 내용대로라면, 아래와 같은 쿼리가 될 것입니다.


SELECT * FROM employee

WHERE salary >= 300

AND salary <= 500;


하지만 BETWEEN A AND B 구문을 이용하면 다음과 같이 쿼리를 작성하면 됩니다.


SELECT * FROM employee

WHERE salary BETWEEN 300 AND 500;



실제로 같은 결과를 가져오지만 이전의 쿼리보다 보다 간결하고 직관적임을 알 수 있습니다.



4. IN


마지막으로 배워볼 구문은 IN입니다.

만약 salary가 300, 400, 500, 600인 데이터를 조회하려면 어떻게 해야할까요?

이전의 학습을 기반으로 쿼리를 작성해보면 다음과 같습니다.


SELECT * FROM employee

WHERE salary = 300

OR salary = 400

OR salary = 500

OR salary = 600;


하지만 IN 구문을 이용하면 다음과 같이 쿼리를 작성할 수 있습니다.


SELECT * FROM employee

WHERE salary IN (300,400,500,600);



IN구문을 활용함으로써 OR을 통한 이전의 쿼리보다 더 간결하고 직관적임을 알 수 있습니다.



이번 포스팅에서는 WHERE 절을 이용해서 조건에 부합하는 데이터 조회방법에 대해서 알아보았습니다.

사실 WHERE절 없이 SELECT를 활용하는 경우보다는 WHERE절을 통해 원하는 데이터만 조회할 때가 더 많다고 생각됩니다. 따라서 위에 나온 쿼리문들 이외에도 다양하게 시도해보고 쿼리문을 만들어보시길 바랍니다.


블로그 이미지

Tigercow.Door

Back-end / Python / Database / AI / Algorithm / DeepLearning / etc

댓글을 달아 주세요


안녕하세요. 문범우입니다.

이번 포스팅에서는 먼저 샘플 데이터세트를 구성해보고, 이를 바탕으로 select 문에 대해서 보다 자세히 다뤄보도록 하겠습니다.



1. 샘플 데이터세트 구성하기


아래의 쿼리를 실행시킴으로써 샘플 데이터베이스 생성 부터 데이터 입력까지 진행합니다.

단순 CREATE 및 INSERT 문이기 때문에 복사 붙여넣기를 하셔도 되지만

복습 및 익숙해짐을 위해서 직접 타이핑 해보시는 것도 좋을 것 같습니다.


-- CREATE SAMPLE_DB

CREATE DATABASE SampleDB;


USE SampleDB;


-- CREATE TABLE

CREATE TABLE department(

deptNo INT PRIMARY KEY,

deptName NVARCHAR(20),

location NCHAR(20)

);


CREATE TABLE employee(

empNo INT PRIMARY KEY,

empName NVARCHAR(20),

job NVARCHAR(20),

manager INT,

hireDate DATETIME,

salary INT,

commission INT,

deptNo INT FOREIGN KEY REFERENCES DEPARTMENT(deptNo)

);


-- INSERT DATA

INSERT INTO department (deptNo, deptName, location)

VALUES (10, '경리부', '서울');

INSERT INTO department (deptNo, deptName, location)

VALUES (20, '인사부', '인천');

INSERT INTO department (deptNo, deptName, location)

VALUES (30, '영업부', '대전');

INSERT INTO department (deptNo, deptName, location)

VALUES (40, '전산부', '부천');


INSERT INTO employee (empNo, empName, job, manager, hireDate, salary, deptNo)

VALUES (1001, '최범우', '사원', 1013, '2007-03-21', 300, 20);

INSERT INTO employee (empNo, empName, job, manager, hireDate, salary, commission, deptNo)

VALUES (1002, '김범수', '대리', 1005, '2007-04-11', 250, 80, 30);

INSERT INTO employee (empNo, empName, job, manager, hireDate, salary, commission, deptNo)

VALUES (1003, '장태훈', '과장', 1005, '2005-02-01', 500, 100, 30);

INSERT INTO employee (empNo, empName, job, manager, hireDate, salary, deptNo)

VALUES (1004, '최상우', '부장', 1008, '2003-09-01', 600, 20);

INSERT INTO employee (empNo, empName, job, manager, hireDate, salary, commission, deptNo)

VALUES (1005, '변봉중', '과장', 1008, '2003-10-02', 450, 200, 30);

INSERT INTO employee (empNo, empName, job, manager, hireDate, salary, deptNo)

VALUES (1006, '송원철', '부장', 1005, '2003-08-02', 480, 30);

INSERT INTO employee (empNo, empName, job, manager, hireDate, salary, deptNo)

VALUES (1007, '문서연', '부장', 1008, '2004-03-08', 520, 10);

INSERT INTO employee (empNo, empName, job, manager, hireDate, salary, commission, deptNo)

VALUES (1008, '장웅', '차장', 1003, '2004-03-01', 500, 0, 30);

INSERT INTO employee (empNo, empName, job, hireDate, salary, deptNo)

VALUES (1009, '최상범', '사장', '1996-10-04', 1000, 20);

INSERT INTO employee (empNo, empName, job, manager, hireDate, salary, deptNo)

VALUES (1010, '이명근', '과장', 1003, '2005-04-01', 500, 10);

INSERT INTO employee (empNo, empName, job, manager, hireDate, salary, deptNo)

VALUES (1011, '서은혜', '사원', 1007, '2007-02-03', 280, 30);

INSERT INTO employee (empNo, empName, job, manager, hireDate, salary, deptNo)

VALUES (1012, '이철진', '사원', 1006, '2007-08-06', 300, 20);

INSERT INTO employee (empNo, empName, job, manager, hireDate, salary, deptNo)

VALUES (1013, '한태범', '부장', 1003, '2002-10-09', 560, 20);

INSERT INTO employee (empNo, empName, job, manager, hireDate, salary, deptNo)

VALUES (1014, '김광우', '사원', 1006, '2007-11-09', 250, 10);


위의 쿼리들을 이용해서 데이터세트를 구성하고 나서 아래의 기본 SELECT문을 이용하여 각각의 테이블을 조회하면 아래 사진과 같은 결과가 나와야 합니다.


-- SELECT TABLE

SELECT * FROM department;




SELECT * FROM employee;



그럼 위의 데이터들을 바탕으로 SELECT 문에 대해서 학습해보도록 하겠습니다.



2. SELECT


기본적으로 SELECT 문은 아래와 같은 형태를 띄고 있습니다.


SELECT <COLUMN NAME1, COLUMN NAME2, ...>

FROM <TABLE NAME>;


물론 해당 SELECT 문에 WHERE 문이라는, 조건절이 추가적으로 붙어서 사용되는 경우가 많지만 이번 포스팅에서 해당 내용은 제외하고 심플하게 SELECT문에 대해서만 알아보도록 하겠습니다.


SELECT문 에서는 특정 테이블에서 내가 원하는 컬럼에 대한 데이터만 조회할 수 있습니다.

이때 조회하고자 하는 테이블이름과 조회하고자 하는 컬럼명을 적어주어야 합니다.

그럼 employee 테이블에서 empName과 job, salary를 조회해보도록 하겠습니다.


SELECT empName, job, salary

FROM employee;




* SELECT문에서 연산자 이용하기


이번에는 SELECT 문에서 연산자를 이용해보는 실습을 진행해보겠습니다.

현재 우리는 salary에 대한 데이터를 가지고 있는데, 만약 연봉값을 알고 싶을 땐 어떻게 해야할까요?

간단하게 생각해보면, salary는 월급이므로 salary에 12를 곱하면 연봉이 될 것입니다.

SELECT 문에서는 연산자 이용이 가능합니다. 따라서 연봉을 구하기 위해 salary에 12를 곱해주면 되는 것이죠.


아래와 같이 쿼리문을 작성함으로써 employee들의 연봉 값을 같이 구할 수 있습니다.


SELECT empName, job, salary, salary*12

FROM employee;




위의 결과를 보면 salary에 12를 곱한 값들도 함께 출력되는 것을 확인할 수 있습니다.

하지만 해당 열이름을 보면 (열 이름 없음) 이라는 값으로 나와서 그것이 연봉인지는 모두가 알기 쉽지 않을 것 입니다.

그럼 우리가 원하는 열 이름을 지정해줄 수 있다면 어떨까요?

당연히 해당 기능을 지원하고 많이 이용되고 있습니다.



* as 를 이용한 열 이름 별칭 사용하기


해당 기능을 열 이름에 별칭을 사용한다고 표현합니다.

별칭이라는 말 그대로, 원래 이름대신 별명을 이용하는 것이라고 생각하시면 됩니다.

이는 위에서 본 (열 이름 없이)와 같이 새롭게 생성된 열 이외에도, 기존의 열에도 사용 가능합니다.

아래의 쿼리와 같이 작성함으로써 각각의 열에 대해서 우리가 원하는 이름을 지정할 수 있습니다.

SELECT empName as 사원이름, job as 직급, salary as 월급, salary*12 as 연봉

FROM employee;



위와 같이 as 뒤에 설정한 이름이 출력되는 열의 이름이 된 것을 확인할 수 있습니다.


추가로, 아래와 같이 as 라는 예약어는 생략가능하며, 만약 우리가 지어주는 열 이름에 띄어쓰기를 넣고 싶다면 아래와 같이 별칭 값을 홀 따옴표로 묶어줘야 합니다.




그런데 사실 연봉에는 commission 값도 포함되어야 합니다.

그럼 연봉에 해당 값을 같이 더해서 출력해보겠습니다.

우리가 * 연산을 활용한 것과 같이 그대로 + 연산을 활용하면 됩니다.


SELECT empName 사원이름, job 직급, salary 월급, (salary*12) + commission '연  봉'

FROM employee;



하지만 결과를 보면, 우리가 생각하지 못했던 NULL 값이 출력되고 있습니다.

왜 이런 결과가 나오는 것 일까요?



* NULL 값


먼저 그 이유를 알아보자면, NULL과 함께 연산했기 때문에 그 결과가 NULL로 나오는 것 입니다.


기존의 데이터를 살펴보면 commission 값을 NULL로 설정한 행들이 있습니다.

그리고 위의 결과와 대조해 보았을 때 commission 값이 NULL인 행들의 연봉이 NULL로 나온 것을 볼 수 있습니다.

즉, 덧셈 연산을 통해 특정 값에 NULL을 더했기 때문에 그 결과도 NULL이 나오는 것 입니다.

도대체 NULL이 정확이 무엇이길래, 그러한 결과가 될까요?


NULL은 0이라는 값이나, 문자열에서의 공백을 의미하는 것이 아닙니다.

그렇다고 해서 값이 저장되는 공간을 의미하는 것도 아닙니다.

NULL은 정말 단순하게, 인식되지 않는 값, 미확정 값을 의미합니다.


즉 NULL 값이란 어떠한 값이 존재하는 것이지만 어떠한 값인지 우리가 알 수 없는 것 입니다.

NULL 값이 단순하게 하나로 정의되기 보다는 우리가 인식하지 못하는, 어떠한 값이라고 이야기할 수 없는 모든 값이 NULL로 표현됩니다.

이해를 위해 특정 NULL의 값이 3a937f8b13 이라고 해봅시다.

그런데 만약 해당 값에 5000 이라는 값을 더하면, 우리가 인식할 수 있는 값이 될까요?

그렇지 않습니다. 우리가 5000 이라는 인식할 수 있는 값이 있었지만 해당 값과 인식하지 못하는 값을 더했기 때문에 결국 그 결과도 인식할 수 없는 결과가 되어 버립니다.


따라서 연산에서도, NULL을 이용한 연산을 한다면 그 결과 또한 항상 NULL이 되어버립니다.


그럼 이렇게 NULL이 포함된 값에 대해서 연산을 수행할 때, 그 결과가 NULL이 나오지 않게 하려면 어떻게 해야 할까요?



* isnull 함수 사용하기


바로, isnull() 이라는 내장함수를 사용하면 됩니다.

내장함수라는 것은 말 그대로, 외부에서 호출(import)을 하지 않아도 내부에 저장되어 있어 즉시에 사용할 수 있는 함수를 이야기합니다.

isnull함수는 다음과 같이 사용될 수 있습니다.


isnull(field, val)


위와 같이 사용되는 isnull함수는 field의 값이 null일때 val값으로 대치(변경)되어 처리됩니다.


말이 조금 어렵다면 바로 아래와 같이 쿼리를 작성하여 그 결과를 보고 이해해보도록 합시다.


SELECT empName 사원이름, job 직급, salary 월급, isnull(commission, 0) 보너스, (salary*12) + isnull(commission, 0) '연  봉' FROM employee;



아까와 달리 NULL이라는 결과가 나오지 않고, 제대로 결과가 출력됨을 볼 수 있습니다.



* distinct


그럼 이번에는 회사에 있는 직급들에 대해서만 한번 출력해보도록 하겠습니다.


SELECT job as 직급 FROM employee;


위와 같이 회사내의 직원들의 직급이 전부 출력되었습니다.

하지만 위의 결과에서는 직급에 대해 중복되는 결과들이 있기에 실제로 회사에 어떤 직급들이 존재하는지 보기가 편리한 결과는 아닙니다.

즉, 중복되는 값들을 출력되지 않게 한다면 회사 내에 존재하는 직급들을 확인하는데 보다 편리할 것 입니다.

이렇게, 중복되는 값들은 출력되지 않도록 하는 것이 distinct 입니다.

아래의 쿼리를 통해 확인해보도록 하겠습니다.


SELECT DISTINCT job as 직급 FROM employee;


그럼 아래와 같은 쿼리는 어떨까요?


SELECT DISTINCT job as 직급, empName as 사원이름 FROM employee;


이전의 쿼리와 달리, 직급의 중복 데이터가 존재합니다.

즉 DISTINCT는 특정 칼럼에 대해서만 중복을 확인하는 것이 아니라, 출력되는 각 행(레코드)의 중복을 체크하는 것입니다.

다시 말해서, 출력된 결과의 1번과 2번의 직급은 과장으로 동일하지만 사원이름이 서로 다르기 때문에 중복된 행이 아닙니다. 따라서 DISTINCT에 의해 생략되지 않고 둘 다 출력되는 것 입니다.



* 애스터리스크(*)


마지막으로는 애스터리스크라고도 불리는, 별표(*)에 대해서 알아보고 오늘 글을 마무리하려 합니다.

사실 이전에도 몇번 만나보았고 간단하게 설명드렸던 내용입니다.

이전에 우리가 아래와 같은 쿼리를 작성했던 것 기억하시나요?


SELECT * FROM employee;

위의 쿼리에서 *를 애스터리스트, 별표라고 합니다.

그리고 그 의미는 모든 값을 의미하는 것이죠.

즉, employee에 있는 모든 칼럼을 의미하기 때문에 해당 쿼리의 결과는 아래 사진과 같이 employee 테이블의 모든 칼럼에 대한 값을 출력하게 됩니다.




이렇게 해서 SELECT 문에 대한 글을 마무리합니다.


물론 추후에 WHERE절이 붙거나 JOIN, 서브쿼리를 이용하는 등의 작업에 있어서 SELECT 문에 대해서도 더 알아보아야 할 내용들이 많겠지만, 간단한 내용부터 하나씩 알아갈 예정입니다.

처음 SQL을 공부하시는 분들은 꼭 위의 내용에 대해서 이해해주셔야 추후에 더 복잡한 쿼리문에 있어서 어렵지 않게 공부하실 수 있을 것이라 생각됩니다.

더 궁금한 점이나 잘못된 부분에 대해서는 언제든지 거침없이 말씀해주시면 감사하겠습니다 :)


블로그 이미지

Tigercow.Door

Back-end / Python / Database / AI / Algorithm / DeepLearning / etc

댓글을 달아 주세요

안녕하세요. 문범우입니다.

지난 포스팅에서는 SSMS의 개체탐색기를 이용하며 데이터베이스 구축을 진행해보았습니다.

이번 포스팅에서는 같은 과정에 대해서 Transact-SQL을 이용해 진행해보도록 하겠습니다.


1. 데이터베이스 구축하기

 

먼저 아래와 같이 SSMS를 실행시키고 상단의 새쿼리 메뉴를 클릭합니다.

빨간색 박스에 master로 설정되어 있는 것을 확인합니다.

 

우리는 먼저 데이터베이스를 만들고 해당 데이터베이스 내부에 테이블이나 데이터를 추가할 것이니, 먼저 master를 선택하여 데이터베이스를 만들어야 합니다.

 

그럼 우측, 쿼리를 입력할 수 있는 곳에 아래와 같이 데이터베이스 생성 쿼리를 입력해봅니다.

 

create database <database명>

 

위의 쿼리문은 데이터 정의어(DDL) 중의 하나인 create문을 이용하는 쿼리입니다.

 

위의 쿼리문을 실행시키기 위해서 해당 쿼리문을 블록처리하고 F5를 눌러 실행시킵니다.

그리고 좌측의 개체탐색기 > 데이터베이스를 확인하면 Test02 라는 데이터베이스가 새로 생긴것을 확인할 수 있습니다.

 

이제 우리가 방금 생성한 Test02 라는 데이터베이스 내에 새로운 테이블을 생성하고 데이터를 추가해야 합니다.

하지만 우리가 처음 시작할 때 master 로 설정하고 시작한 것을 기억하시나요?

이 상태에서 테이블을 생성하거나 데이터를 입력하려고 하면 우리가 원하는대로, Test02 라는 데이터베이스에 데이터가 기록되지 않고 시스템 데이터베이스에 기록되게 됩니다.

따라서 우리가 앞으로 Test02에서 작업하겠다고 컴퓨터에게 알려주어야 합니다.

이를 위해서 아래와 같은 쿼리를 입력합니다.

 

use Test02;

 

위의 쿼리문을 실행하면 아래와 같이 master 로 선택되어있던 것이 Test02로 바뀐것을 확인할 수 있습니다.

 

그럼 이제 Test02에 새로운 테이블을 만들어 보도록합시다.

새로운 테이블을 만들때에도 데이터베이스 생성과 동일하게 create 문을 이용합니다.

 

create table member(
    id int constraint pk_code primary key,
    name char(10),
    email char(10)
);

 

쿼리를 실행시킬 때는 실행시키고자 하는 부분만 블록으로 감싸 F5를 눌러야합니다.

특정 부분을 블록으로 감싸지 않고 F5를 누르면 해당 쿼리창의 시작부터 끝까지 모든 쿼리가 다시 실행되므로 에러가 발생할 수 있습니다.

 

위의 쿼리를 잠시 살펴보면, create 문을 사용하였지만 database 생성시와는 다르게 테이블명 뒤에 소괄호가 있고 그 내부에 여러 정보가 있습니다.

테이블은 특정 칼럼과 그 칼럼에 대한 설명이 존재하기 때문에 위와 같은 형태를 띄게 됩니다.

 

위의 쿼리에서, member 테이블은 id, name, email 이라는 3개의 칼럼을 가지고 있습니다.

그리고 id는 int형 데이터 타입, name과 email은 모두 char(10) 이라는 데이터 타입을 가집니다.

추가적으로 id 칼럼은 contraint pk_code primary key 라고 붙어있는데, 여기서 constraint는 해당 칼럼에 특정 제약조건을 주겠다라는 의미이고 그 제약조건의 내용이 뒤에 따라서 붙습니다.

여기서는 pk_code primary key 라는 제약조건이 붙었는데, 이는 pk_code 라는 이름의 primary key로 설정하겠다라는 의미입니다.

즉, member 테이블에서의 primary key, 기본키는 id컬럼이며 해당 기본키의 이름은 pk_code인 것 입니다.

 

그런데 이렇게 테이블을 만들고 보니 name이름에 null이 들어가면 안되는 것을 깜빡했습니다.

name이라는 칼럼에 not null 속성을 추가해주어야 하는데, 그렇다고 해서 테이블을 통째로 지우고 다시 날리는 것은 너무나 비효율적입니다.

이렇게 테이블의 속성을 변경하기 위해 데이터 정의어(DDL)에서 ALTER구문이 존재합니다.

 

ALTER문을 이용하여 member 테이블의 name 칼럼의 속성을 변경해보도록 하겠습니다.

 

alter table member
alter column name char(10) not null;

 

먼저 어떤 테이블에 대해서 변경을 진행할 지 알려줍니다.

그리고 column을 수정하는데 어떤 칼럼을 수정하는지 해당 칼럼의 이름을 적어주고 이후 속성을 그대로 적어줍니다.

우리가 not null만 추가하고자 했으나 char(10)까지 그대로 적어주는 이유는 해당 alter 구문이 추가하는 명령이 아닌 변경하는 명령이기 때문입니다.

즉, char(10) 이라는 속성을 가진 칼럼을 char(10) not null 속성을 가지도록 변경하는 것 입니다.

 

그럼 이제 우리가 만든 member 테이블에 데이터를 직접 입력해주도록 하겠습니다.

이렇게 데이터를 입력하거나 조회, 수정, 삭제하는 쿼리를 데이터 조작어(DML) 이라고 합니다.

데이터 조작어에는 크게 INSERT(삽입), UPDATE(수정), DELETE(삭제), SELECT(조회) 네가지가 있으나 이번 포스팅에서는 단순히 Transact-SQL을 경험해보는 것이 목적이기 때문에 INSERT와 SELECT문에 대해 간단히 사용만 하도록 하겠습니다.

 

해당 쿼리문들에 대해서는 추후에 좀 더 자세히 알아볼 것이니 잘 이해가 가지 않아도 괜찮습니다.

 

먼저 member 테이블에 아래와 같은 쿼리로 데이터를 입력합니다.

 

insert into member values(10, '홍범우', 'hong@email');

 

위의 쿼리는, member 라는 테이블에 데이터를 insert 할 것이다라는 의미입니다.

그리고 입력되는 데이터의 내용은 values(~~~) 내부에 입력합니다.

 

해당 쿼리를 실행시키고, 우리가 입력한 데이터가 잘 저장되었나 확인하기 위해서 아래 쿼리를 입력합니다.

 

select * from member;

 

select 문은 데이터를 조회하는 쿼리문 입니다.

select 문을 통해서 어떤 칼럼을 조회할 지 선택할 수 있는데, 이때 * 의 의미는 모든 것을 의미합니다.

즉, 위의 쿼리는 특정 칼럼만 확인하는게 아니라 모든 칼럼을 조회하겠다는 의미이고, 배경이 되는 테이블이 member라는 것을 알려주기 위해 from ~ 절을 작성해준 것 입니다.

 

위의 select 쿼리를 실행시키면 아래와 같이 우리가 위에서 입력한 데이터가 정상적으로 입력된 것을 볼 수 있습니다.

 


이렇게 해서 간단하게 Transact-SQL 을 통해 데이터베이스를 구축하는 방법에 대해서 알아보았습니다.

 

블로그 이미지

Tigercow.Door

Back-end / Python / Database / AI / Algorithm / DeepLearning / etc

댓글을 달아 주세요

안녕하세요. 문범우입니다.

이번 포스팅에서는 SQL Server 에서의 데이터 타입과 SQL에 대해서 간단하게 알아보고, 직접 데이터베이스를 구축해보는 실습 과정을 진행하도록 하겠습니다.

 

 


1. 데이터 타입(DataType)

 

SQL Server에서 사용하는 데이터 타입과 그 범위는 아래와 같습니다.

 

- 정수타입

tinyint : 0~255

smallint : -32768 ~ 32767

int : -2^31 ~ 2^31 - 1

 

- 날짜 시간 타입

datetime : 1753-1-1 ~ 9999-12-31

smalldatetime : 1900-1-1 ~ 2079-6-6

 

- 문자타입

char[(n)] : 고정형 길이

varchar[(n)] : 가변형 길이

 

물론 이 외에도 다른 데이터 타입이 존재하지만, 현재 학습하는 과정에서 기초적으로 알아두어야 할 것들에 대해서만 나열해보았습니다.

 

2. SQL(Structured Query Language)

 

SQL은 기능에 따라서 총 3가지로 나누어 볼 수 있습니다.

 

- 데이터 정의어(DDL) : CREATE, ALTER, DROP 등

   테이블이나 테이블 간의 관계를 생성 및 수정하는데 사용하는 것

 

- 데이터 조작어(DML) : SELECT, INSERT, DELETE, UPDATE 등

   테이블에 데이터를 검색하거나 삽입, 삭제, 수정하는데 사용하는 것

 

- 데이터 제어어(DCL) : GRANT, REVOKE 등

   데이터에 대한 사용 권한을 제어하거나 관리하는 데 사용하는 것

 

위와 같이 기능에 따라 총 3가지로 나누어 볼 수 있으며, 각각에 대해서는 앞으로 학습을 하며 좀 더 자세히 알아보도록 하겠습니다.

 

 

3. 데이터베이스 구축하기

 

이제 실제로 SQL Server에 데이터베이스를 구축해보도록 하겠습니다.

먼저 지난번에 설치한 SSMS를 실행시켜서 SQL Server에 연결시켜서 아래와 같은 화면이 보이도록 합니다.

 

데이터베이스를 구축하는 방법은 총 2가지가 존재하는데 이에 대해서 실습을 진행해보도록 하겠습니다.

2가지 방법은 이번 글에서 알아볼 개체탐색기를 이용하는 방법과 다음 포스팅에서 알아볼 Transact-SQL을 이용한 방법입니다.

- 데이터베이스 만들기

먼저 첫번째로 이번 글에서는 좌측에 보이는 개체탐색기를 이용합니다.

개체탐색기에서 데이터베이스에 우클릭을 하여 새 데이터베이스를 클릭하여 아래와 같은 화면이 뜨도록 합니다.

 

이제 여기서 새롭게 만들 데이터베이스 이름을 설정합니다.

또한 소유자는 현재 기본값으로 되어 있는데 이러한 경우 기본적으로 연결되어있는 유저가 소유자가 됩니다.

 

이렇게 설정하고 확인을 눌러주고 나면 좌측의 개체탐색기의 데이터베이스 내부에 Text01이라는 데이터베이스가 새로 생긴것을 확인할 수 있습니다.

또한 Test01 내부를 보면 테이블, 뷰와 같은 것들이 자동으로 생긴것을 볼 수 있습니다.

 

- 테이블 만들기

그럼 이어서 Test01에 새로운 테이블을 만들어보도록 하겠습니다.

이번에는 데이터베이스 > Test01 > 테이블을 우클릭 하여 테이블을 클릭하여 아래와 같은 창이 뜨도록 합니다.

새롭게 뜬 창을 보면 열이름과 데이터 형식 등을 기입할 수 있도록 되어 있습니다.

해당 창에 아래 사진과 같이 열과 데이터 형식, Null 허용 체크를 맞추어 채워보도록 합니다.

위와 같이 3개 필드를 추가하셨다면 Ctrl+s 또는 화면 상단의 저장버튼을 눌러서 저장하는데 이때 테이블 이름은 member 로 설정하도록 합니다.

 

정상적으로 저장이 되었다면, 좌측 개체탐색기에서 Test01 > 테이블에 dbo.member 라는 것이 새로 생긴것을 확인할 수 있습니다.

 

- 기본키 설정

이제 특정 칼럼에 대해서 기본키설정을 해보겠습니다.

 

먼저 기본키란, 간단히 얘기해서 동일 테이블 내에서 행을 유니크하게 구별할 수 있는 값을 이야기합니다.

따라서 기본키로 설정된 값은 서로 중복될 수 없으며 null이 허용되지 않습니다.

 

 dbo.member 탭에서 id를 우클릭하면 아래 사진과 같이 여러가지가 나오는데 이중에서 기본 키 설정을 클릭합니다.

 

 

그럼 id라는 값 좌측에 노란색 열쇠모양이 생긴 것을 확인 할 수 있습니다.

 

이제 새로운 테이블을 만들어 보도록 하겠습니다.

방법은 위에서 했던 것과 동일하며 아래와 같이 3개의 컬럼을 가지도록 테이블을 만들어 줍니다.

 

그리고 테이블 이름은 Product로 설정합니다.

 

이렇게 하여 새로 테이블을 추가하였는데, 아까와 달리 좌측 개체탐색기에 dbo.Product 테이블이 보이지 않는다면 F5를 눌러 새로고침하거나, 개체탐색기 창의 상단에 있는 새로고침 버튼을 눌러줍니다.

 

- 데이터 추가

이제 member 테이블에 데이터를 추가해보도록 하겠습니다.

개체탐색기에서 dbo.member 를 우클릭하고 상위 200개 행 편집을 선택합니다.

 

그리고 아래 사진과 같이 데이터를 입력합니다.

데이터를 입력때는 Tab 키를 이용하면 편리하게 입력이 가능하고, 위의 사진에서 빨간색 느낌표가 있는 이유는 아직 해당 행의 데이터가 저장되지 않았다는 의미입니다.

다음 행으로 넘어가게 되면 자동적으로 이전 행이 추가(저장)됩니다.

그리고 특정행을 삭제하기 위해서는 id 열의 좌측에 빈공간을 우클릭하여 삭제를 누르시면 됩니다.

 

그럼 이번에는 Proudct 테이블에 아래 사진과 같은 데이터를 입력해보도록 합니다.

 

- 데이터 확인

이제 실제로 쿼리문을 통해 데이터가 정상적으로 입력되었는지 확인해보도록 하겠습니다.

 

SSMS 상단에보면 새쿼리 라는 메뉴가 있는데 이것을 클릭합니다.

그리고 아래 사진과 같이 Test01 데이터베이스가 선택되어있는지 확인합니다.

 

그럼 이제 새롭게 열린 쿼리 창에 쿼리문을 작성해보도록 하겠습니다.

 

쿼리문에 대해서는 추후에 공부하도록 하고, 지금은 단순히 데이터가 입력되었는지를 확인하는 것이니, 쿼리문에 대해 정확히 알지 못해도 일단 따라서 입력하겠습니다.

 

select * from member;

 

 위의 쿼리문을 입력하고 F5 버튼을 눌러서 쿼리문을 실행시키면 아래와 같은 결과가 나옵니다.

 

즉, 우리가 좀전에 입력한 3개의 데이터가 잘 입력된 것을 확인할 수 있습니다.

 

동일한 방식으로 아래 쿼리를 통해 Product 테이블에 추가한 데이터도 확인할 수 있습니다.

 

select * from Product;

 

 


이렇게 해서 기초적인 데이터베이스 구축방법에 대해서 실습과정을 진행하였습니다.

기존의 다른 데이터베이스에 대해서 공부하셨던 분들은 매우 쉽게 느껴졌을 것이라 생각합니다. 하지만 SQL Server를 사용하기 위해 SSMS를 잘 다루는 것도 중요하니, 꼭 한번씩 실습과정을 진행하시기를 추천드립니다.

블로그 이미지

Tigercow.Door

Back-end / Python / Database / AI / Algorithm / DeepLearning / etc

댓글을 달아 주세요

안녕하세요. 문범우입니다.

이번 포스트에서는 몽고db에서 사용되는 update() 메소드와 제한자에 대해서 알아보도록 하겠습니다.



먼저 오늘 알아볼 내용에 앞서, 필요한 mock-up 데이터는 아래와 같습니다.



위의 데이터를 만드는 쿼리문은 아래와 같습니다.





1. 업데이트(Update)


특정 다큐먼트(document)를 수정하는 업데이트에 대해서 알아보도록 하겠습니다.

userItem에 있는 어둠의 단도라는 항목의 price를 수정해보도록 할게요.

현재 어둠의 단도의 가격은 980,000,000입니다. 해당 가격을 1,000,000,000 으로 바꿔볼게요!


mongoDB의 공식문서를 살펴보면 update메소드는 다음과 같은 구조를 가지고 있습니다.


db.COLLECTION.update(

<query>,<update>,

{

upsert: <boolean>,

multi: <boolean>,

writeConcern: <document>,

collation: <document>

}

)


구조에 있는 각각의 인자에 대한 설명은 아래와 같습니다.


Parameter

Type

Description

query

document

업데이트를 할 항목을 선택합니다. find() 함수에서 사용되는 것과 동일합니다.

update

document

선택된 document에 적용할 수정사항을 입력합니다.

upsert

boolean

Optional. (기본값: false) 만약 해당 값을 true로 설정하면, query한 document가 없을 경우 새로운 document를 추가합니다.

multi

boolean

Optional. (기본값: false) 만약 해당 값을 true로 설정하면, query에 해당하는 다수의 document를 수정합니다.

writeConcern

document

Optional. document의 write concern을 표현합니다. 기본으로 사용할 때는 생략합니다. 자세한 설명을 위해서는 메뉴얼을 참고하세요.

collation

document

Optional. Collation을 통해 사용자는 대문자 및 악센트 부호와 같은 문자열 비교에 대한 언어별 규칙을 지정할 수 있습니다. collation은 기본적으로 다음과 같은 사항을 가지고 있습니다.

collation: {
   locale: <string>,
   caseLevel: <boolean>,
   caseFirst: <string>,
   strength: <int>,
   numericOrdering: <boolean>,
   alternate: <string>,
   maxVariable: <string>,
   backwards: <boolean>
}


위의 공식문서를 확인하여 어둠의 단도라는 item의 가격을 수정합니다.


쿼리문은 다음과 같습니다.


db.gameItem.update({name:"어둠의 단도"},{$set:{price:1000000000}});


<query>는 {name:"어둠의 단도"}로 하였습니다.

{_id:"i777"}로 해도 동일합니다.

<update>는 {$set:{price:1000000000}}으로 함으로써 price를 수정하도록 하였습니다.

$set은 제한자라고 불리는 것인데 제한자에 대한 자세한 것은 아래에서 더 살펴보도록 할게요.

아래 사진과 같이 올바른 결과를 나타냅니다.




2. 배열 데이터 추가, 삭제하기


mock-up data를 살펴보면 gameUser의 item 항목에는 배열로써 각 아이템의 _id값을 가지고 있습니다.

그렇다면 특정 유저가 아이템을 얻게되면 어떻게 표현할까요?

그리고 아이템을 잃게되면 어떻게 표현할까요?

위를 표현하기위해 배열항목에 데이터를 추가하거나 삭제하는 방법을 알아보도록 하겠습니다.


2-1. 추가하기


먼저 배열에 데이터를 추가해보도록 하겠습니다. 이 또한, 위에서 사용된 update() 함수를 사용합니다.

초보자라는 user에게 "초보자의 분노" 아이템을 추가해볼게요.

위의 document 수정에서는 $set이라는 제한자가 사용되었는데, 이번에는 $push라는 제한자를 사용합니다.

쿼리를 확인하면 다음과 같습니다.


db.gameUser.update({name:"초보자"},{$push:{item:"i004"}});


아래와 같이 올바른 결과를 나타냅니다.




2-2. 삭제하기


삭제또한, update() 함수를 사용하지만 제한자가 바뀌게 됩니다.

추가를 할땐 $push를 사용하였는데, 삭제에서는 $pull 제한자가 사용됩니다.

이번에는 장사꾼 user가 초보자의 갑옷을 버린 상황입니다.

즉, 장사꾼 user가 가진 item중 초보자의 갑옷을 삭제하도록 하겠습니다.

쿼리문은 다음과 같습니다.


db.gameUser.update({name:"장사꾼"},{$pull:{item:"i002"}});


이 또한 아래와 같이 올바른 결과를 나타냅니다.




3. 제한자


지금까지 document를 수정하고, document의 배열 항목에 데이터를 추가, 삭제하는 것을 알아보았습니다.

그런데 중간중간 '제한자'라는 개념이 등장했죠. 조금 더 구체적으로 말하면 이는 '갱신 제한자'입니다.

이번에는 갱신 제한자에 대해서 더 구체적으로 알아보도록 하겠습니다.


MongoDB에서 갱신 제한자라는 것은, 문서의 부분 갱신을 할때 매우 효율적으로 수행할 수 있도록 하는 개념입니다. document를 변경하거나 추가 또는 삭제하고, 배열과 같은 항목에 대한 연산을 하는데 사용될 수 있습니다.


그렇다면 갱신 제한자의 종류와 그 사용법에 대해서 알아보도록 하겠습니다.


갱신 제한자

설명

$set

document에서 특정 키의 값을 수정합니다. 특정 키가 존재하지 않다면 새롭게 생성합니다.

특정 키의 데이터형도 수정할 수 있습니다.

$unset

document에서 특정 키와 값을 모두 제거합니다.

$nc

배열에 사용되는 제한자로써, 지정된 키가 존재하는지 확인할 수 있습니다.

$inc

이미 존재하는 키의 값을 수정하거나, 새로운 키를 생성합니다. $set과 비슷하지만 주로 값이 자주 변경되는 값을 수정하는데 사용됩니다.

int, long, double 의 자료형에만 사용이 가능합니다.

$push

배열에 사용되는 제한자로써, 지정된 키가 존재할 때 해당 키(배열)의 끝에 요소를 추가하며 지정된 키가 존재 하지 않으면 새로운 배열을 추가합니다.

$pull

배열에 사용되는 제한자로써, 지정된 키에 대한 요소를 삭제합니다.

$addToSet

배열에 사용되는 제한자로써, 중복을 피해서 요소를 배열에 추가할 때 사용합니다. 즉, $nc와 $push를 함께 수행하는 기능과 같습니다.

$each

$addToSet과 함께 사용되는 제한자로써, 여러 개의 값을 중복되지 않게 배열에 추가합니다.

$pop

배열을 스택이나 큐처럼 활용할 수 있습니다.




블로그 이미지

Tigercow.Door

Back-end / Python / Database / AI / Algorithm / DeepLearning / etc

댓글을 달아 주세요


안녕하세요.

오늘은 mongoDB에서 데이터 자료형과 find함수, 쿼리연산자에 대해서 알아보도록 하겠습니다.

내용에 대한 피드백이나 궁금한 점은 언제든지 댓글을 남겨주세요 :)


1. 데이터 자료형(Datatypes)


MongoDB에는 많은 데이터 자료형을 지원합니다. 그 중 몇가지에 대해서만 알아보도록 하겠습니다.


String

 String은 데이터를 저장할때 가장 많이 사용되는 데이터 자료형 중 하나입니다. MongoDB에서 String은 반드시 UTF-8 형식만 가능합니다.

Integer

 숫자값을 저장할때 주로 사용되는 자료형입니다. Integer는 서버에 따라서 32bit 또는 64bit입니다.

Boolean

 이것은 참(true) 또는 거짓(false)를 나타내는 값을 저장하는 자료형입니다.

Double

 Double 자료형은 부동 소수점 값을 저장하는데 사용됩니다.

Min/Max keys

 이것은 BSON요소의 최저 값과 최고값을 비교하는데 사용됩니다.

Arrays

 Arrays 자료형은 배열 또는 여러 값을 하나의 키에 저장하는데 사용됩니다.

Timestamp

 해당 자료형은 문서가 수정되거나 추가될때 기록하기 편리합니다.

Object

 해당 자료형은 embedded documents에 사용됩니다.

Null

 Null 자료형은 Null 값을 저장할 떄 사용됩니다.

Symbol

 해당 자료형은 문자열(String)과 동일하게 사용됩니다. 하지만 일반적으로 특정 기호 유형을 사용하는 언어로 사용되고 있습니다.

Date

 Date 자료형은 현재의 날짜 또는 시간을 UNIX시간 형식으로 저장하는 데 사용됩니다. Date 객체를 만들어 내며 일, 월, 년을 전달하여 자신의 날짜 및 시간을 지정할 수 있습니다.

Object ID

 이것은 document의 ID를 저장하는데 사용됩니다.

Binary data

 이것은 2진수 데이터를 저장하는데 사용됩니다.

Code

 이것은 document 내부에 JavaScript 코드를 저장하는데 사용됩니다.

Regular expression

 이것은 정규 표현식을 저장하는데 사용됩니다.



2. Document 검색:: find() 함수


이번에는 Document를 검색하는 find() 함수에 대해서 알아보도록 하겠습니다.

먼저 find method에 대한 정의는 아래와 같습니다.


db.COLLLECTION-NAME.find(query,projection)


Parameter

Type

Description

query

document

Optional(선택적임).

검색시 보다 구체적인 내용을 반환받기 위해 조건을 입력. default로는 모든 값을 검색.

projection

document

Optional(선택적임).

검색후 반환 값(출력 값)을 어떤식으로 할지 결정함. default로는 모든 값을 출력. 


find는 위와 같은 구조를 가진 함수입니다. 그럼 바로 사용해볼까요?



위의 사진에서 순서대로 확인해보겠습니다.

먼저 사용할 데이터베이스를 선택하고, 어떠한 collection들이있는지 확인해보았습니다.

그리고 존재하는 firstCollection을 find()함수로 확인해보았습니다.

하나의 document가 존재하여 2개의 document를 추가하였습니다.

이후 find() 함수를 한번더 사용하였습니다.


이때, document가 한줄로 출력되서 보기 힘드신가요?

이러한 시각적 불편함을 해결하기위해 pretty() 함수가 있습니다.

함수이름대로, 보기좋게 document를 출력해주는 함수입니다.

아래 사진을 보시면 잘 이해가 가실거에요.



pretty() 함수를 사용하지 않았을떄와 사용했을떄의 차이가 보이시나요?



2-1. find() 함수 활용하기


find() 함수를 좀 더 응용해보도록 할게요.

기본적으로, collection에 있는 모든 다큐먼트를 조회하려면 어떻게 해야 할까요?

네. 맞습니다. 위에서 했던 것처럼,

db.COLLECTION-NAME.find()

를 입력하면 해당 컬렉션의 모든 document가 조회됩니다.


이제 몇가지 조건을 추가해볼게요.

위의 firstCollection을 바탕으로 하여, 성별(sex)가 남자(male)인 다큐먼트만 조회하려면 어떻게 해야할까요?

find() 함수의 정의에서 살펴본 것처럼, query parameter에 조건을 추가하면 되겠죠?


db.firstCollection.find({"sex":"male"})



한번 더 해보겠습니다.

그럼, 전공이 운동(sport)인 다큐먼트의 이름(name)을 조회하려면 어떻게 해야할까요?

네, 바로 query와 projection 두개다 적절히 조건을 추가하면 되겠습니다.


db.firstCollection.find({"major":"sport"},{"_id":false,"name":true})




3. 쿼리 연산자(Query operators)


이번에는 MongoDB에서 사용되는 쿼리 연산자(Query operators)에 대해서 살펴보겠습니다.

쿼리연산자는 위에서 알아본 find() 함수와 함께 응용되어 다양한 기능을 할 수 있습니다.

쿼리 연산자는 프로그래밍 언어에서 사용되는 비교(Comparison), 논리(Logical)등과 같은 다양한 종류의 연산자가 있습니다.

하나씩 살펴보기에 앞서, 연산자들에 대한 예제를 진행하기 위해서 기본 muck up data를 설정하겠습니다.


insert 코드는 아래와 같으며 그에 대한 muck up data를 find()함수로 확인하였습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
db.operatorTest.insert([
{
    "name":"John""sex":"male""major":"ECE""score":76"grade":"B"
},{
    "name":"Kai""sex":"male""major":"art""score":99"grade":"A"
},{
    "name":"Jane""sex":"female""major":"ECE""score":90"grade":"A"
},{
    "name":"Ko""sex":"male""major":"ECE""score":21"grade":"F"
},{
    "name":"Ki""sex":"female""major":"dance""score":79"grade":"B"
},{
    "name":"Bro""sex":"female""major":"art""score":68"grade":"C"
},{
    "name":"Victor""sex":"male""major":"ECE""score":49"grade":"D"
},{
    "name":"Kan""sex":"female""major":"art""score":61"grade":"C"
}
])
cs





3-1. 비교(Comparison)


연산자

설명(Description)

$eq

Matches values that equal to a specified value.

주어진 값과 동일한 값

$gt

Matches values that are greater than a specified value.

주어진 값보다 더 큰 값

$gte

Matches values that are greater than or equal to a specified value.

주어진 값보다 크거나 같은 값

$lt

Matches values that are than a specified value.

주어진 값보다 더 작은 값

$lte

Matches values that are less than or equal to a specified value.

주어진 값보다 작거나 같은 값

$ne

Matches all values that are not equal to a specified value.

주어진 값과 동일하지 않은 값

$in

Matches any of the values specified in an array.

주어진 배열에 속하는 어떤 값

$nin

Matches none of the values specified in an array.

주어진 배열에 속하지 않는 어떤 값


예제)

A) score의 값이 70이하이고, 45초과를 하는 document를 조회하여라.




B) grade가 [A,B,C,D]에 속하지 않는 document를 조회하여라.




C) major가 art인 document를 조회하여라.




3-2. 논리(Logical)


연산자

설명(Description)

$or

Joins query clauses with a logical OR returns all documents that match the conditions of either clause.

논리적 OR과 같은 의미로써, 주어진 조건 중 하나라도 true일때 true를 반환합니다.

$and

Joins query clauses with a logical AND returns all documents that match the conditions of both clauses.

논리적 AND와 같은 의미로써, 주어진 조건 중 모든 조건이 true일때 true를 반환합니다.

$not

Inverts the effect of a query expression and returns documents that do not match the query expression.

주어진 조건에 대해 반대 논리를 반환하는 것으로써, 주어진 조건이 false일때 true를 반환합니다.

$nor

Joins query clauses with a logical NOR returns all documents that fail to match both clauses.

주어진 조건 중 모든 조건이 false일때 true를 반환합니다.


예제)

A) 성별이 남자(male)이고 score가 50이하인 document를 조회하여라.




B) 전공(major)가 ECE가 아니고 score가 80미만이 아닌 document를 조회하여라.




C) 전공(major)가 ECE가 아니거나 score가 80미만이 아닌 document를 조회하여라.




3-3. 요소(Element)


연산자

설명(Description)

$exists

Matches documents that have the specified field.

주어진 필드를 가진 documents를 조회합니다.

$type

Selects documents if a field is of the specified type.

field가 지정된 유형인 경우 해당 documents를 선택합니다.



3-4. 평가(Evaluation)


연산자

설명(Description)

$mod

Performs a modulo operation on the value of a field and selects documents with a specified result.

field 값에 대한 modulo 연산을 수행하고 해당 결과가 있는 documents를 선택합니다.

$regex

Selects documents where values match a specified regular expression.

정규 표현식(regular expression)과 일치하는 documents를 선택합니다.

$text

Performs text search.

텍스트 검색을 수행합니다.

$where

Matches documents that satisfy a JavaScript expression.

JavaScript 표현식에 만족하는 documents를 조회합니다.



3-5. 배열(Array)


연산자

설명(Description)

$all

Matches arrays that contain all elements specified in the query.

query에 지정된 모든 요소를 포함하는 배열을 찾습니다.

$elemMatch

Selects documents if element in the array field matches all the specified $elemMatch conditions.

배열 field의 요소가 지정된 $elemMatch의 조건과 모두 일치하는 documents를 선택합니다.

$size

Selects documents if the array field is a specified size.

배열 field가 지정된 크기인 경우의 documents를 선택합니다.



네, 이렇게 해서 MongoDB에서 데이터 자료형과, find() 함수, 다양한 연산자에 대해서 알아보았습니다.

내용에 대한 피드백이나 궁금한 점은 언제나 댓글을 이용해주세요 :)

블로그 이미지

Tigercow.Door

Back-end / Python / Database / AI / Algorithm / DeepLearning / etc

댓글을 달아 주세요

  • undefined 2018.05.06 02:53  댓글주소  수정/삭제  댓글쓰기

    로그인한id에 저장된aaa필드의 내용을 모두 출력하려는데
    User.find({_id:req.user.aaa}) = aaa필드의 내용이 1개있을경우 검색되는데
    "aaa": "111, 222, 333" 등 여러개가입력되있을경우 에러가 발생합니다

    따로 스키마 옵션이있나요 아니면 find검색방법을 바꿔야할까요...
    연산자 이것저것대입해봤는데 이쪽이아닌거같아요 도움부탁드려요~~

  • undefined 2018.05.06 03:08  댓글주소  수정/삭제  댓글쓰기

    router.get("/:id", util.isLoggedin, checkPermission, function(req, res){
    User.find({_id:req.user.aaa}) // 1개있을때만가능 내_id에있는 aaa 내용 전부검색방법강구
    .populate("_id") // 1
    .sort("-createdAt")
    .exec(function(err, friends){
    if(err) return res.json(err);
    });
    });

    에러 : {"message":"Cast to ObjectId failed for value \"111, 222\" at path \"_id\" for model \"user\"","name":"CastError","stringValue":"\"111, 222\"","kind":"ObjectId","value":"111, 222","path":"_id"}

    입니다~~ 반갑습니다^^ 지금 컴터앞에서대기하고있어요 ㅋㅋ

  • Favicon of https://doorbw.tistory.com BlogIcon Tigercow.Door 2018.05.06 03:31 신고  댓글주소  수정/삭제  댓글쓰기

    으어ㅠㅠ저도컴터로확인해봐야할것같아요..제가 지금 밖이라..내일중에한번알아보고 댓달겠습니다!

  • undefined 2018.05.06 03:35  댓글주소  수정/삭제  댓글쓰기

    네네네네 감사해요!!! 쉬는날인데 죄송합니다 ㅠㅠ 좋은밤되세요~~

    • Favicon of https://doorbw.tistory.com BlogIcon Tigercow.Door 2018.05.06 13:56 신고  댓글주소  수정/삭제

      흠.. 좀 살펴보고 있는데 제가 js를 제대로 공부해보지 않아서 확실한 답변이 아닐수도 있겠네요 ㅠ
      일단 mongoose 를 사용하시는 것 같은데, 공식문서 (http://mongoosejs.com/docs/populate.html)를 보면 find함수 대신에 findOne함수를 사용하고 있어요. 제가 봤을때는 populate함수가 하나의 값에 대해서만 처리하는? 그런 함수인 것 같은데, 그런부분으로 문서 한번 살펴보셔도 될 것 같아요.
      그리고 제가 populate 함수를 아직 제대로 파악하지 못해서 그러는데, 로그인한 id의 저장된 aaa필드의 내용을 모두 출력하려면 아래와 같이 단순하게 작성될 수 있지 않을까요?
      (User.find({_id:<로그인된 id>})).aaa 이런식으로?.. 혹시 가능하시다면 db 구성한거랑 코드전문 보여주시면 저도 좀 더 찾아볼게요!
      가능하시면 doorbw@outlook.com 으로 보내주세요 :) 즐거운 주말 되세요!

  • undefined 2018.05.06 18:03  댓글주소  수정/삭제  댓글쓰기

    혹시 저한테 댓글다신건가요? 비밀글로되어있어서 제가 못읽어요~ 권한이없대요ㅠ

  • Favicon of https://doorbw.tistory.com BlogIcon Tigercow.Door 2018.05.06 18:03 신고  댓글주소  수정/삭제  댓글쓰기

    수정했습니다!

  • undefined 2018.05.08 19:53  댓글주소  수정/삭제  댓글쓰기

    연휴는 잘 보내셨나요? 저는 지금도 씨름중입니다 ㅋ
    문의드린부분만수정해서되는게 아니라
    전체적으로 뭔가 잘못돌아가고있는듯해요
    기본이안잡혀있는데 만들려고하니까 코드도 중구난방, 문제 파악도잘안되네요;;;
    친절히상담해주셔서 감사해요~~~~~
    다시 댓글드릴게요ㅠ

  • Favicon of https://blog.djjproject.com BlogIcon ㅋㅋ잠자 2018.06.30 13:12 신고  댓글주소  수정/삭제  댓글쓰기

    저기 궁금한게 생겼는데요. 혹시 몽고 DB 는 몽고에서 만들어서 몽고DB 인가요?


안녕하세요. 문범우입니다.

이번에는 지난 포스팅에 이어서 MySQL의 'SELECT 조건에 따른 데이터 검색'에 대한 명령어를 알아보겠습니다.




SELECT (속성1, 속성2, … ) FROM (테이블명) WHERE (조건식);

(조건식)에 의해 해당하는 행을 선택하고 (속성1, 속성2, … )에 의해 열을 선택합니다.

 

SELECT * FROM (테이블명);

WHERE 조건문이 없으므로 모든 행을 선택하고, *(: 모든)을 통해 모든 열을 선택합니다.

(테이블명)의 이름을 가진 테이블을 확인하는 명령어입니다.

 

SELECT * FROM (테이블명) WHERE (조건1) AND (조건2);

(테이블명)의 테이블에서 (조건1) (조건2)를 모두 만족하는 행의 모든 열을 선택합니다.

 

SELECT * FROM (테이블명) WHERE (속성1) BETWEEN (1) AND (2);

(테이블명)의 테이블에서 (속성1)의 값이 (1)(2) 사이인 행의 모든 열을 선택합니다.

 

          - 참고

           아래 두 명령어를 비교합니다.

           SELECT * FROM (테이블명) WHERE age > 19 AND age < 30;

           SELECT * FROM (테이블명) WHERE age BETWEEN 19 AND 30;

           두 명령어를 통한 결과 값은 같지만 성능은 BETWEEN을 사용한 명령어가 더 좋습니다.

            

           단순히 AND만 사용한 첫번째 쿼리는

           전체 데이터에서 age19보다 큰 값과 30보다 작은 데이터를 각각 구해 이들의 교집합 값을 구하는 연산이며

           BETWEEN을 사용한 두번째 쿼리는

           age라는 속성에서 19라는 값부터 시작하여 30이라는 값보다 작은 값을 찾는 연산이기 때문입니다.

 

SELECT * FROM (테이블명) WHERE (조건1) OR (조건2);

(테이블명)의 테이블에서 (조건1) (조건2) 중 어떤 하나라도 만족하는 행의 모든 열을 선택합니다.

 

SELECT * FROM (테이블명) WHERE (속성1) IN (조건1, 조건2, … );

(테이블명)의 테이블에서 (속성1)의 값이 (조건1)이거나 (조건2) 인 행의 모든 열을 선택합니다.

 

          - 참고

           IN을 사용한 구문 또한 BETWEEN을 사용한 구문과 같이 OR보다 성능이 좋습니다.

           아래 두 쿼리를 비교합니다.

 SELECT * FROM (테이블명) WHERE age = 19 OR age = 20 OR age = 21;

           SELECT * FROM (테이블명) WHERE age IN (19,20,21);

           두 쿼리 모두 같은 결과를 출력하지만 IN을 사용한 두번째 쿼리가 성능이 좋습니다.

 

          - 참고

          AND 연산이 OR 연산보다 우선순위가 높습니다.

          , age19 또는 20인 열과 birth1998 또는 1999인 행의 모든 열을 선택하려면

          SELECT * FROM (테이블명) WHERE age = 19 OR age = 20 AND birth = 1998 OR birth = 1999;

가 아닌

SELECT * FROM (테이블명) WHERE (age = 19 OR age = 20)AND(birth = 1998 OR birth = 1999);

를 입력해야 합니다.

 

SELECT * FROM (테이블명) WHERE NOT (조건1);

(테이블명)의 테이블에서 (조건1)을 만족하지 않는 행의 모든 열을 선택합니다.


SELECT * FROM (테이블명) WHERE (속성1) LIKE ‘A_’;

(테이블명)의 테이블에서 (속성1) ‘A+1글자값을 가진 행의 모든 열을 선택합니다.

 

SELECT * FROM (테이블명) WHERE (속성1) LIKE ‘A__’;

(테이블명)의 테이블에서 (속성1) ‘A+2글자값을 가진 행의 모든 열을 선택합니다.


          - 참고

          위의 _ 관련 쿼리의 예제입니다.

          


SELECT * FROM (테이블명) WHERE (속성1) LIKE ‘A%’;

(테이블명)의 테이블에서 (속성1) ‘A’로 시작하는 값을 가진 행의 모든 열을 선택합니다.


SELECT * FROM (테이블명) WHERE (속성1) LIKE ‘%A’;

(테이블명)의 테이블에서 (속성1) ‘A’로 끝나는 값을 가진 행의 모든 열을 선택합니다.

 

SELECT * FROM (테이블명) WHERE (속성1) LIKE ‘%A%’;

(테이블명)의 테이블에서 (속성1) ‘A’를 포함하는 값을 가진 행의 모든 열을 선택합니다.

 

          - 참고

             위의 % 관련 쿼리의 예제입니다.

 


SELECT * FROM (테이블명) ORDER BY (속성1) (순서);

(테이블명)이란 테이블에서 (속성1)(순서)에 따라 모든 열을 출력합니다.

이따 (순서)에는 DESC(내림차순) 또는 ASC(오름차순)을 입력하며 생략했을시의 default 값은 ASC(오름차순) 입니다.

 

SELECT (속성1) AS ‘별명1’, (속성2) AS ‘별명2’ FROM (테이블명);

(테이블명)이란 테이블에서 (속성1)은 별명1이란 이름으로, (속성2)는 별명2라는 이름으로 두개의 열을 출력한다.

 

SELECT DISTINCT (속성1), (속성2), … FROM (테이블명);

(테이블명)이란 테이블에서 (속성1), (속성2), … 를 선택하는데 이때 중복되는 값은 제외합니다.

 

          - 참고

             DISTINCT 관련 쿼리를 예제를 통해 확인합니다. 두 명령어에 따른 출력 값의 차이를 확인하세요.


             기본테이블

 


DISTINCT 쿼리에 따른 차이


 


이렇게 해서 MySQL에서 SELECT 조건에 따른 데이터 검색에 관한 명령어를 알아보았습니다.

다음 포스팅에서부턴 특정 예제를 기준으로 하여 명령어를 알아보도록 하겠습니다.

피드백이나 문의사항은 댓글 및 이메일(doorbw@outlook.com)을 이용해주세요 :)

 

 

블로그 이미지

Tigercow.Door

Back-end / Python / Database / AI / Algorithm / DeepLearning / etc

댓글을 달아 주세요


안녕하세요.

데이터베이스를 학교에서 공부중에 있는데 MySQL을 사용하여 수업을 하고 있습니다.

따라서 MySQL에서 사용되는 명령어들을 정리할겸 포스팅을 진행하려 합니다.

각각의 명령어들을 최대한 순서(?)에 맞춰서 의미들을 설명하려하는데

부족한 점이 있거나 추가적인 명령어들이 있다면 덧글로 피드백 해주세요 :)


이번 포스팅에서 공부해볼 내용은 'Database 및 Table 생성 / 확인 / 제거 / 수정' 에 대한 명령어 입니다.

다음 포스팅에서는 '조건에 따른 데이터 검색'에 대한 명령어를 알아보겠습니다.


CREATE DATABASE 데이터베이스명 default CHARACTER SET UTF8;

(데이터베이스명)이라는 데이터 베이스를 생성하고 한글을 사용할 수 있는 UTF8로 문자열을 저장

 

GRANT ALL PRIVILEGES ON (데이터베이스명).* TO (사용자)@localhost INDENTIFIED BY ‘(비밀번호)’;

GRANT는 사용자에게 데이터베이스의 사용권한을 적용하는 구문입니다.

ALL PRIVILEGES 는 데이터베이스에 대한 모든 권한을 의미합니다. (DB 삭제 또한 가능)

ON (데이터베이스명).* 은 권한 대상 데이터베이스의 테이블을 설정합니다. .* 를 통해 모든 테이블을 의미합니다.

TO (사용자)@localhost 는 사용 권한을 받는 사용자를 지정합니다. 없는 유저라면 새롭게 생성하며 localhost는 말 그대로 로컬에서만 연결 가능함을 뜻합니다.

(localhost가 아닌 외부에서 접근하려고 한다면 접근권한을 따로 설정해 주어야 합니다.)

INDENTIFIED BY ‘(비밀번호)’ 는 사용자의 비밀번호를 설정합니다.

 

SHOW DATABASES;

데이터베이스들의 목록을 보여주는 명령어

 

USE (데이터베이스명)

(데이터베이스명)이라는 이름의 데이터베이스를 사용

 

DROP DATABASE (데이터베이스명);

(데이터베이스명)이라는 이름의 데이터베이스를 제거합니다.


CREATE TABLE (테이블명)(

_id INT PRIMARY KEY AUTO_INCREMENT,

name VARCHAR(32) NOT NULL,

job VARCHAR(64) DEFAULT ‘student’,

phone VARCHAR(12)

) ENGINE=INNODB;

(테이블명)이라는 이름을 가진 테이블을 생성합니다.

( ) 내부에 속성을 입력합니다. 각각에 대한 설명은 아래와 같습니다.

_id 란 이름의 칼럼을 추가하며, 데이터 타입은 INT 입니다. 해당 칼럼을 PRIMARY KEY(기본 키)로 설정합니다. AUTO_INCREMENT를 통해 자동으로 인덱스를 증가시킵니다.

name 이란 이름의 칼럼을 추가하며, NULL을 허락하지 않으므로 자료를 입력할 때 항상 값을 넣어줘야 합니다.

job 이란 이름의 칼럼을 추가하며, DEFAULT(아무런 값을 입력하지 않았을 때의 값) ‘student’로 설정합니다.

phone 이란 이름의 칼럼을 추가합니다.

ENGINE = INNODBMySQL의 저장구조를 설정합니다.(생략가능)

 

DESCRIBE (테이블명);

(테이블명)이라는 이라는 테이블의 구조를 확인합니다. 줄여서 DESC (테이블명); 또한 가능합니다.

 

-      참고

Field = 열 이름

Type = 해당 열의 자료형 ex) int(11) '11자리의 정수값을 저장할 수 있는 자료형'

Null = NULL 값을 허용할 것인지 아닌지를 나타내는 제약사항으로 YES로 지정하면 NULL 값을 허용

Key = 해당 열이 ''로 지정되어 있는지 나타냄.

Default = 그 열에 주어진 '기본값' , 생략했을 경우 적용되는 값

자료형

INTEGER = 정수값을 저장할 수 있는 자료형

CHAR = 문자열을 저장할 수 있는 자료형. 열의 최대 길이를 지정해야 함 => 고정 길이 문자열

VARCHAR = 문자열을 저장할 수 있는 자료형.데이터크기에 맞춰 저장공간의 크기도 변경됨 =>가변 길이 문자열

DATE = 날짜값을 저장할 수 있는 자료형. 연월일

TIME = 시간을 저장할 수 있는 자료형. 시분초

 

SHOW TABLES;

데이터베이스 안의 사용 가능한 테이블 목록을 보여주는 명령어

 

INSERT INTO (테이블명) (칼럼1, 칼럼2, … ) VALUES (칼럼1의 값, 칼럼2의 값, … );

(테이블명)이라는 테이블의 (칼럼1, 칼럼2, … ) 맞춰서 (칼럼1의 값, 칼럼2의 값, … )을 넣습니다.


SELECT (칼럼1, 칼럼2, … ) FROM (테이블명);

(테이블명) 이라는 테이블에서 (칼럼1, 칼럼2, … )의 값을 읽어옵니다.

 

SELECT * FROM (테이블명);

(테이블명) 이라는 테이블에서 (*: 모든)데이터를 읽어오는 명령어

 

-      참고

숫자로 구성된 데이터      =  수치형 데이터(오른쪽 정렬)

문자로 구성된 데이터      =  문자열형 데이터(왼쪽 정렬)

날짜와 시각을 나타내는 데이터 =  날짜시간형 데이터(왼쪽 정렬)

열은 하나의 자료형만 가질 수 있고, 수치형의 열에 문자형의 데이터를 저장할 수는 없다.

값이 없는 데이터 = NULL

 

SELECT * FROM (테이블명) ORDER BY (칼럼 명);

(테이블명) 이라는 테이블에서 (*: 모든)데이터를 읽어오는데, (칼럼 명)을 기준으로 정렬하여 읽어옵니다.

 

SELECT * FROM (테이블명) WHERE (조건);

(테이블명) 이라는 테이블에서 (*: 모든)데이터를 읽어오는데, (조건)을 만족하는 행을 읽어옵니다.

 

SELECT * FROM (테이블명) WHERE (칼럼 명) LIKE ‘2017%’;

(테이블명) 이라는 테이블에서 (*: 모든)데이터를 읽어오는데, (칼럼 명)에서 값이 2017로 시작하는 모든 값을 읽어옵니다.

 

SELECT * FROM (테이블명) WHERE (칼럼 1) <> (칼럼 2);

(테이블명) 이라는 테이블에서 (*: 모든)데이터를 읽어오는데, (칼럼 1) (칼럼 2)가 같지 않은 행만 읽어옵니다.

( <>!= 와 같은 의미 입니다.)

 

ALTER TABLE (테이블명) ~ ;

(테이블명)이라는 이름의 테이블을 대상으로 테이블의 이름을 변경(RENAME)하거나 테이블에 칼럼(속성)을 추가(ADD)하거나 테이블의 칼럼(속성)을 변경(CHANGE, MODIFY)하거나 테이블의 칼럼(속성)을 제거(DROP)하는 명령을 내릴 수 있습니다.

 

ALTER TABLE (테이블명) RENAME TO (바꿀 이름);

(테이블명)이라는 테이블의 이름을 (바꿀 이름)이라는 이름으로 바꿉니다.

 

ALTER TABLE (테이블명)

ADD COLUMN (새로운 속성) INT NOT NULL AFTER (기존의 속성_1),

ADD PRIMARY KEY (기존의 속성_2);

(테이블명)이라는 테이블에 (새로운 속성)이라는 이름의 속성을 (기존의 속성_1)의 뒤에 추가합니다.

이때 (새로운 속성) INT형 자료를 가지며 NULL을 허용하지 않습니다.(NOT NULL)

또한 (기존의 속성_2)PRIMARY KEY(기본 키)로 변경합니다.

 

ALTER TABLE (테이블명)

MODIFY COLUMN (속성 이름) (변경할 타입);

(테이블명)이라는 테이블의 (속성 이름)이라는 속성의 타입을 (변경할 타입)으로 바꿉니다.

 

ALER TABLE (테이블명)

CHANGE COLUMN (속성 이름) (변경할 속성 이름) (변경할 타입);

(테이블명)이라는 테이블의 (속성 이름)이라는 속성의 이름을 (변경할 속성 이름)으로 바꾸고 타입을 (변경할 타입)으로 바꿉니다.

 

ALTER TABLE (테이블명)

DROP COLUMN (속성 이름),

DROP PRIMARY KEY;

(테이블명)이라는 테이블에서 (속성 이름)이라는 이름의 속성을 제거합니다.

또한 PRIMARY KEY(기본 키)를 제거합니다.


UPDATE (테이블명)

SET (속성 이름) = (바꿀 값)

WHERE (조건: ex. Age > 20);

(테이블명)이라는 테이블에서 WHERE 구문의 조건에 맞는 레코드의 (속성 이름) 값을 (바꿀 값)으로 변경합니다.

- 참고

좌측의 테이블이 있다고 했을 때, 현재 adult 속성의 값을 보면 제대로 맞지 않습니다.

이를 수정하기 위해서 UPDATE 구문을 사용하겠습니다.

 

사용된 명령어는 아래와 같습니다.

UPDATE updateTest

SET adult = ‘Yes’ WHERE age > 19;

 

UPDATE updateTest

SET adult = ‘No’ WHERE age <= 19;

 

결과는 아래 사진과 같습니다.

 


DELETE FROM (테이블명) WHERE _id = 3;

(테이블명)이라는 이름의 테이블에서 _id = 3인 데이터를 삭제합니다.

WHERE 구문을 입력하지 않으면 테이블의 모든 데이터가 제거됩니다.

 

DROP TABLE (테이블명);

(테이블명)이라는 이름의 TABLE을 제거합니다. (DELETE는 데이터만 제거하는 것이고 DROP는 테이블 자체를 제거하는 것)

 

TRUNCATE TABLE (테이블명);

(테이블명)이라는 이름의 테이블의 모든 데이터를 삭제합니다.

 

           - 참고

           DELETE 명령은 데이터를 순차적으로 삭제합니다.

           TRUNCATE 명령은 테이블 자체를 삭제하고 같은 이름의 테이블을 새로 생성합니다.

           (테이블을 DROPCREATE 하는 명령어입니다.)

           따라서, 모든 데이터를 삭제할 때 DELETE 명령보다 TRUNCATE 명령이 처리속도가 빠르지만

TRUNCATE 명령은 데이터의 복구가 불가능합니다.


내용에 대한 피드백 및 궁금한 점은 댓글 및 이메일(doorbw@outlook.com) 으로 말씀해주세요 :)

다음 포스팅에서는 '조건에 따른 데이터 검색'에 대한 명령어를 알아보겠습니다.

블로그 이미지

Tigercow.Door

Back-end / Python / Database / AI / Algorithm / DeepLearning / etc

댓글을 달아 주세요