맥북으로 Xcode를 쓰다가 문득 이런 생각이 들었다.


'비쥬얼 스튜디오는 왜 cpp파일을 만들 때 템플릿이 없을까?'


물론 처음부터 코딩하는게 더 편할 때도 있지만,

알고리즘 문제를 풀 때나 일반적인 프로젝트를 진행할 때는 기본 틀이 있는게 작업하기가 훨씬 편하다.



예를 들어, Xcode에서 지원하는 기본 템플릿은 이렇게 생겼다.




VS2017에서도 템플릿을 만들면, cpp파일을 만들 때 자동적으로 코드를 넣어줄 수가 있다.


처음에 개념을 찾다가 Item Template라는 것을 발견했는데, VS2017엔 그런게 없어서 한참 헤매다가 발견했다.. '항목 템플릿'이라고 번역해뒀더라..



Visual Studio 2017을 실행하고, 빈 프로젝트를 만들어주자

소스 파일에 main.cpp 파일을 하나 생성하고, 다음과 같은 코드를 작성해 놓는다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//
// main.cpp
// project
//
// Created by (name) on 20xx. x. x..
// Copyright ⓒ 20xx년 (nickname). All rights reserved.
//
 
#include <iostream>
 
int main(int argc, const char * argv[]){
    //insert code here...
    std::cout << "Hello World!\n";
    return 0;
}
cs

* 필요한 부분은 바꿔서 작성하면 되겠다.



저장하고 프로젝트 탭에서 템플릿 내보내기 클릭.

항목 템플릿을 선택한다.




소스 파일 밑에 있는 main.cpp 파일만 선택한다.




여기서 주의할 점은, 템플릿 이름이 파일 이름으로 설정된다는 것이다.

main으로 설정하면 이 템플릿을 선택했을 때 main.cpp 파일이 만들어진다.


또한 출력 위치를 잘 기억해두자. 템플릿을 삭제하고 싶으면 저 위치에 있는 zip파일을 삭제하면 된다.




VS2017을 재시작하고, 프로젝트를 만들어서 소스 파일을 추가해보자. 




다음과 같이 main 템플릿이 뜨면 성공!



※ 날짜와 프로젝트 이름까지 자동적으로 적용시킬 수 있는 방법이 있을지 모르겠다.. 한번 연구해 봐야겠다.

'코딩을 배우자 > C++로' 카테고리의 다른 글

Visual Studio 2017 프로젝트 템플릿 만들기  (1) 2018.07.11

코딩을 열심히 하고 ctrl +F5를 눌러서 결과를 확인하려고 했으나, 콘솔창이 바로 꺼져서 당황했던 적이 있었다.


해결방법은

1. 코드 마지막 부분에 system("pause")를 추가하거나 

2. 프로젝트 속성에서 링커->시스템->하위 시스템을 콘솔(/SUBSYSTEM:CONSOLE)로 바꿔주는 두 가지가 있는데


1번 해결책은 불필요한 코드가 프로젝트에 들어가 있어서 찜찜하다는 단점이 있었고

2번 해결책은 프로젝트를 새로 생성할 때마다 설정해줘야된다는 불편함이 있었다.


따라서 좀 더 깔끔한 방법이 없을까 하다가.. 프로젝트 템플릿이라는 개념을 발견했다.


프로젝트 템플릿


사용자가 원하는 프로젝트 설정을 저장해 새로운 프로젝트를 만들 때 바로 적용시켜 사용할 수 있도록 하는 것


이 포스팅에서는 프로젝트 템플릿을 이용해 새 프로젝트를 디버깅 했을 때 '계속하려면 아무 키나 누르십시오.' 문구가 나오도록 할 것이다.



빈 프로젝트를 하나 생성하고, 프로젝트 설정으로 들어가서 링커>시스템>하위 시스템을 콘솔(/SUBSYSTEM:CONSOLE) 로 바꿔주자


 


프로젝트 탭에서 템플릿 내보내기 선택




템플릿 이름은 편한대로 영어로 지어주고, 출력 위치를 잘 기억해두자.





마침을 누르고 Visual Studio 2017을 재실행해서 새 프로젝트 버튼을 누르면 다음과 같이 템플릿이 추가된 것을 확인할 수 있다.

※ 마침을 누르면 폴더창이 뜨면서 압축파일이 생성된 것을 확인할 수 있는데, 이 압축파일을 삭제하면 템플릿을 삭제할 수 있다. (위의 출력 위치에 생성)




디버그를 했을 때 '계속하려면 아무 키나 누르십시오...'가 성공적으로 뜨면 완료!




다음 포스팅에서는 항목 템플릿(Item Template)에 대해 알아보도록 하겠다.



'코딩을 배우자 > C++로' 카테고리의 다른 글

Visual Studio 2017 아이템 템플릿 만들기  (0) 2018.07.11

자 이번 포스팅에서는 장애물들을 설정하고 마무리하도록 하겠습니다.


장애물을 배치하는 것은 간단합니다.

하이라키 탭에서  3D Object > Cube  이름을 Obstacle로 설정해 주시고, 프로젝트 탭에서  Create > C# Script  선택, 이름을 역시 Obstacle로 설정하겠습니다.

Obstacle에 들어갈 스크립트는 아래와 같습니다.


1
2
3
4
5
6
7
8
9
10
11
public class Obstacle : MonoBehaviour {
    private int hp = 1;
 
    void OnDamage(int damage){
        hp = hp - damage;
        if (hp <= 0) {
            Destroy (gameObject);
            return;
        }
    }
}
tistory.hanorange.com
cs


Obstacle 오브젝트는 1 만큼의 hp를 가지고 있으며 피격시 OnDamage함수가 실행되어 damage만큼 hp가 깎이게 됩니다.

hp가 0이하가 되면 큐브가 없어지게 되죠.


OnDamage 함수는 저번시간에 작성했던 Bullet 오브젝트의 컴포넌트인 Fire.cs 스크립트에 있습니다. 잠깐 가져와 볼까요?


1
2
3
if(Physics.Raycast(레이캐스트 설정)){
    hit.collider.SendMessage("OnDamage"1, 메세지 옵션);
}
tistory.hanorange.com
cs

Raycast로 광선을 쏘았을 때 맞는 오브젝트가 있다면 그 오브젝트가 hit되었을 때 OnDamage함수를 발동시키라는 내용입니다. 데미지는 명시된 1 만큼 전달됩니다.

이제 Obstacle에 스크립트와 물리적 요소를 추가하기 위한 Rigidbody를 넣어주시고, Obstacle의 크기를 2, 2, 2로 키워주겠습니다.


Obstacle 을 배치할 시간입니다. 하지만 배치하기에는 땅이 너무 좁네요. 

Plane의 크기를 4, 4, 4로 늘려줍시다.

이제 하이라키 탭에서 Obstacle 을 Plane의 자식으로 넣어서, 맵과 함께 움직이도록 설정하겠습니다.

그 뒤에 Obstacle을 선택한 뒤 Ctrl+c, Ctrl+v 로 복붙해서 맵에 10개 정도만 만들어주겠습니다. ( Ctrl+d 를 누르면 더 빨라요! )



잘 따라오셨나요? 


자, 실행해 봅시다!



정상적으로 잘 플레이되네요.

여기까지 잘 따라오셨으면 게임은 완성입니다! 수고하셨습니다. 👏👏👏

오류가 나거나, 이해가 안되는 부분은 댓글 달아주시면 답해드리도록 하겠습니다!



※ 다음 포스팅에서는 외전으로 어떻게 두명이서 플레이할 수 있는지에 대해 알아보도록 하겠습니다.

계속 개발해 보겠습니다. 

먼저 지금까지 한 Scene을 저장하겠습니다. 하이라키 탭에서  Ctrl + s  를 눌러서 Main이라고 저장해줍니다.


슈팅게임이기 때문에 플레이어가 총을 들고있어야 하겠죠? 하이라키에서  3D Object > Cube  를 두개 만들어서 모형을 적당히 잡아줍시다.

큰 큐브는 Gun으로 손잡이는 Handle로 Gun안에 자식으로 넣어줍니다. 만들어진 Gun은 또한 Player의 자식으로 넣어줍니다.

Material 도 생성해서 색깔을 입혀주시면 Gun 모양까지 완성입니다.



이제 총알과 총알을 발사하는 C# 스크립트를 제작해보겠습니다.

총알은  3D Object > Sphere  의 크기를 0.2 정도로 한 작은 구로 만들어 주시구, 이름은 Bullet 입니다. 앞과 마찬가지로 Material을 만들어서 총알에 색깔을 입혀줍니다. Bullet Color정도로 이름을 설정해주면 되겠네요.


저는 총알이 빛나게 해주고 싶기 때문에  Bullet에서  Add Component > Light  를 넣어주었습니다. 선택 사항이에요!


이제 Project에서  Create > C# Script  로 스크립트를 만들어 줍시다. 이름은 Fire로 설정해주세요.

코드는 다음과 같습니다


public class Fire : MonoBehaviour {
    public float speed = 8f;
    private RaycastHit hit;
    
    // Update is called once per frame
    void Update () {
        if(Physics.Raycast(transform.position, transform.forward, out hit, speed * Time.deltaTime){
 
            hit.collider.SendMessage("OnDamage"1, SendMessageOptions.DontRequireReceiver);
 
            Destroy(gameObject);
            return;
        }
            transform.Translate(00, speed * Time.deltaTime);
    }
}
 
tistory.hanorange.com
cs


speed 는 총알이 날아가는 속도입니다. public으로 선언해주었기 때문에 inspector창에서 직접 수정이 가능하죠.


눈여겨볼 코드는 RaycastHit 메소드입니다. 

만약 오브젝트에 Collider를 붙여서 CompareTag 메소드를 사용하게 되면, 총알처럼 빠른 오브젝트는 프레임과 프레임 사이를 순식간에 지나가게 되어 업데이트 적용을 받지 못해 물체의 충돌을 감지하지 못하는 경우가 발생할 수 있습니다.


그러나 RaycastHit를 사용하게되면 보이지 않는 빔이 속성값으로 넣어준 방향으로 '한 프레임' 정도를 먼저 쬐면서 지나가게 됩니다. 이 빔에 맞는 오브젝트의 정보를 반환할 수도 있죠. 

즉, Update문에 있는 Physics.Raycast(transform.position, transform.forward, out hit, speed * Time.deltaTime

코드는 시작점과 방향, 빔과 속도를 지정해준 것입니다.


hit.collider.SendMessage("OnDamage"1, SendMessageOptions.DontRequireReceiver);

이 코드에서는 총알을 맞은 오브젝트에게 "OnDamage" 함수를 실행하라고 알려줍니다. 1 만큼 데미지를 주고, DontRequireReceiver 메소드는 "OnDamage" 함수가 없는 객체는 수행할 필요가 없다는 뜻입니다. 


작성이 완료되었으면 Bullet의 inspector에 Fire 스크립트를 붙여줍시다.

이제 총알은 게임이 시작되면 클릭할때마다 생성되어 발사될것이기 때문에 Project탭으로 드래그해서 프리팹으로 만들어 주시고, 하이라키에서는 지워줍니다.



총알을 발사할 스크립트를 만들 차례입니다.

하이라키 탭에서  Create > Create Empty  를 선택해서 Fire Position이라고 이름을 바꿔 주시구, 위치를 다음과 같이 총구 앞으로 배치해줍시다.

총알이 발사될 위치를 잡아주는 과정입니다.



Project 탭에서  Create > C# Script , 이름은 Gun으로 설정해줍니다.


public class Gun : MonoBehaviour {
    public GameObject bulletPrefab;
    public Transform firePosition;
 
    public float timeBetFire = 0.6f;
    private float lastFireTime = 0;
 
    // Update is called once per frame
    void Update () {
        if (Input.GetButton("Fire1")){
            if(Time.time >= lastFireTime + timeBetFire) {
                Fire ();
            }
        }    
    }
 
    void Fire(){
        lastFireTime = Time.time;
        Instantiate (bulletPrefab, firePosition.position, firePosition.rotation);
    }
}
 
tistory.hanorange.com

cs


먼저 프리팹으로 만든 Bullet과 총알이 발사될 위치인 firePosition을 가져와줍니다.


발사 간격도 설정해 주어야겠죠? timeBetFire 에서 설정한 쿨타임은 0.6초입니다.

lastFireTime 은 총알이 발사되었을 때 Time.time 으로 현재 시간을 저장하기 때문에, 업데이트문에서 버튼을 눌렀을 때 현재 시간이 마지막에 발사된 시간과 쿨타임을 합친 시간보다 크다면 총알이 발사되는 원리입니다.


Instantiate 메소드는 프리팹을 firePosition의 위치와 각도로 복사해 가져온다는 내용의 코드입니다.

이제 Gun의 inspector에서 Gun 스크립트를 붙여주시고, BulletPrefab과 Fire Position에 맞는 오브젝트를 넣어줍시다.



이제 카메라 뷰를 적당히 설정해주고, 구동해 봅시다!



총알까지 잘 발사가 되네요. 완성이 머지않았습니다.

저번 포스팅에 이어서, 3주차때 진행한 내용을 포스팅하겠습니다.


이번에 제작한 것은 위에서 아래로 내려다보는 탑다운 뷰 게임입니다. 로컬에서 2명이 동시에 플레이할 수 있죠.

플레이어는 맵의 끝과 끝에서 시작되고, 중간의 장애물들을 파괴하면서 서로를 잡아야 합니다.


먼저 유니티 프로젝트를 3D로 시작해 줍니다.


기본 배치로 하이라키 탭에서  3D Object > Plane  으로 땅을 깔아 줍시다.


그 후에  3D Object > Capsule  로 주인공의 몸체를 만듭니다.

또한 주인공의 앞뒤를 구분하기 위해 간단하게 선글라스를 씌워 주겠습니다. 

주인공 캡슐의 이름을 Player로 바꿔주시고, Player를 우클릭,  3D Object > Cube  로 자식 오브젝트로 넣어주겠습니다.

이제 적당히 크기와 위치를 조정해 주시면 이런 구성이 될겁니다.



색깔이 없으니 허전하네요. Project 빈 공간에서 우클릭,  Create > Material  을 두 개 추가해서 바닥과 선글라스의 색깔을 넣어주겠습니다.

각각 Plane Color, Glass Color라고 설정해 주시고 속성(inspector)탭에서 Albedo 값으로 색을 지정하겠습니다.

색깔 설정이 완료된 Material을 오브젝트로 드래그 앤 드롭해주면 색깔 설정까지 완료됩니다.



이제는 플레이어가 물리적인 힘을 받을 수 있도록 Rigidbody 컴포넌트를 추가해야겠네요. 

Player에서  Add Component > Rigidbody  추가.


또한 플레이어가 보고있는 방향을 기준으로 앞뒤로만 움직이게 할 것이고, 움직임을 직접 값으로 넘겨줄 것이기 때문에 

 Player의  Rigidbody > Constraints > Freeze Rotation  에서 x, y, z값 모두 체크해 주겠습니다.


이제 플레이어가 움직일 수 있도록 스크립트를 추가해 줍니다. 

Project 탭에서 우클릭  Create > C# Script  선택해서 이름을 PlayerController 라고 지정합시다.

코드는 다음과 같습니다.


public class PlayerController : MonoBehaviour {


    public Rigidbody myRigidbody;

    public float rotationSpeed = 180f;
    public float moveSpeed = 12f;
    

    void Start () {

    }


    void Update () {
        float inputRotation = Input.GetAxis ("Horizontal");
        float inputSpeed = Input.GetAxis ("Vertical");

        transform.Rotate (0, rotationSpeed * inputRotation * Time.deltaTime, 0);

        Vector3 moveDistance = transform.forward * moveSpeed * inputSpeed * Time.deltaTime;

        myRigidbody.MovePosition (myRigidbody.position + moveDistance);

    }
}


여기서 핵심적인 부분은, rotationSpeed 라는 회전 속도와 moveSpeed 라는 움직이는 속도를 플레이어에게 어떻게 적용시키느냐입니다.

Update() 문 안의 코드들은 1초에 대략 30번~ 60번 실행됩니다. 이것을 흔히 게임에서 '프레임'이라고 하죠.

플레이어가 원하는대로 부드럽게 움직이려면 이 프레임 단위로 수행되는 단위가 극히 짧아야 합니다.

예를 들어서, moveSpeed가 12f라는 뜻은 1초에 12f만큼 가겠다는 뜻입니다. 그러나 만약


Vector3 moveDistance = transform.forward * moveSpeed * inputSpeed;


이런 식으로 코드를 작성하게 되면 1프레임마다 12f씩 튕겨나가는 주인공을 보시게 될겁니다.

그것을 방지하기 위해서  Time.deltaTime 이라는 녀석을 곱해주는 것이죠.  

즉, 이 녀석을 곱함으로써 프레임이 다른 환경에서도 원하는 움직임을 똑같이 맞춰주는 것이다! 라고 생각하시면 되겠네요. 자세한 설명은 지금은 넘어가도록 하겠습니다.


transform.Rotate (0, rotationSpeed * inputRotation * Time.deltaTime, 0);


이 회전속도를 제어하는 코드도 역시 마찬가지입니다.

모든 3D 오브젝트는 x, y, z의 축을 가지고 있는데 저희가 만들 게임은 y축으로만 회전할것이기 때문에 x와 z값에는 0이 들어갑니다.


아참, inputRotation 과 inputSpeed 는 각각 "Horizontal" 과 "Vertical" 로 설정되어 있는데,

이것은 십자 방향키를 입력했을 때 "좌우" 와 "위아래"를 뜻합니다. 


이 스크립트를 저장한 뒤에, Player의 inspector 탭에서  Add Component > PlayerController  를 검색해 넣어줍시다.

아래와 같이 스크립트에서 myRigidbody 에 Rigidbody 컴포넌트를 붙여주면 실행 완료입니다.




노트북 사양이 딸려서 약간 끊기네요.


자 그럼 오늘은 여기까지입니다. 

데이터베이스 설계

  • 개념적 데이터베이스 설계 : 정보 사용의 모델을 개발하는 과정으로 실세계를 바탕으로 추상화 모델을 구축한다.
    • 엔티티-관계 (ER: Entity-Relationship)모델이 주로 사용된다.
  • 물리적 데이터베이스 설계 : 물리적인 저장 장치와 접근 방식을 다룸
  • 엔티티 : 서로 구분이 되며 조직체에서 DB에 나타내려는 객체를 의미
  • 관계 : 두 개 이상의 엔티티들 간의 연관
  • 프로세스 : 관련된 활동
  • 무결성 제약조건 : 데이터의 정확성과 비즈니스 규칙을 의미
데이터베이스 설계의 개요
한 조직체의 운영과 목적을 지원하기 위해 DB를 생성하는 과정이다. 
목적은 모둔 주요 응용과 사용자들이 요구하는 데이터, 관계를 표현하는 것

데이터베이스 설계의 주요단계
- 요구사항 분석, 개념적 설계, DBMS의 선정, 논리적 설계, 물리적 설계, 트랜잭션 설계
  • 요구사항 수집 및 분석 : 기존의 문서 조사, 인터뷰나 설문 → 엔티티, 애트리뷰트, 관계 파악
    • 데이터 처리에 관한 요구사항 → 연산의 종류, 데이터의 양 분석
  • 개념적 설계 : 조직체에서 사용되는 정보의 모델을 구축
    • 사용자의 요구사항 명세로부터 개념적 스키마가 만들어짐
    • ER모델과 같은 높은 추상화 수준의 데이터 모델을 기반으로 구조 명시
    • 엔티티 타입, 애트리뷰트 도메인, 키 애트리뷰트를 결정
  • DBMS 선정 : 기술적, 정치적, 경제적 요인을 검토하여 선정
  • 논리적 설계 : 개념적 스키마에 알고리즘을 적용해 논리적 스키마를 생성, 스키마로 사상하는 과정
  • 물리적 설계 : 응답 시간, 트랜잭션 처리율 등의 성능 기준으로 요구사항을 만족시키는 구조를 결정
  • 트랜잭션 설계 : 완성될 DB에서 동작할 응용 프로그램에 대한 설계를 진행
ER 모델 : 개념적 설계를 위한 모델, 실세계를 엔티티, 애트리뷰트, 관계로 표현함
- 관계 데이터 모델로 사상하기 용이하며 엔티티, 관계, 애트리뷰트 및 카디날리티, 제약조건 등의 구문이 있다.

엔티티
  • 실세계에 독립적으로 존재하며 고유하게 식별이 가능한 객체
  • 생각이나 개념과 같이 추상적인 것도 있다.
  • 엔티티 타입은 동일한 애트리뷰트들을 가진 엔티티들의 틀
  • 엔티티 집합은 동일한 애트리뷰트들을 가진 엔티티들의 모임
  • 엔티티 타입은 내포, 엔티티 집합은 외연에 해당된다.
  • ER 다이어그램에서 직사각형으로 나타냄
  • 강한 엔티티 타입 ; 자신의 키 애트리뷰트를 사용하여 고유하게 엔티티들을 식별할 수 있는 엔티티 타입
  • 약한 엔티티 타입 : 키를 형성하기에 충분한 애트리뷰트들을 갖지 못한 엔티티 타입. 소유 엔티티 타입이 필요하다.
애트리뷰트
  • 하나의 엔티티는 연관 애트리뷰트들의 집합으로 설명된다.
    • 사원 엔티티는 사원번호, 이름, 직책, 급여 등의 애트리뷰트를 갖는다.
  • 애트리뷰트의 도메인은 그 애트리뷰트가 가질 수 있는 모든 값들의 집합으로, 여러 애트리뷰트가 동일한 도메인을 공유할 수 있다.
  • 키 애트리뷰트는 한 엔티티 타입 내에서 각 엔티티를 고유하게 식별한다.
  • 요구사항 명세에서 명사나 형용사로 표현된다.
  • ER 다이어그램에서 타원형
  • 단순 애트리뷰트 : 더 이상 다른 애트리뷰트로 나눌 수 없는 애트리뷰트
  • 복합 애트리뷰트 : 두 개 이상의 애트리뷰트로 이루어진 애트리뷰트. 밀접히 연관된 것을 모아놓은 것이다.
  • 단일 값 애트리뷰트 : 각 엔티티마다 정확히 하나의 값을 갖는 애트리뷰트 (대부분)
  • 다치 애트리뷰트 : 각 엔티티마다 여러 개의 값을 가질 수 있는 애트리뷰트. 이중선 타원으로 표현한다.
  • 저장된 애트리뷰트 : 다른 애트리뷰트와 독립적으로 존재하는 애트리뷰트
  • 유도된 애트리뷰트 : 다른 애트리뷰트의 값으로부터 얻어진 애트리뷰트. 점선 타원으로 표현한다. 
관계와 관계 타입 : 엔티티들 사이에 존재하는 연관, 연결로서 다이아몬드로 표현된다.
차수 : 관계로 연결된 엔티티 타입들의 개수. 2진 관계가 가장 흔하다.
카디날리티 : 하나의 엔티티가 참여할 수 있는 관계의 수를 말한다.
  • 1:1 관계, 1:N 관계, M:N 관계
  • 관계 실선 위에 최솟값과 최댓값이 표시된다. * (아스테리카) 표시는 n을 나타낸다.



ER 스키마를 관계 모델의 릴레이션으로 사상
  • 엔티티 타입과 단일 값 애트리뷰트 
    • 단계1_정규 엔티티 : 각 정규 엔티티 타입에 있던 단순 애트리뷰트를 릴레이션에 포함, 복합 애트리뷰트는 단순 애트리뷰트만 포함
    • 단게2_약한 엔티티 : 약한 엔티티 타입에 있던 단순 애트리뷰트를 릴레이션에 포함, 부분 키와 소유 엔티티의 기본 키를 외래키로 포함시켜 기본 키 구성 
  • 2진 관계 타입 
    • 단계3_2진 1:1관계 : 둘 중 하나의 릴레이션에서 기본 키를 나머지 릴레이션의 외래 키로 포함시키거나 다른 릴레이션을 만들어 포함
    • 단계4_2진 1:N관계 : 1측의 릴레이션 기본 키를 N측의 외래 키로 포함시킨다.
    • 단계5_2진 M:N관계 : 릴레이션을 새로 생성해서 M과 N측의 기본 키를 외래 키로 포함시킨다. 외래 키의 조합이 새로운 릴레이션의 기본 키가 된다.
  • 3진 이상 관계 타입
    • 단계6 : 새로운 릴레이션을 생성하고, 각 참여 릴레이션의 기본 키를 새로운 릴레이션의 외래 키로 포함. 이 외래 키의 조합이 기본 키가 된다.
    • 1:N:N의 경우는 1측의 기본 키를 참조하는 외래 키를 제외한 나머지 외래 키들의 조합이 기본 키가 된다.
  • 다치 애트리뷰트
    • 각 다치 애트리뷰트에 대해 새로운 릴레이션을 생성


INSERT문

  • 기존의 릴레이션에 투플을 삽입
  • 참조되는 릴레이션에 삽입되는 경우 문제 없음.
  • 참조하는 릴레이션에 삽입되는 경우 참조 무결성 제약조건 위배가능
  • INSERT  INTO 릴레이션 (애트리뷰트1, ..., 애트리뷰트n)  VALUES (값1, ..., 값n);
  • 릴레이션에 한 번에 여러 개의 투플들을 삽입하는 경우 WHERE절을 이용해 지정해주면 된다.
DELETE문
  • 한 릴레이션으로부터 한 개 이상의 투플들을 삭제
  • 참조되는 릴레이션은 참조 무결정 제약조건 위배가능
  • 참조하는 릴레이션을 삭제하는 경우 문제 없음
  • DELETE  FROM 릴레이션  WHERE 조건;
UPDATE문
  • 한 릴레이션에 들어 있는 투플들의 애트리뷰트 값들을 수정
  • 기본 키나 외래 키에 속하는 애트리뷰트의 값이 수정되면 참조 무결성 제약조건을 위배할 수 있음
  • UPDATE 릴레이션  SET 애트리뷰트 = 값  WHERE 조건;
트리거 : 명시된 이벤트가 발생할 때마다 DBMS가 자동적으로 수행하는, 사용자가 정의하는 문으로 DB의 무결성을 유지하기 위한 일반적이고 강력한 도구이다.
트리거 활성(이벤트) -> 수행되는 조건(컨디션) -> 조건이 참일 때 수행되는 동작 (액션) ☞ 이벤트-조건-동작(ECA)규칙


내포된 SQL (embedded SQL)

  • SQL이 호스트 언어의 완전한 표현력을 갖고 있지 않기 때문에 모든 질의를 표현할 수는 없다.
  • SQL은 조건문과 반복문, 입출력, GUI등의 기능이 미약하다.
  • 따라서 C나 자바를 이용한 프로그램에 SQL문을 삽입하여, DB에 접근하는 부분은 SQL이 맡고 SQL에 없는 기능은 호스트 언어로 작성하는 형태를 내포된 SQL이라고 한다.
  • 데이터 구조의 불일치 문제(impedance mismatch)가 발생할 수 있다.
  • 호스트 변수는 SQL문에 포함된 C프로그램의 변수이다. 둘 사이의 통신을 위해 사용 (EXEC SQL ~)
    • 정적인 SQL문 : C프로그램에 내포된 오나전한 SQL문
    • 동적인 SQL문 : 불완전한 SQL문으로서 일부 또는 전부를 질의가 수행될 때 입력할 수 있다.
  • 커서 : 호스트 언어와 SQL문 사이의 불일치 문제를 해결하기 위해 사용된다. 한 번에 한 투플씩 가져오는 수단이다.
WHENEVER절 : 자동적인 에러 검사와 에러 처리를 위한 구문
- WHENEVER <조건> <동작> 형식으로 사용된다.

SQL 통신 영역 (SQLCA) : C프로그램에 내포된 SQL문에 발생하는 에러들을 사용자에게 알려준다.
오라클 통신 영역 (ORACA) : SQLCA 표준을 오라클에서 확장한 구조체




SQL : 현재 관계 DBMS 시장에서 널리 사용되는 ANSI (미국 표준 기구) 표준 언어

  • 비절차적 언어이므로 원하는 바만 명시, 처리하는 방법은 명시하지 않음
  • 대화식 SQL과 내포된 SQL이 있다.
  • 관계 DBMS는 사용자가 입력한 SQL문을 번역, 요구한 데이터를 찾는데 모든 과정을 담당한다.

데이터 정의어

  • 스키마의 생성 : CREATE (DOMAIN, TABLE, VIEW...)
    • CREATE SCHEMA MY_DB
  • 스키마의 제거 : DROP (DOMAIN, TABLE, VIEW...)
    • DROP SCHEMA MY_DB
  • 릴레이션의 정의에 사용되는 오라클 데이터 타입
    • INT, NUMBER(n, s) : 정수와 소수점
    • CHAR(n), VARCHAR(n) : 문자열과 가변 문자열
  • 제약조건
    • NOT NULL, UNIQUE, CHECK ...
  • 참조 무결성 제약조건
    • ON DELETE NO ACTION
    • ON DELETE CASCADE : 기본 키 삭제시 외래 키도 삭제된다.
    • ON DELETE SET NULL : 참조되는 값 삭제시 참조하는 값을 NULL로 바꾼다.
    • ON DELETE SET DEFAULT : NULL이 아닌 DEFAULT값으로 바꾼다.
    • ON UPDATE NO ACTION

SELECT절
  • 관계 DB에서 정보를 검색하는 SQL문
    • 관계 대수의 실렉션, 프로젝션, 조인, 카티션 곱 등을 결합한 것으로 가장 자주 사용된다.
    • SELECT절과 FROM절은 필수적, 나머지는 선택 사항
    SELECT         [DISTINCT] 애트리뷰트(들)
    FROM          릴레이션(들)
    [WHERE        조건
           [중첩 질의]]
    [GROUP BY   애트리뷰트(들)]
    [HAVING      조건]
    [ORDER BY   애트리뷰트(들) [ASC|DESC]];

    • * (아스테리카)를 사용하면 전체에 대해 검색할 수 있다.
    • 보통은 애트리뷰트를 열거해 검색
    • DISTINCT를 사용하면 중복을 제거해 준다.
    • 산술 연산자를 이용할 수 있다.


    WHERE절 : 검색 조건을 명시

    • % (퍼센트 기호)를 이용해 문자열을 비교할 수 있다. 
      • WHERE EMPNAME LIKE '이%'   ☞  '이씨 성을 가진'
    • 부울 연산자 (AND, OR, <>(NOT))를 이용해 조건을 제시할 수 있다.
    • 범위 연산자도 가능
    • 리스트를 사용한 검색이 가능하다.
      • WHERE DNO IN (1, 3)  ☞  '1번 부서나 3번 부서에 소속된'
    • NULL값과의 직접적인 비교는 불가능하다. 
      • IS NULL, IS NOT NULL 등으로 사용가능

    ORDER BY절 :  오름차순(ASC)과 내림차순(DESC)으로 정렬할 때 사용한다. 
    - SELECT절에 명시한 애트리뷰트들을 사용해서 정렬해야 한다.

    AS문 : 서로 다른 릴레이션에 동일한 이름을 가진 애트리뷰트가 있을 때 구분하기 위한 방법
    - EMPLOYEE AS E, DEPARTMENT AS D

    집단 함수
    • DB에서 검색된 여러 투플들의 집단에 적용되는 함수
    • 한 개의 애트리뷰트에 적용되어 단일 값을 반환한다.
    • SELECT절과 HAVING절에만 나타날 수 있음
    • COUNT(*)는 릴레이션의 모든 행들의 총 개수
    • COUNT(애트리뷰트)는 해당 애트리뷰트에서 널값이 아닌 값들의 갯수
    • SUM, AVG, MAX, MIN ..
    그룹화 : GROUP BY절에 사용된 애트리뷰트에 동일한 값을 갖는 투플들이 묶인다.

    HAVING절 : 각 그룹이 만족해야 하는 조건을 명시
    - HAVING절에 나타나는 애트리뷰트는 반드시 GROUP BY절에 나타나거나 집단 함수에 포함되어야 한다.

    집합 연산 : 두 릴레이션이 합집합 호환성을 가져야 적용할 수 있다.
    - UNION(합집합), EXCEPT(차집합), INTERSECT(교집합)


    조인
    • 두 개 이상의 릴레이션으로부터 연관된 투플들을 결합
    • WHERE절에 애트리뷰트들을 비교하는 조인 조건이 포함
    • 조인 조건이 명확해지도록 애트리뷰트 이름 앞에 변수를 사용하는 것이 좋다.
    자체 조인 : 한 릴레이션에 속하는 투플을 동일한 릴레이션에 속하는 투플들과 조인.
    - 릴레이션에 대한 별칭을 두 개 지정해야 한다.


    중첩 질의
    • 질의의 WHERE 또는 FROM절에 다시 SELECT문이 괄호로 묶여 포함되는 것
    • 부질의(subquery)라고 한다.
    • 결과는 크게 세 종류가 있다.
      • 한 개의 스칼라값
      • 한 개의 애트리뷰트로 이루어진 릴레이션 : 외부 질의의 WHERE절에서 IN, ANY, ALL, EXISTS와 같은 연산자를 사용해야 한다.
        1. IN : 한 애트리뷰트가 값들의 집합에 속하는가
        2. ANY : 한 애트리뷰트가 값들의 집합에 속하는 하나 이상의 값들과 어떤 관계를 갖는가
        3. ALL : 한 애트리뷰트가 값들의 집합에 속하는 모든 값들과 어떤 관계를 갖는가
        4. EXISTS : 중첩 질의의 결과가 빈 릴레이션인지 여부를 검사
      • 여러 애트리뷰트로 이루어진 릴레이션
    • 상관 중첩 질의 : 중첩 질의의 WHERE절에서 외부 질의에 선언된 릴레이션의 일부 애트리뷰트를 참조


    관계 해석 : 원하는 데이터만 명시하고 질의를 어떻게 수행할 것인지는 명시하지 않는 선언적 언어

    관계 대수 : 어떻게 질의를 수행할 것인가를 명시하는 절차적 언어

              -> 상용 관계 DBMS에서 널리 사용되는 SQL의 기초로써 DBMS의 내부 언어로서도 사용된다.


    SQL : 사용자가 관계 DB 릴레이션에 정의, 검색, 갱신, 제약조건 등 여러가지 질의를 수행하기 위한 표준 질의어


    관계 대수의 특징

    • 기존 릴레이션들로부터 새로운 릴레이션을 생성
    • 릴레이션이나 관계 대수식에 연산자를 적용해 복잡한 관계 대수식을 만들 수 있음
    • 기본적인 연산자들의 집합
    • 결과 릴레이션은 또 다른 관계 연산자의 입력으로 사용될 수 있음

    필수적인 관계 연산자 : 실렉션, 프로젝션, 합집합, 차집합, 카티션 곱

    실렉션 연산자 (Selection)
    • δ<조건>릴레이션
    • 단항 연산자로서 릴레이션에서 조건을 만족하는 투플들의 부분 집합을 생성한다.
    • 결과 릴레이션의 차수는 입력 릴레이션의 차수와 같다.
    • 결과 릴레이션의 카디날리티는 항상 기존 릴레이션의 카디날리티보다 작거나 같다.
    • 임의의 애트리뷰트와 상수, 비교 연산자, 부울 연산자를 포함할 수 있다.
    • 중복 투플이 존재할 수 없음
    프로젝션 연산자 (Projection)
    • π<애트리뷰트 리스트>릴레이션
    • 릴레이션에서 애트리뷰트들의 부분 집합을 구한다.
    • 결과 릴레이션은 <애트리뷰트 리스트>에 명시된 애트리뷰트만 갖는다.
    • 중복 투플이 존재할 수 있음
    집합 연산자 : 합집합, 교집합, 차집합이 있으며 입력으로 사용되는 릴레이션은 합집합 호환이어야 한다.

    합집합 연산자 
    • 릴레이션1 ∪ 릴레이션2
    • 중복된 투플들은 제외된다.
    • 결과 릴레이션의 차수는 입력 릴레이션 중 하나의 차수와 같다.
    차집합 연산자
    • 릴레이션1 - 릴레이션2
    • 릴레이션1에는 속하지만 릴레이션2에는 속하지 않는 투플들로 이루어진 릴레이션
    • 결과 릴레이션의 차수는 입력 릴레이션 중 하나의 차수와 같다.
    카티션 곱 연산자 : 릴레이션1 × 릴레이션2 에서 릴레이션 1과 릴레이션2의 투플들의 모든 가능한 조합으로 이루어진 릴레이션이다.


    유도된 연산자 : 교집합, 세타 조인, 동등 조인, 자연 조인, 세미 조인, 디비전

    교집합 연산자
    • 릴레이션1 ∩ 릴레이션2
    • 결과 릴레이션의 차수는 입력 릴레이션 중 하나의 차수와 같다.
    조인 연산자 : 두 개의 릴레이션으로부터 연관된 투플들을 결합하는 연산자

    세타 조인
    • R ⋈<조인조건>S
    • 두 릴레이션 R과 S의 세타 조인의 결과는 두 릴레이션의 차수, 애트리뷰트를 합친 것이다.
    • 조인 조건은 비교 연산자를 이용한다.
    • 세타 조인 결과는 두 릴레이션의 카티션 곱에 조인 조건을 적용한 결과와 같다. 
    동등 조인 : 세타 조인 중에서 비교 연산자가 =인 조인

    자연 조인
    • R ⋈ S
    • 두 릴레이션의 공통된 애트리뷰트에 대해 동등 조인을 수행하고, 결과 릴레이션에 있는 조인 애트리뷰트 중 하나를 제외한 조인
    • 관계 DB에 있어서 대부분의 질의는 실렉션, 프로젝션과 자연 조인으로 표현이 가능하다.
    디비전 연산자
    • R ÷ S
    • 릴레이션 S의 모든 투플 값과 쌍을 이루는 릴레이션 R의 애트리뷰트 값
    • "모든 ~에 대해 ~하는" , "~하지 않는 ~가 없다" 형태의 질의에 사용될 수 있다.

    관계 대수의 한계 : 정렬을 나타낼 수 없고, 데이터베이스를 수정할 수 없으며 중복된 투플을 명시하지 못한다.

    추가된 관계 대수 연산자
    • 집단 함수 : AVG, SUM, MIN, MAX, COUNT
    • 그룹화 : 각 그룹에 대해 집단 함수를 적용
    • 외부 조인 : 상대 릴레이션에서 대응되는 투플을 갖지 못하거나 널값이 들어 있는 투플들을 다루기 위한 조인
    1. 왼쪽 외부 조인 (R ⟕ S) : 왼쪽 릴레이션의 투플을 결과에 모두 포함시키고, 오른쪽 릴레이션에 관련 투플이 없다면 널값으로 채움
    2. 오른쪽 외부 조인 (R ⟖ S) : 오른쪽 릴레이션의 투플을 결과에 모두 포함시키고, 왼쪽 릴레이션에 관련 투플이 없다면 널값으로 채움
    3. 완전 외부 조인 (R ⟗ S) : 양쪽 릴레이션의 투플을 모두 결과에 포함시키고, 양쪽에 관련 투플이 없다면 널값으로 채움 . R ⟗ S = (R ⟕ S) ∪ (R ⟖ S)


    관계 데이터 모델 : 데이터 모델 중 개념이 가장 단순, 가장 널리 사용된다.

    • 모든 데이터를 논리적으로 구성
    • 사용자는 원하는 데이터만 명시, 찾는 방법은 명시하지 않는다
    • 선언적인 질의어를 통한 데이터 접근

    장점 : 집합 테이블을 이용한 간단한 구조의 데이터, 이론이 탄탄하며 응용에 적합하다. 설계와 질의처리도 효율적


    릴레이션(Relation) : 2차원의 테이블

    레코드(Record) : 릴레이션의 각 행

    투플(Tuple) : 레코드의 공식적인 용어

    애트리뷰트(Attribute) : 릴레이션에서 이름을 가진 하나의 열


    도메인(Domain) : 한 애트리뷰트에 나타날 수 있는 값들의 집합

    프로그래밍 언어의 데이터 타입과 비슷한 형태로써 동일한 도메인이 여러 애트리뷰트에서 사용될 수 있다.

    • CREATE DOMAIN EMPNAME CHAR(10)
    • EMPNAME 도메인 : {Jeff, John, Alves, Kim, Osher ...}


    차수(Degree) : 한 릴레이션에 들어있는 애트리뷰트들의 수 (1 이상)

    카디날리티(Cardinality) : 릴레이션의 투플 수 (0 이상)

    널값(Null Value) : '알려지지 않음', '적용할 수 없음'에 사용한다. 0과 공백과는 다르다.



    릴레이션 스키마(Relation Schema) : 릴레이션의 이름, 애트리뷰트들의 집합 -> 내포

    릴레이션을 위한 틀이라고 생각하면 된다.

    •  릴레이션이름(애트리뷰트1, 애트리뷰트2, ... , 애트리뷰트N)

    기본 키 애트리뷰트에 밑줄을 그어 표시한다.


    릴레이션 인스턴스(Relation Instance) : 릴레이션의 어느 시점에 들어 있는 투플들의 집합 -> 외연

    일반적으로 현재의 인스턴스만 저장하고, 시간의 흐름에 따라 계속 변한다.



    관계 데이터베이스 스키마는 하나 이상의 릴레이션 스키마들로 이루어진다.

    • DEPARTMENT (DEPTNO, DEPTNAME, FLOOR)
    • EMPLOYEE (EMPNO, EMPNAME, TITLE, DNO, SALARY)
    관계 데이터베이스 인스턴스는 릴레이션 인스턴스들의 모임으로 이루어진다.

    DEPTNO 

    DEPTNAME 

    FLOOR 

     1

    영업

    기획 

    10 

     3

    개발 


     EMPNO

    EMPNAME 

    TITLE 

    DNO 

    SALARY 

     2106

    김창섭 

    대리 

    2000000 

     3426

    박영권 

    과장 

    2500000 

     3011

    이수민 

    부장 

    3000000 

     1003

    조민희 

    대리 

    2000000 

     3427

    최종철 

    사원 

    1500000 



    릴레이션의 특성

    • 각 릴레이션은 오직 하나의 레코드 타입만 포함한다.
    • 한 애트리뷰트 내의 값들은 모두 같은 유형이며 순서는 중요하지 않다.
    • 동일한 투플이 두 개 이상 존재하지 않으며 순서는 중요하지 않다.


    릴레이션의 키에는 수퍼 키, 후보 키, 기본 키, 대체 키, 외래 키가 있다.

    • 수퍼 키 : 릴레이션 내의 특정 투플을 고유하게 식별하는 하나 이상의 애트리뷰트 집합
    • 후보 키 : 각 투플을 고유하게 식별하는 최소한의 애트리뷰트 집합, 두 개 이상일 경우 복합 키라고 한다.
    • 기본 키 : 릴레이션 후보 키 중에서 설계자 혹은 관리자가 기본 키로 선정, 인위적인 키 애트리뷰트를 추가할 수 있음
    • 대체 키 : 키본 키가 아닌 후보 키
    • 외래 키 : 어떤 릴레이션의 기본 키를 참조하는 애트리뷰트, 관계 DB에서는 관계를 나타낼 때 사용된다.

    데이터 무결성 : 데이터의 정확성, 유효성을 의미한다. 일관된 DB상태를 정의하는 규칙이며 DB가 갱신될 때 DBMS가 자동적으로 조건을 검사한다.
    • 도메인 제약조건 (Domain Constraint)
    각 애트리뷰트 값이 반드시 원자값이어야 하며, 디폴트 값과 CHECK 제약조건을 통해 범위를 지정할 수 있다.
    NOT NULL, CHECK 등이 도메인 제약조건에 해당된다.
    • 키 제약조건 (Key Constraint)
    키 애트리뷰트에 중복된 값이 존재해서는 안된다. UNIQUE 로 설정할 수 있다.


    엔티티 무결성 제약조건 (Entity Integrity Constraint)
    • 기본 키 : 투플들을 식별하기 위해 사용되므로 어떤 애트리뷰트도 널값을 가질 수 없다.
    참조 무결성 제약조건 (Referential Integrity Constraint)
    • 두 릴레이션의 연관된 투플들 사이의 일관성을 유지하는데 사용된다.
    • 외래 키 : 관계 DB에서 릴레이션 사이의 관계들이 다른 릴레이션의 기본 키를 참조하는 것을 기반으로 하기 때문에 중요하다.
    • 릴레이션 R2의 외래 키가 릴레이션 R1의 기본 키를 참조할 때 무결성 제약조건의 성립조건 (하나만 만족해도 성립)
      1. 외래 키 값은 R1의 어떤 투플의 기본 키 값과 같다.
      2. 널 값을 가진다. 단, 외래 키가 자신을 포함하고 있는 릴레이션의 기본 키를 구성하고 있지 않음

    무결성 제약조건 : DBMS가 각각의 갱신 연산에 대해 필요한 조치를 취한다.
    • 삽입
    기본적으로 참조되는 릴레이션에 새로운 투플 삽입시 위배되지 않음
    하지만 참조되는 릴레이션에 투플 삽입시 기본 키 애트리뷰트의 값에 따라 (도메인, 키, 엔티티 무결성) 제약조건 위배될 수 있음
    참조하는 릴레이션에 새로운 투플 삽입시 (도메인, 키, 엔티티 무결성, 참조 무결성) 제약조건 위배될 수 있음
    제약조건을 위배하는 삽입 연산은 DBMS가 거절함으로써 무결성을 유지한다.
    • 삭제
    참조하는 릴레이션에서 투플 삭제시 제약조건 위배하지 않음
    참조되는 릴레이션에서 투플 삭제시 참조 무결성 제약조건 위배할 수도 있음
    이 경우 DBMS가 제공하는 옵션
    1. 제한 : 연산을 거절 
    2. 연쇄 : 참조하는 릴레이션에서도 해당 투플을 함께 삭제
    3. 널값 : 참조하는 릴레이션의 외래 키에 널값을 삽입
    4. 디폴트값 : 3번에서 널값 대신 디폴트값 삽입
    5. 수정 : 수정은 투플을 삭제하고 삽입하는 과정과 마찬가지다. 키의 종류에 따라 제약조건을 살펴봐야 한다.


    + Recent posts