반응형

**mongo db

1.mongo db설치

=>windows용은 msi버전(gui tool compasss를 같이 설치할 수 있는 옵션)을 다운로드 받아서 설치해도 되고 zip버전을 받아서 압축을 풀어도 됩니다.

 

2.mongo db서버 실행

=>mongo db 디렉토리에 가면 bin디렉토리에 있는 mongod라는 명령으로 서버를 실행

cmd > mongod --dbpath데이터베이스파일경로

C:\mongodata

mongod -dbpath C:\mongodata

 

=>처음 실행하는 경우에는 데이터베이스 파일이 저장될 디렉토리를 생성

 

=>명령어를 편리하게 사용할려면 bin디렉토리를 path환경변수에 추가해주면 됩니다.

 

3.mongo db클라에언트 실행(접속하는 것)

1)mongo db를 설치하면 mongo라는 command line기반의 접속 프로그램 제공

mongo db설치 디렉토리 안의 bin이라는 디렉토리에 존재

 

자신의 컴퓨터에서 실행 중인 데이터베이스 접속할 때는 아래 명령

cmd > mongo

 

원격에 있는 컴퓨터의 mongo db 접속

cmd > mongo –-host ip주소 :포트번호

cmd > mongo –-host ip주소 --port포트번호

ip주소 대신에 도메인도 가능

 

 

 

2)gui program을 설치해서 접속

=>가장 많이 사용하는 프로그램은 robomongo

https://studio3t.com/download-thank-you/?OS=win64

참조 사이트 : https://soye0n.tistory.com/149

 

 

4.데이터 저장 단위

database -> collection (table) ->document(- row)->field( -column)

1)데이터베이스 생성 및 사용

use 데이터베이스이름

=>없는 데이터베이스 이름을 사용하면 새로 생성되고 있는 데이터베이스 이름을 사용하면 접속

 

2)컬렉션 생성 및 사용

=>생성 명령 : db.createCollection(“컬렉션 이름”)

=>없는 컬렉션이더라도 db.컬렉션이름.insert()을 하게 되면 자동으로 생성

:

TABLE

이름

점수

 

 

 

 

 

 

5.데이터 저장

1. 데이터 표현

=>하나의 객체: {“속성이름”:데이터, ... }

=>여러 개의 데이터:[데이터 나열] – 값만 나열해도 되고 객체를 나열해도 됩니다.

 

2)데이터 삽입 함수

=>insert

db.컬렉션이름.insert(데이터)

데이터에 배열을 대입하면 배열을 분해해서 하나하나 삽입합니다.

mongo db는 최상위 루트에 배열을 허용하지 않습니다.

[]->이것으로 시작하는 것이 없고 {}것으로 된다.

 

=>데이터 확인 함수

db.컬렉션이름.find()

 

 

=>실습

데이터베이스 사용 명령: > use sample

데이터 삽입 명령 :   > db.users.insert({"name":"kim",score:90})              

> db.users.insert([{"name":"lee",score:80},{"name":"park","score":95}])

데이터 확인:      >db.users.find()

 

=>데이터를 확인해보면 직접 삽입하지 않은 _id라는 필드에 ObjectId라는 데이터가 삽입되어 있는데 이 필드는 직접 입력하지 않으면 mongo db document를 구분하기 위해서 자동으로 삽입하는 값입니다.

mongo db에서 id라는 필드를 만드는 것은 권장하지 않습니다.

 

=>insertOne insertMany함수를 이용해서 데이터를 삽입하는 것도 가능

insertOne은 하나의 데이터를 삽입할 때 사용하고 insertMany는 여러 개의 데이터를 삽입할 때 사용합니다.

 

3)데이터 삽입할 때 옵션

ordered 라는 옵션이 있는데 이 옵션은 데이터를 여러 개 삽압할 때 사용할 수 있는 옵션인데

ordered true로 설정되면 싱글 스레드를 이용해서 데이터를 삽입하는데 이 의미는 데이터를 순서대로 하나씩 삽입하는 것이고 ordered false로 설정하면 멀티 스테드를 이용해서 데이터를 삽입하는데 데이터를 동시에 삽입합니다.

 

차이점은 중간에 오류가 발생했을 때 ordered true이면 오류가 발생한 지점부터 데이터가 삽입되지 않습니다.

false로 설정되면 오류가 발생한 데이터만 삽입되지 않고 나머지 데이터는 삽입이 됩니다.

 

대량의 데이터를 약간의 오류를 무시하고 빠르게 삽입할려면 ordered옵션을 false로 설정합니다.

옵션이 없을 경우 ture

4)ordered옵션의 차이를 알아보기 위한 실습

users의 모든 데이터 삭제 >db.users.drop()

 

동일한 name을 삽입하면 오류를 발생시키기 위해서  name필드를 유일한 인덱스로 설정

users에 유니크 한 인덱스 설정 >db.users.createIndex({name:1},{unique:true})

db.users.insert({"name":"kim",score:90})

db.users.insert([{"name":"lee",score:80},{"name":"kim","score":95},{"name":"park","score":95}],{ordered:true})

db.users.find()

=>결과로 kim lee만 조회됩니다.

kim을 삽입할 때 오류가 발생해서 그 이후 데이터는 삽입되지 않습니다.

 

ordered  true일 경우 오류나면 뒤에는 안 들어간다.

ordered false일 경우 같이 들어가서 들어간다.

관계형 db는 제약조건 위반이면 무조건 안들어간다.

 

 

db.users.insert([{"name":"lee",score:80},{"name":"kim","score":95},{"name":"park","score":95}],{ordered:false})

db.users.find()

=>중간에 오류가 발생하더라도 park이 삽입됩니다.

동시에 삽입했기 때문에 데이터가 삽입될 때 다른 부분에 오류가 발생한 것은 상관하지 않습니다.

 

_id 수정,저장 조회 등 가능하는데 잘 하지 않는다.

 

=>기본적으로 single thread

mongo db

node.js

 

5).mongo db의 옵션에 대한 이행

잘못된 옵션을 사용해도 오류가 발생하지 않는 경우가 있습니다.

자바스크립트 함수는 필요한 옵션만 추출해서 사용하기 때문입니다.

 

6).ObjectId 직접 생성

=>_id 필드에 직접 값을 설정하는 것이 가능

=>ObjectId(“문자열 24자리”)로 생성할 수 있고 일련번호 처럼 new ObjectId()로 생성이 가능

=>inert함수를 이용해서 _id값을 직접 입력하면 동일한 값이 있을 때 에러를 발생시키고 save는 동일한 값이 있으면 수정을 합니다.

일련번호 형식으로 바꾼다. 일련번호 갑자기 바꾸는 것은 thread등 사용했기 때문이다.

var temp = new ObjectId()

print(temp)

 

패턴을 있으면

 

6.robomongo –mongo db에 접속해서 사용할 수 있는 gu tool

=>mongo db이 데이터를 sql형식으로도 조회 가능

 

use sample

db.users.find()

 

=>connect를 만들고  intellishell을 열면 명령어를 입력해서 결과 확인 가능

=>sql을 열면 sql 을 입력해서 mongo db의 데이터 사용가능

 

7.데이터 수정

1)수정메소드

update, updateOne, updateMany, replaceOne 추가

 

2)update함수

db.컬렉션이름.update({조건},{수정할 내용},{옵션})

=>옵션은 생략하면 기본값으로 설정

=>기본적으로 조건에 맞는 데이터 1개만 수정합니다.

 

3)수정 실습

샘플 데이터 1개 삽입

db.users.insert({"name":"강감찬",score:90})

 

수정 해주는 함수 호출

db.users.insert({"name":"강감찬"},{score:80})

 

별다른 옵션 없이 수정할 내용을 입력하면 수정할 내용으로 데이터가 대체됩니다.

위의 경우 name:강감찬 , score:90이라는 데이터가 score:80으로 대체됩니다.

 

db.users.find()

 

이름이 날라간다.

 

4)수정 내용에 설정하는 옵션

$set: 특정 필드만 수정할 때 사용

$unset:특정 필드를 제거

$inc : 특정 필드의 값에 더하기  => 조회수

$mul:특정 필드의 값에 곱하기

$rename :필드이름 변경

$currentDate: 현재 시간으로 설정  =>글을 수정한 날짜

 

데이터 1개 삽입

db.users.insert({"name":"굴리트","score":98,"nation":"holland"})

db.usres.find()

 

굴리트의 score 99로 수정

db.users.update({"name":"굴리트"},{$set:{"score":99}})

db.users.find()

 

 

굴리트의 nation 필드를 삭제

db.users.update({"name":"굴리트"},{$unset:{"nation":99}})

db.users.find()

굴리트의 score필드의 값을 5증가

db.users.update({"name":"굴리트"},{$inc:{"score":5}})

db.users.find()

 

굴리트의 lastModified필드의 값을 현재 시간으로 설정

db.users.update({"name":"굴리트"},{$currentDate:{"lastModified":true}})

db.users.find()

 

5)update 3번째 옵션

upsert:true로 설정하면 조건에 맞는 데이터가 없으면 insert

(update insert)

db.users.update({"name":"반바스텐"},{$set:{"score":89}})

db.users.find()

=>위의 경우는 조건에 맞는 데이터가 없어서 아무일도 발생하지 않습니다.

 

db.users.update({"name":"반바스텐"},{$set:{"score":89}},{upsert:true})

db.users.find()

조건에 맞는 데이터가 없으므로 반바스텐 89라는 데이터가 삽입

 

마지막 로그인 user의 시간을 업데이트 할때

한번도 로그인 하지 않는 분도 입력할 수 있다.

로그인 이력 : 로그인 id, 시간

a 12시에 로그인하면 수정하면 되는데

b가 없을 경우 13시에 업데이트 해야 하는데 없을 경우 추가한다.

 

multi:true로 설정하면 조건에 맞는 모든 데이터가 수정

(기본은 false여서 하나만 수정된다.)

 

 

RDBMS(관계형 데이터베이스)

테이블 설계

기본키 모든 데이터를 유일하게 구분

인덱스 설정

기본키로 하면 빨리 찾을 수 있다.

 

게시글

게시글 번호 (pk)

제목

내용

댓글은 내용(여러개 있을 수 있어서 게시글 테이블에 추가하면 안된다.)

 

댓글번호

게시글 번호

댓글 내용

 

 

 

 

 

 

 

 

 

 

join을 한다. 그래서 늦어 질 수 있다.

댓글 접고 원본글 내용에서 보다가 댓글클릭시 댓글만 조회된다.

 

 

No SQL

테이블 설계과정이 없다.

게시글번호

제목

내용

댓글 [{댓글번호: , 내용: }]

따로 따로 만들어서 join 을 할 필요없다.

$set

$push

$pull

 

stack

queue

push pop/pull(javascript)

 

카카오 spring hibernate

게시판

저장의 개념

변수  (프로그램 끝다 키면 없어진다.) 일시적이다.

파일 영구적으로 저장할 목적이다. 파일은 다른 데서 사용하려면 피씨가 켜져있어야 한다.

서버 외부에 파일로 저장 주기적으로 백업하고 켜놓는다.------------->저장 을 db(검색에 특화)

 

스마트폰은 컴퓨터이지만 서버로 될수 없다 돌아다니면서 IP가 변한다

내 카카오하고 친구 카카오 통신 하려면 중간에 고정 IP로 한다.

카카오 -> 카카오 서버 -> 애플서버 -> 친구 카카오에게 보낸다.(스마트폰 욺직이여서 )

서버 는 고정적인 이름(도메인)이나 주소(IP)가 있어야 한다.

 

6)필드에 배열이 있을 때 수정

배열에 데이터를 추가할 때$push

배열에서 데이터를 제거할 때는 $pul을 사용

 

//reply라는 필드에 배열을 소유하고 있는 데이터 생성

db.board.insert({"board_num":1,"board_id":"ggangpae1","board_title":"가입인사","board_content":"안녕하세요 반갑습니다.","reply":[]})

db.board.find()

 

board_num 1번인 데이터의 reply에 데이터를 추가

db.board.update({"board_num":1},{$push:{"reply":{"reply_num":1,"reply_content":"환영합니다.","reply_id":"admin","reply_time":ISODate("2019-1231T12:19:00")}}})

 

//2019-1231 날 짜만 할 겨우

//z는 더 아래 단위 천...

board_num 1번이고  reply_num 1번인 데이터의 content time을 수정

db.board.update({"board_num":1, "reply.reply_num":1},{$set:{"reply.$":{"reply_num":1"reply_content":"안녕.", "reply_time":ISODate("2019-1231T12:26:00")}}})

 

board_num 1번인 데이터의 reply_num 1번인 데이터를 삭제

db.board.update({"board_num":1},{$pull:{"reply":{"reply_num":1}}})

 

각각의 작업을 수행하고 match가 몇개 되는지 확인

조건에 맞는 데이터가 없으면 match된 데이터가 없다고 나옵니다.

옵션들에 따옴표를 해도되고 하지 않아도 됩니다.

 

8.데이터 삭제

remove()

deleteOne()

deleteMany()

 

=>remove의 첫번째 매개변수는 삭제할 조건입니다.

두번째 매개변수는 justOne이라는 옵션인데 true로 설정하면 1개만 지워지고 생략하거나 false로 설정하면 조건에 맞는 데이터가 모두 삭제됩니다.

 

9.컬렉션 삭제는 drop입니다.

board_num 1인 데이터 모두 삭제

 

db.board.remove({"board_num":1})

db.board.find()

 

board라는 컬렉션을 삭제

db.board.drop()

db.borad.find()

 

10.MOngo DB에서 documnet를 삽입 ,삭제,갱신 하는 것도 중요하지만 mongo db는 자식 테이블을 별도로 만들지 않고 부모 테이블에 배열의 형태로 저장하기 때문에 배열의 데이터를 삽입,삭제 ,갱신하는 것도 중요합니다.

 

11.bulkWrite

=>삽입 ,삭제 , 갱신을 동시에 수행할 수 있는 함수

=>insertOne,updateOne,updateMany, deleteOne,deleteMany함수를 사용

 

삽입과 수정을 하나의 명령어로 수행하도록 bulkWrite 사용

//90으로 여고 88로 변경된다.

db.board.bulkWrite([{insertOne:{"document":{"name":"kim","score":90}}},{updateOne:{"filter":{"name":"kim"},"update":{$set:{"score":88}}}}])

 

db.board.find()

 

 

12.데이터 검색

=>find()함수 이용

=>첫번째 매개변수로 조건을 설정하고 두번째 매개변수로 조회할 필드를 설정

=>매개변수를 아무것도 대입하지 않으면 컬렉션의 모든 데이터 조회

 

1).users컬렉션의 모든 데이터 조회

db.users.find()

 

2)특정 필드만 출력하거나 제외

=>두번째 매개변수에 {필드이름:0 또는 1,...}

=>0이 설정되면 출력하지 않고 1이 설정되면 조회

 

users에서 _id name만 조회

>db.users.find({},{"name":1})

usres에서 name만 제외

>db.users.find({},{"name":0})

db.users.find({},{"name":1,"score":1})

db.users.find({},{"name":0,"score":0})

조회시 1 1 끼리 0 0끼리 사용해야 한다. 혼용하면 오류 난다.

 

3.조건 설정

{필드이름:,...}

=>필드의 값이 값고 일치하는 데이터만 조회

=>여러 개의 조건을 나열하면 and입니다.

 

4)조건 연산자

$eq    : = 와 같은 기능으로 이 기능을 사용하지 않고 값을 직접 설정하는 형태를 사용

$ne    : <> != 같은 기능

$lt(lte): <(<=)

gt(gte): > (>=)

 

$in:배열에 속하는 경우

$nin:배열에 속하지 않는 경우

 

$not:반대로

$or: 또는

$and:그리고

$nor:not or

4개는 사용방법이 같다.

db.users.find( {$or: [ {name:"반바스텐"}, {password:89} ] })

 

users에서 score 90이 넘는 데이터만 조회

db.users.find({'score' :{$gt:90}})

 

users 에서 name이 굴리트 이거나 반바스텐인 데이터 조회

db.users.find({'name':{$in :['굴리트','반바스텐']}})

db.users.find({'name':{$nin :['굴리트','반바스텐']}})

 

5)like

=>정규식(Regular Expression - RegExp) 패턴을 사용

문자열에서 특정 패턴을 문자열을 조회하기 위해서 사용하는 문법

[0-9]

[-]

이메일은 정해진 단어가 아니다.

pattern을 뺄 경우 정규식 사용한다.

[A-Za-z]

 

users에서 name이 굴로 시작하는 데이터만 조회

db.users.find({'name':/.*/})

db.users.find({'name':/^/})

 

users에서 텐으로 끝나는 데이터만 조회

db.users.find({'name':/$/})

 

정규식:문자열에서 원하는 글자를 찾는 것이다.

여기 원래 정규식이였다.

 

6)findOne

=>1개만 조회

 

7)find().limit(개수)

 

8)find().skip(개수)

 

9)find().sort({필드이름:1 또는 -1,...})

=>1을 오름차순 정렬이고 -1을 설정하면 내림차순

 

10)limit,skip,sort는 조합할 수 있습니다.

db.users.find().skip(0).limit(1) // 여기 숫자는 chunk

db.users.find().skip(1).limit(1) // 몇개를 띄여쓰고 몇개를 찾을 가?

db.users.find().sort({"name":1}) //이름의 오름차순 정렬

chunk 는 분할 한다는 의미이다.

python에서는 chunk사용한다.

db.users.find().sort({"name":-1})

크기 비교할때 보통 3개 로 돌아온다.

 

11)cursor

=>여러 개의 데이터가 있을 때 하나씩 접근 할 수 있도록 해주는 포인터

=>다음 데이터 존재여부를 알려주는 메소드와 다음 데이터로 이동하는 메소드를 가지고 있습니다.

cursor는 첫번째 데이터를 가르키지 않는다.

그래서 첫번때 데이터를 읽으려면 next를 해야한다.

begin of file =>출발점 bof

데이터가 없는 끝나는 자리는 end of file(EOF)

자료구조에선느 BOF->HEAD

                  EOF->TAIL

다음 있냐 없냐는가 아니면 다음으로 넘어가는 것 등은 next이다.

 

데이터를 하나씩 접근

var cur = db.users.find()

 

데이터 존재 여부를 확인

cur.hasNext()

true false가 리턴

true가 리턴되면 다음 데이터가 잇는 것이고 false가 리턴되면 다음 데이터가 없는 경우

 

다음 데이터가 존재하는 경우 다음 데이터 확인

cur.next()

 

var cur = db.users.find()

cur.hasNext()

cur.next()

#프로그래밍에서 가져온다.

 

**Map – Reduce(맵 리듀스)

=>데이터의 모임에 집계를 적용한 후 연산을 수행해도록 하는 것

=>연산이나 집계 적용단위는 함수

 

1.샘플 데이터 생성 -CLASS별로 score의 합계를 구할려고 합니다.

db.map.insert({"name":"kim",score:76,"class":"A"})

db.map.insert({"name":"lee",score:85,"class":"B"})

db.map.insert({"name":"park",score:91,"class":"A"})

db.map.insert({"name":"choi",score:65,"class":"B"})

 

2.Map –Reduce Programming에서는 2개의 함수가 필요

집계를 위한 함수 그룹화할 함수

연산을 수행할 함수 연산 함수

 

#집계

var mapper = function(){

           emit(this.class, {score:this.score});

}

 

#연산

 

var reducer = function(key,values){

           var sum = 0;

           values.forEach(function(doc){

                       sum = sum + doc.score;

    });

    return {score:sum};

}

sum = sum + 1;=>개수가 된다.

#map-reduce 수행

db.map.mapReduce(mapper,reducer,{out:{inline:1}})

 

Hadoop            분산저장처리 기술

분산시스템은 각자 연산해서 한다.

**python mongo db연동

=>pymongo라는 패키지를 이용

1.pymongo패키지를 설치

cmd창에서 >pip install pymongo

python은 프로그램 수행도중에 설치 해도 괜찮다.

R은 다시 설치하면 restart된다.

 

2.mongo db연결

변수 = pymongo.MongoClient("ip주소","포트번호")

=>포트번호를 생략하면 27017

=>ip주소를 생략하면 로컬 컴퓨터

 

3.데이터베이스 설정

데이터베이스 변수 = 변수.데이터베이스이름

=>데이터베이스 이름이 없으면 새로 만들어 집니다.

 

4.컬렉션 설정

컬렉션변수 = 데이터베이스변수.컬렉션이름

=>컬렉션 이름이 없으면 새로 만들어 집니다.

 

5.실습

데이베이스 연결 및 컬렉션 연결

 

from pymongo import MongoClient

 

'''

데이터베이스 연결

'''

con = MongoClient()

#print(con)

 

'''

con 이 사용할 수 있는 속성과 메소드 확인

'''

#print(dir(con))

 

'''

데이터베이스 연결 및 생성

'''

db = con.mymongo

 

'''

컬렉션 연결 및 생성

'''

collection = db.sample

 

6.데이터 삽입

컬렉션.insert_one(dict 객체)

컬렉션.insert_many(list객체)

=>insert메소드가 있는데 deprecated

 

7.데이터 삽입 실습

dict1 = {"name":"kim","nation":"라이베리아"}

dict2 = {"name":"
요한","nation":"네덜란드"}
dict3 = {"name":"
에우","nation":"포르투칼"}
li = [dict2, dict3]

'''
데이터 삽입
'''
collection.insert_one(dict1)
collection.insert_many(li)

 

collection.insert(dict1)

C:/OracleConnect/mongoConnect.py:28: DeprecationWarning: insert is deprecated. Use insert_one or insert_many instead.

  collection.insert(dict1)

deprecated사용해도 되지만 없어질 수 있다.

 

8.데이터 조회

find_one(하나) find(여러개)함수를 이용

mongo db는 하나의 행을 dict로 만들어 줍니다.

 

분석 할려고 하면  자료형 무조건 확인 하는게 좋다.

'''
데이터 조회
'''
result = collection.find_one()
#print(type(result))
#<class 'dict'>
#dict
는 바로 출력해도 되고 dict['key']를 이용해서 부분적으로 사용
print(result)
print(result["name"])

result = collection.find()
#print(type(result))
#<class 'pymongo.cursor.Cursor'>
#
자료형이 class -> cursor
#
자료형이 모르는 클래스라서 사용 가능한 속성을 확인
#print(dir(result))
#iterator
여러개 데이터 순서대로 조회
#__iter__ 가 있으면 for - in 사용가능
#for i in []:
for i in result:
    print(i)

result = collection.find({"name":"
요한"})
for temp in result:
    print(temp)

 

result = collection.find({"name":"조지웨아"})

#print(type(result))

#자료형이 모르는 클래스라서 사용 가능한 속성을 확인

#__iter__ 가 있으면 for - in 사용 가능

#print(dir(result))

for temp in result:

    print(temp)

 

9.수정

update_one update_many

'''
데이터 수정
'''
#name
kim인 데이터의 nation을 모장비크로 변경
collection.update_one({"name":"kim"},{"$set":{"nation":"모장비크"}})
#update_many
다 바꿔진다.
result = collection.find()
for temp in result:
    print(temp)

 

 

 

10.삭제

delete_one() delete_many()

삭제하는 것은 경고하고 없에는 것이다.

'''
데이터 삭제
'''
collection.delete_one({"name":"kim"})
#update_many
다 바꿔진다.
result = collection.find()
for temp in result:
    print(temp)

 

 

java

gui프로그램

andriod

java network db연결

 

반응형

'Study > DB' 카테고리의 다른 글

DB-5  (0) 2020.09.17
DB-4  (0) 2020.09.15
DB-3  (0) 2020.09.15
DB-2  (0) 2020.09.13
DB-1  (0) 2020.09.13
반응형

**Trigger

=>관계형 데이터베이스에서는 테이블에 삽입,삭제,갱신 작업이 발생했을 때 작업 전이나 후에 다른 동작을 수행하도록 하는 것

=>작업 전에 하는 동작은 휴효성을 검사에 실패했을 때 작업을 수행하지 않도록 하기 위해서 인 경우가 많고 작업후에 하는 동작은 하나의 트랜잭션으로 묶여야 하는 작업이나 로그를 기록하는 경우가 많습니다.

1.테이블에 데이터가 삽입될 때 데이터 삽입 시간과 삽인된 데이터의 기본키를 다른 테이블에 저장

=>dept테이블에 데이터를 삽입하면 기록

CREATE TABLE deptlog(

 deptno number(2) PRIMARY KEY,

 insertime DATE

);

 

2.트리거 생성

--트리거 생성

CREATE OR REPLACE TRIGGER tri_01

--dept텡블에 데이터를 삽입한

--전에 동작시키고자 하면 after대신에 before삽입 대신에 다른 작업이면 update delete사용

AFTER INSERT ON DEPT

-- 꺼번에 여러 개의 행에 작업이 발생하면 작업 단위별로 것인지 아니면 전체에 한법만 동작 것인지

--for each row 수행 그렇지 않은 경우는 생략

OR EACH ROW ;

 

a ->dept no primary key

b -> deptno reference A (deptno) on delete cascade

insert, delete, update

로그 잘 만들어 줘야 한다.

--2.트리거 생성

--트리거 생성

CREATE OR REPLACE TRIGGER tri_01

--dept텡블에 데이터를 삽입한

--전에 동작시키고자 하면 after대신에 before삽입 대신에 다른 작업이면 update delete사용

AFTER INSERT ON DEPT

FOR EACH ROW

--begin end ->plsql이라고 한다. 문법체크 하지 않고 만들어진다.

BEGIN

       --새로 입력되거나 수정되는 경우에는 :new 이전 데이터는 :old

       INSERT INTO DEPTLOG(deptno, inserttime) VALUES(:NEW.deptno, SYSDATE);

END;

--/ dbeaver에서는 안해도 된다.

 

 

SELECT * FROM deptlog;

 

 

INSERT INTO DEPT (deptno, dname, loc)

VALUES(73,'경비실','이대');

 

 

INSERT INTO DEPTLOG(deptno, inserttime) VALUES(72, SYSDATE);

DELETE FROM DEPTLOG;

 

2.트리거를 이용한 유효성 검사

=> 작업을 하지 않도록 해주는 코드

raise_application_error(에러코드번호 ,에러메시지)

emp테이블에서 sal 값을 현재 값보다 작은 값으로는 수정하지 못하도록 트리거를 생성

 

CREATE OR REPLACE TRIGGER tri_02

BEFORE UPDATE ON emp

FOR EACH ROW when(NEW.sal < OLD.sal)

--다른 작업 있을 경우 or 연결

BEGIN

       RAISE_APPLICATION_ERROR(-20500,'sal 작은 값으로는 수정 못함');

END;

 

 

UPDATE emp SET sal = 900 WHERE ENAME = 'SMITH';

--정상 수행

UPDATE emp SET sal = 800 WHERE ENAME = 'SMITH';

 

--특정 시간대에 동작하지 않도록 하기

BEGIN

       IF TO_NUMBER(TO_CHAR(SYSDATE,hh24)) NOT BETWEEN 9 AND 18 THEN

               RAISE_APPLICATION_ERROR(-25001,'9시에서 18 까지만 작업을 수행합니다.');

END;

 

RAISE_APPLICATION_ERROR( [에러코드][에러메시지] )

에러코드 : -20000 ~ -20999 사이의 코드

; 부분 주의해서 하기

 

 

**1.사용자 접근 제어

관리자 권한으로 해야 한다.

권한 부여  grant

with admin option 권한을 다른 사용자에게 부여할 없다. 없으면 읽기 전용

권한 취소 revoke

a -> b 권한 부여하는데 a 취소한다고 해서 b 변하지 않는다.

cascade , 하면 연쇄로 삭제되거나 수정된다.

 

 

mysql ->root

oracle ->system sys

관리자 권한에서는 테이블 만든는게 좋다. 권한도 없을 있고 테이블도 많아서 찾기 힘들다.

 

전역데이터베이스명

xe ->express edition

orcl ->exterprise edition

자기것은 owner 사용하지 않는다.

특정 테이블 가져올때는 tables

dmp

 

 

fromuser touser

 

python DB API

 

 

**파이썬에서 데이터베이스 연동

1.표준 API 이용하는 방법

2.pandas 같은 자료구조를 제공하는 패키지에서는 데이터베이스에 별도의 방식으로 접근

3.orm(object relation mapping)

=관계형 데이터베이스의 테이블과 객체를 1:1 매핑시켜서 sql없이 데이터베이스를 사용하는 방식

=>Django프레임워크 에서 지원

=>java hibernate,android content values, IOS에서의 CORE DATA등이 ORM 개념

 

 

** 오라클 사용

1.CX_ORACLE이라는 패키지를 이용

1)패키지 설치

pip install 패키지이름

pip install 패키지이름 --upgrade:업그레이드

pip install 패키지이름 = 버전:  특정 버전 설치

 

2)pip업그레이드

 

 

c->vc++

   spss

:업그레이드 제조회사에서 제공

java ->오픈 소스

누구나 자바 가지고 배포 수있다.

 

maven

gradle

이것들이 검정한다.

코드 + 문서 올려서 cran 업로드 한다.

cran 한글로 되여있는것 안읽는 것이다.

일반인이 만들 경우 버전 문제가 있을 있다.

 

 

다운할 경우 종속의 경우가 있다.

tensorflow numpy 종속이 되여있ㄷ

numpy 있어야 tensorflow있어야 한다.

pip install tensorflow numpy필요하면 자동으로 업데이터 한다.

여러개 같이 사용해서 작업한다.

 

3).pip명령이 오류가 발생하는 경우

=>pip command 없다고 나오는 경우

python 설치되지 않았거나 python명령어 디렉토리가 path 추가되지 않은 경우 입니다.

 

=>windows 경우에는 VC++ 패키지를 만드는 경우가 있는데 이러한 패키지들은 vc++ 재배포 패키지를 설치해야만 설치되는 패키지들이 있습니다.

 

4).금융기관이나 공공기관 폐쇄망에서의 설치

=>다운로드가 가능한 곳에서

pip download 패키지이름으로 현재 컴퓨터에 다운로드

 

=>다운로드 받은 파일들을 복사한

pip install 파일명으로 설치

때는 자동으로 종속된 패키지를 설치해주지 않기 때문에 직접 하나하나 순서대로 설치해야 합니다.다른 패키지가 필요하면 어떤 패키지가 없다고 에러 메시지가 나오기 때문에 메시지를 읽으면서 하면 됩니다.

 

2.외부 모듈 가져오기

1)import 모듈이름 : 모듈이름에 해당하는 모듈을 모듈이름으로 묶어서 가져옵니다.

ex).import numpy

numpy 있는 것들은 numpy.이름 으로 사용해야 합니다.

 

2)from모듈이름 import모듈 내부 요소들을 나열: 모듈이름에 해당하는 모듈에서 import뒤에 있는 것들을 현재 모듈에 포함시켜서 가져옵니다.

 

import pandas

pandas.DataFrame()

 

from pandas import DataFrame

DataFrame()

 

3)from 모듈이름 import * : 모듈이름에 해당하는 모듈 모든 내부요소를 현재 모듈에 포함시켜서 가져옵니다.

 

4).import 모듈이름 as 별명: 모듈이름 대신에 별명을 사용합니다.

import pandas as pd :pandas대신에 pd라는 이름을 사용

import numpy as np:numpy대신에 np라른 이름을 사용

 

3.파이썬에서 오라클 연결

import cx_Oracle

 

#접속 정보 만들기

변수1 = cx_Oracle.makedsn(‘ip 주소’,’포트번호’,’데이터베이스이름’)

#접속

변수2 = cx_Oracle.connect(user= ‘계정’,password = ‘비번’,dsn = 변수1)

 

#연결 해제하기

변수2.close()

 

프로젝트에서 설치 된다.

 

아래 3개는 반드시 닫기

file

newwork

database

close안하면 읽기 전용으로 자주 뜬다. 파일을 닫지 않을 경우

 

4.관계형 데이터베이스 연동 때는 tuple 사용하고  No sql 연동할 dict 사용합니다.

 

5.insert,delete,update

=>연결 객체로 부터 cursor. 가져옵니다.

cur = 변수2.cursor()

 

=>cursor 이용해서 sql 실행

cur.execute(‘sql 구문’)

cur.execute(‘매개변수를 이용한 sql구문 작성’,(매개변수에 해당하는 데이터 나열))

 

=>작업을 완료하려면 cur.commit()

 

 

6.작업 도중 오류가 발생

에러 메시지가 ora 시작하면 오라클 접속오류나 sql에러

 

dept테이블에 데이터 삽입

cursor = con.cursor()

cursor.execute(“insert into dept(deptno,dname,loc) values(51, ‘총무’,’광주’)”)

con.commit()

 

방화벽 끄기

 

7.파라미터를 이용한 실행

sql구문을 만들 :번호 형태로 매개변수를 만들고 두번째 매개변수로 :번호 자리에 매핑될 튜플을 대입하는 방법으로 실행이 가능

cursor = con.cursor()

cursor.execute("insert into dept(deptno,dname,loc) values(:1, :2,:3)",

                   (53,"비서실","부산"))con.commit()

=>매핑하는 구조를 이용하면 데이터를 입력받아서 사용하는 것이 편리

 

 

 

deptno dname,loc 입력받아서 deptno 해당하는 데이터의 dname loc 수정

#데이터 입력받기

    deptno = input("부서번호")

    dname = input("부서명")

    loc = input("지역")

 

    cursor.execute("insert into dept(deptno,dname,loc) values("+deptno+",'"+dname+"','"+loc+"')")

 

cursor.execute("insert into dept(deptno,dname,loc) values(:1, :2,:3)",

                   (int(deptno),dname,loc))

 

 

#데이터 수정하기

#수정 구무 실행

    cursor.execute('update dept set dname=:1 , loc = :2 where deptno = :3',(dname,loc,int(deptno)))

 

**데이터 읽기

=>execute까지는 같은데 cursor객체의 fetchall 이라는 메소드를 호출하면   select 결과가 튜플의  튜플로 만들어집니다.

fetchone이라는 메소드를 호출하면 1개만 튜플로 리턴됩니다.

cursor.execute('select * from dept')

    #1 데이터 가져오기

    data = cursor.fetchone()

    print(data)

    for imsi in data:

        print(imsi)

 

#여러개 데이터 가져오기

    data = cursor.fetchall()

    #print(data)

    for imsi in data:

        print(imsi)

 

#데이터를 저장할  list 생성

    li = []

    for imsi in data:

        dic = {'부서번호':imsi[0],'부서명':imsi[1],'지역':imsi[2]}

        li.append(dic)

    print(li)

 

 

    cursor.execute('select * from dept where deptno = 93')

    data1 = cursor.fetchall()

    #없을 경우에는 어떻게 구분하는지

    #튜플은 데이터 개수를 카운터로 구할 있다.

    #print(data.count())

    #데이터 개술 출력 0개면 검색된 데이터가 없음

    #1이상이면 검색된 데이터가 있음

    print(len(data1))

   

    #작업한 내역을 원본에 반영

    con.commit()

    print("삽입성공")

   

   

    #print(con)

    #print(dir(con))

 

 

**로그인

아이디와 비밀번호를 입력받아서 아이디와 비밀번호에 해당하는 데이터가 있으면 로그인 성공 없으면 로그인 실패

 

원래는 비밀번호는 반드시 암호화해서 저장하고 복호화가 불가능하도록 해야 합니다.

 

**데이터베이스 연동 프로그램의 가장 기본은  crud(create,read,update,delete)

=>데이터 삽입 , 수정 ,삭제

=>데이터 전체 또는 페이지 단위로 가져오기 ,기본키를 가지고 하나의 데이터를 조회

 

**프로시저실행

=>커서.callproc(‘프로시저이름’,(프로시저의 매개변수 나열))

 

1.dept테이블에 데이터를 삽입하는 프로시저를 생성

create or replace procedure insert_dept(

)

is

begin

       프로시저 내용

end;

 

 

create or replace procedure insert_dept(

       vdeptno dept.DEPTNO%TYPE,

       vdname dept.DNAME%TYPE,

       vloc dept.LOC%TYPE

)

is

BEGIN

               INSERT INTO DEPT(DEPTNO,DNAME,LOC)

               VALUES(vdeptno,vdname,vloc);

      

END;

 

2.프로시져 테스트

 

BEGIN

       INSERT_DEPT(13,'영업','서울');

END;

 

 

new PROJECT->

 

이것 설정시 pycharm에서도 연결 가능하다.

프로젝트를 전체것사용하기

 

 

 

=>프로그램을 나누어서 한다.

controller service dao

나누어서 단위테스트 한다.

프로그램을 분할해서 한다.

 

 

3.파이썬 코드

pycharm

import cx_Oracle

try:
    #접속 정보 만들기 :컴퓨터 ip,port,sid
    dtnStr = cx_Oracle.makedsn("IP","1521","xe")
    # 데이터베이스 연결 객체 생성
    con = cx_Oracle.connect(user= "scott",password="tiger",dsn = dtnStr)
    # 데이터베이스 작업 객체 생성
    cursor = con.cursor() 


   
   
# sql execute를 호출하고 프로시저는 calporc를 호출
   
# 매개변수는 튜플
   
cursor.callproc("insert_dept",(14,"제무","이대"))

   
#작업 내용을 원본 데이터베이스에 반영
   
con.commit()
except Exception as e:
   
print(e)
finally:
   
#데이터베이스 연결 해제
   
con.close()

 

 

**blob 저장과 읽기

blob:파일의 내용을 저장하기 위한 오라클 자료형

프로그래밍 언어에서는  byte 집합으로 간주(python 경우는 bytes)

 

1.blob 저장하기 위한 테이블을 생성

=>데이터베이스에서 작업

=>파일이름과 파일내용을 저장할 있는 테이블을 생성

create table filesave(

  FILENAME VARCHAR2(50),

  FILECONTENT BLOB

);

-- 명렬 수행에 실패하거나 수행하지 않으면 파이썬에서 VIEW또는 TABLE 없다는 에러 메시지

 

 

더블 클릭시 이미지 창이 나온다.

 

c 드라이브에 파일 저장하면 오류가 경우 있어서

사용할 있는 디렉터리로 해야 한다.

문서 디렉터리가 제일 편하다.

저장이 되야 읽는 것이 가능하다.

 

 

import cx_Oracle

try:
   
#접속 정보 만들기 :컴퓨터 ip,port,sid
   
dtnStr = cx_Oracle.makedsn("IP주소","1521","xe")
   
# 데이터베이스 연결 객체 생성
   
con = cx_Oracle.connect(user= "scott",password="tiger",dsn = dtnStr)
   
# 데이터베이스 작업 객체 생성
   
cursor = con.cursor()

   
#읽을 파일의 경로 만들기 -파이썬은 디렉토리 기호를 \를 사용해도 되고 /를 사용해도 됨
   
filePath = "C:/Users/admin/Desktop/03. DB/img1.jpg"

   
#파일 내용 읽기
   
f = open(filePath, "rb")
    photo = f.read()
   
#파일 닫기
   
f.close()

   
#파일 이름 만들기- /로 분할해서 가장 마지막 부분을 파일이름으로 설정
   
path = filePath.split("/")
    filename = path[
len(path)-1]#파일 이름은 img1.jpg이 될 것이다.

    #sql
실행
   
cursor.execute('insert into filesave(filename,filecontent) values(:1,:2)',(filename,photo))

   
#작업 내용을 원본 데이터베이스에 반영
   
con.commit()
except Exception as e:
   
print(e)
finally:
   
#데이터베이스 연결 해제
   
con.close()

 

 

import cx_Oracle

try:
   
#접속 정보 만들기 :컴퓨터 ip,port,sid
   
dtnStr = cx_Oracle.makedsn("IP주소","1521","xe")
   
# 데이터베이스 연결 객체 생성
   
con = cx_Oracle.connect(user= "scott",password="tiger",dsn = dtnStr)
   
# 데이터베이스 작업 객체 생성
   
cursor = con.cursor()

    cursor.execute(
"select * from filesave")

   
# 전체 데이터 가져오기
   
data = cursor.fetchall()

   
for imsi in data:
       
print(imsi[0])
        f =
open("C:\\Users\\Public\\Documents\\" +imsi[0] ,"wb")#파일 이름
       
#기록할 데이터 가져오기
       
blob = imsi[1]
       
#파일에 기록
       
offset = 1
       
while True:
           
#65536 바이트 단위로 읽어준다.
           
temp = blob.read(offset, 65536)

           
#데이터가 있으면
           
if temp :
                f.write(temp)
           
#읽은 데이터가 65536 보다 작으면 전부 읽은 것이므로 읽기 중단
           
if len(temp) < 65536:
               
break
   
f.close()
except Exception as e:
   
print(e)
finally:
   
#데이터베이스 연결 해제
   
con.close()=====================이미지가 경우import cx_Oracle

try:
   
#접속 정보 만들기 :컴퓨터 ip,port,sid
   
dtnStr = cx_Oracle.makedsn("IP주소","1521","xe")
   
# 데이터베이스 연결 객체 생성
   
con = cx_Oracle.connect(user= "scott",password="tiger",dsn = dtnStr)
   
# 데이터베이스 작업 객체 생성
   
cursor = con.cursor()

    cursor.execute(
"select * from filesave")

   
# 전체 데이터 가져오기
   
data = cursor.fetchall()

   
for imsi in data:
       
print(imsi[0])
        f =
open("C:\\Users\\Public\\Documents\\" +imsi[0] ,"wb")#파일 이름
       
#기록할 데이터 가져오기
       
blob = imsi[1]
       
#파일에 기록
       
offset = 1
       
while True:
           
#65536 바이트 단위로 읽어- 한번에 읽을 크키를 설정하는 것이므로 메모리 크기를 가지고 조절
           
#1부터 65536까지 읽어오기
           
temp = blob.read(offset, 65536)

           
#데이터가 있으면
           
if temp :
                f.write(temp)
           
#읽은 데이터가 65536 보다 작으면 전부 읽은 것이므로 읽기 중단
           
if len(temp) < 65536:#64k
                
break
           
# 앞 쪽의 64k를 읽고 다음 데이터 읽기 위해서 offset을 조정
           
offset += len(temp)#이미지가 클 경우
   
f.close()
except Exception as e:
   
print(e)
finally:
   
#데이터베이스 연결 해제
   
con.close()

 

 

mongodb procedure 자바스크립트로 것이다.

mean(Mongo DB-자바스크립트 문법으로 데이터베이스 작업, Express.js – 서버 생성, Angular.js- 서버의 데이터를 mvc 패턴으로 출력, Node.js-서버 사이드 언어의 역할 )

angular 자리는 최근에는 react vue 구현하기도 합니다.

react 많이 사용한다.(andriod, ios )같이 사용가능하다.

facebook - hbase

mysql ->nosql사용가능하다.

mondo DB 소계할 mysql 한다.

 

예전의 프로그래밍

1.관계형 데이터베이스(oracle,MySQL, -SQL)

2.서버 사이드 프로그래밍 언어(JAVA – JSP&SERVLET, c#-asp.net, Php)

3.클라이언트 사이드 프로그래밍 언어 (html, css , javascript)

 

 

python 자료구조와 javascript같다.

{“”:””}python 에서는 dict 라고 하고 javascirpt 객체이다.

[]python에서는 list javascript 배열 자료구조는 비슷한데 같지는 않다.

서버 ->csv,xml, json

python이라고 하면 json형식으로 하는게 좋다. 바로 치환가능하다.

python 주식 으로 하는 원인이 구글이 json으로 되여있다. 그래서 python으로

mongoDb python 같게 사용한다. 연동이 된다.

관계형은 execute

스키마 생성없이 가능하다.

데이터 넣으면 바로 스키마 생성한다.

테이블만들지 않고 바로 테이블 만들 있다.

 

DTO(RDBMS) ->구조를 만들고 구조를 기반으로 데이터

구조 (테이블)->데이터

구조 변경이 어렵다. ALTER 하면 데이터 망가질 가능성이 있기 때문에

강력한 트랜잭션

 

DICT(MAP) No SQL -> 구조 생성 없이 바로 데이터 생성 가능

구조 변경이 쉽다. 

확장이 쉬움

 

 

 

오라클은 결과를 가져온다.

no sql 포인터를 지정한다.

다음다음 하면서 데이터 하나씩 하나씩 접근한다.

디비에서는 cursor program 언어에서는 :iterator(반복자)

eg: for in

기존에는 데이터가 

d1     d2     d3

 

 

 

 

 

조인을 하려면 d1+d2+d3 모으고 -> 작업수행 -> 결과

 

리듀스

작업 원리는

작업을 각각에서 하고

 

 

결과를 처리한다.->집계

 

시각화 -> javascript web에서 시각화는 d3.js

https://d3js.org/

 

v  Mongo DB Hbase 차이

v  Mongo DB 하나의 Collection 저장된 데이터들을 하나의 파일에 저장하지만 Hbase 관련된 컬럼들을 패밀리로 묶어서 하나의 파일에 저장

v  Hbase에서는 Row Key 설계하는 방법에 따라 하나의 데이터를 저장하는 방식을 결정하지만 Mongo DB에서는 Document Id라는 _id라는 필드를 생성해서 JSON 문자열을 BSON으로 변환해서 저장

mongodb 옆으로 저장

hbase 관계성 있는 것으로

 

아래 두개 같다.

{‘1’:10 , ‘2’ : 20}

{‘2’ : 20 ,‘1’:10 }

hasing 한다. 데이터 값이 같고 hasing하면 운영체제가 값을 정하는 것이다.

같은 속성의 같은 값이 있더라고 다른 데이터이다.

 

$ 몽골디비가 연산자를 할때

. -> windows 제외하고 이것은 숨김이다.

맥은 unix기반에다 max osx덮어 씌우는 것이다. gui 만든 것이다.

unix(c) ->돈주고 산다. 컴퓨터를 사면 준다.

solaris

상용하면서 대비

linx ()->andriod linux위에 씌우는 것이다.

window dos라는 기반에다 visual 해서  windows이다.

python r unix, linux에서 했다.

_ 시작하는 것도 사용하지 말라 예약어일 가능성이 높다.

대소문자 데이터 형을 정확히 구분

 

json데이터 읽기

 

msi는 설치 버전의 약자이다. 실행

zip은 압축풀고 명령어로 한다.

 

**mongo db명령

1.서버 실행

mongod –dbpath  데이터디렉토리

 

2.클라이언트 실행

mongo

 

3.기본 포트 번호는 27017

 

 

명렁어나 수행하는 것 bin에 가서 찾기

pip명령어도 bin에 가서 찾으면 된다.

mongo d가 서버를 만들어주는 것이고

환경변수 등록

 

**mongo db명령어를 환경 변수의 path에 등록

=>path는 명령어를 입력했을 때 찾는 데렉토리를 설정하는 환경변수

 

운영체제마다 설정이 조금씩 자른다.

윈도우즈에서는 탐색기를 실행하고 [내 컴퓨터] 를 선택하고 마우스 오른쪽을 클릭해서 [속성]을 선택 하고 왼쪽 화면에서 [고급 시스템 설정]을 클릭

고급 탭으로 이동하고 [환경변수]를 클릭

C:\Program Files\MongoDB\Server\4.2\bin

 

4.2버전

위에는 admin

아래에서는 관리자

윈도우에서는 어디에 해서도 문제없다.

[시스템 변수] 항목에서 path 를 찾아서 편집을 클릭

C:\Program Files\MongoDB\Server\4.2\bin

 

path에 추가하기

=>windows7에서는 새로만들기가 없고 경로 문자열이 보일 텐데 맨 뒤에 붙여넣기를 하고 ;를 추가하면 된다.

=>환경 변수를 설정하면 다음에 실행되는 command창에서부터 적용

 

1.서버 실행

1)데이터를 저장할 디렉토리를 생성

저는 c드라이브에 mongodata

 

2)command창을 1개 실행해서 아래 명령을 입력

mongod –dbpath c:\mongodata

 

 

2.client 실행

1)로컬에 있는 데이터베이스에 연결

새로운 command창에 열어서 mongo

2)원격에 있는 데이터베이스에 연결

mongo –host “서버IP주소”:”포트번호

=>포트번호는 기본이 27017

mongo –host “IP주소”:”27017”

1.데이터베이스 생성 및 접속

=>존재하는 데이터베이스 이름이면 접속이고 없는 이름이면 접속하고 사용

use 데이터베이스이름

use mymongo=>mysql과 같다.

 

2.collection

 

=>관계형 데이터베이스의 table과 유사한 개념으로 도큐머트의 집합

테이블이라는 표현을 사용하지 않는 이유는 동일한 구조의 데이터만 저장되는 것이 아니기 때문이다.

=>mongo db join을 지원하지 않기 때문에 하나의 collection에 많은 양의 데이터를 저장하는 것을 권장하지만 성능 측면에서 하나의 collection 에 너무 많은 데이터가 있으면 읽기 속도가 느려집니다.

데이터를 가져올 때 디스크 읽기 오퍼레이션이 많이 발생하기 때문입니다.

여러 collection에 데이터를 분산해서 저장하는 것을 실무에서는 권장합니다.

 

=>collection생성

db.createCollection(“컬랙션 이름”)

 

=>데이터를 처음 삽입할 때 없는 컬랙션이름을 사용하면 컬렉션이 자동으로 생성됩니다.

 

3. 데이터 삽입

db.collection.insert({필드:, 필드 :})

db.collection.save({필드:, 필드 :})

db.collection.insertOne({필드:, 필드 :})

db.collection.insertMany({필드:, 필드 :},{필드:, 필드 :}) #여러개 입력할때 사용

 

 

=>데이터를 삽입하면 object라는 자료형으로 _id필드를 생성해서 삽입

_id가 기본키의 역할을 수행

insert save의 차이는 이미 존재하는 _id를 직접 입력했을 때 insert는 에러가 발생하고 save는 수정을 합니다.

 

4.컬렉션의 전체 데이터 조회

db.collection.find()

 

5.데이터 삽입

db.users.insert({"nane":"kim"})

확인

db.users.find()

_id기본 키값이다.

 

게시판

RDBMS

회원테이블 ----------> 게시판테이블 ----------------->댓글 테이블

1 : N                           1:N

회원테이블과 ---->댓글테이블

1:N

데이터를 조회하면 JOIN을 한다.

 

 

MONGODB

회원게시판 댓글을 하나의 COLLECTION으로 만든다.

서로 다른 정보들을 그래서 조회에 강하다.

JOIN작업이 없다.

 

 

db.users.insert([{"name":"lee"},{"name":"park"},{"name":"choi", score:90}])

db.users.find()

 

6. insert 2번째 매개변수

ordered속성에 true false 지정할 있습니다.

옵션은 여러개의 데이터를 삽입할 사용이 가능합니다.

ordered true 설정하면 데이터를 순서대로 하나씩 삽입합니다.-싱글 스레드를 사용

ordered false 설정하면 데이터를 동시에 삽입합니다.-멀티 스레드를 사용

기본값은 true입니다.

 

여러 개의 데이터를 삽입하다가 에러가 발생하면 ordered true인 경우는 에러가 발생하는 시점부터 동작이 중지가 됩니다.

ordered false인 경우는 에러가 발생한 데에터를 제외하고는 모두 삽입이 됩니다.

 

사소한 에러는 무시하고 빠르게 데이터를 삽입하고자 하는 경우에는 ordered false로 해서 삽입하지만 데이터를 순서대로 연쇄적으로 삽입해야 하는 경우는 ordered true로 해서 d에러가 발생하면 작업을 더 이상 진행하지 않도록 해주어야 합니다.

다시 수행하고 싶을때 use mymongo

 

반응형

'Study > DB' 카테고리의 다른 글

DB-6  (0) 2020.09.18
DB-4  (0) 2020.09.15
DB-3  (0) 2020.09.15
DB-2  (0) 2020.09.13
DB-1  (0) 2020.09.13
반응형

제약 조건

default 입력하지 않을 경우 값을 설정

 

network을 타고 간다. 데이터 변질 될 가능성이 있어서 데이터 검증해야 한다.

데이터베이스에서도 해야 한다.

r 데이터 있을 경우 먼저 정제 한다.->안맞는 데이터 빼기 정재한다.

client -> smart phone app, web brower

 

데이터입력: check

client ->javascript 불필요한 트래픽 안 쓴다. 보안 이슈

           소스 보이면 해킹의 위험성 있다.

server->서버코드는 보이지 않는다.

response시 데이터 확인 그래서 체크 다시 한번 하는게 좋다.

request에서 도 데이터 다시 확인 하는게 좋다.안정성 문제가 있을 수 있다.

db에서 유효성 검사 를 하는게 좋다.->제약조건

데이터 변질 문제를 조심해야 한다.

데이터 생성 ->전송 처리 하고 분석

최근에는 발생한 곳에서 하는게 낳다.

unique 유일성

별명으로 쓰기

not null:필수

unique:유일성

primary key:테이블에서 행을 구분 not null이고 unique(1개만 지정가능)

check 데이터 종류 제한

테이블 설계=>이상현상 제거를 위해서 테이블 분석:정규화(mongodb차이점)

 

주민번호

이름

수강과목

수강료

전화번호

 

1번학생 전화 바꿔야 할 경우 2번 바꿔야 한다.

transaction문제 발생할 수 있다.

sql하나만 쓸 수 있다면

누군가가 다른 하나를 결정내릴 수 있다면 쪼개라

 

주민번호

이름

전화번호

1

010

2

011

1

010

 

주민번호

수강과목

1

python

2

python

1

java

 

 

수강과목

수강료

python

320,000

java

330,000

 

1번학생이 수강료 합계:join을 하면 먼저 cartesion product생긴다. 모든 조합 만들어서 filter한다.

테이블 쪼개만 좋다. 현업에서는 조회속도가 늦어진 문제 때문에 합친다.

하나의 테이블로 하고 안쪼개는 것이  no sql이라고 한다.

 

 

 

 

 

 

 no sql 트랜잭션 문제가 있다.

foreign key :학번이 3번인 분이 과목을 직접 신청할 경우 학생테이블에 없어서 여고 해야 하는 문제점을 해결

foreign key  설정

 =>2개 테이블의 대응수(cardinality) 조사

1:1        : 양쪽의 기본키를 다른 테이블에 외래키로 추가

1:n     : 1쪽의 기본키를 n쪽의 외래키로 추가

n:n     : 양쪽의 기본키를 가지고 외래키로 갔는 별도의 테이블을 생성

 

회원의 게시판

회원정보

ID(primary key )

PW

NAME

 

게시물 정보

num(글번호 primary key)

title

content

file

id(foreign key 회원정보테이블 뒤에 옵션 추가(delete on cascade, delete set null))

이를 경우 글을 쓴 회원 회원테이블에서 못 지운다.

delete on cascade  회원테이블 삭제시 게시물에 있는것 다 지운다.

delete set null 회원테이블 삭제시 게시물에 null로 된다.

참조 안하게 하는 방법: delete on cascade, delete set null

 

                                                       

 

무결성 제약 조건:

=>개체 무결성 : 기본키는 NULL이거나 중복 될 수 없다.(테이블 하나)

=>참조 무결성 : 외래키는 NULL이거나 참조 할 수 있는 값 만을 가져야 한다.(테이블 2)

 

제약조건은 모든 관계형 데이터 같다.

sqllite등 제약조건은 같다. fk는 안된다. 참조 시 delete on cascade 설정은 되는데 삭제는 안되서 trigger해야 한다.

access에서는 화면에서 잘 사용한다. excel하고 비슷하다.

sqllite는 기능이 떨어진다.

hana db , access등 비슷하다.

sqllite는 일시적으로 데이터를 저장하려고 해서 안되는 것이 좀 있다.

 

 

**제약조건(constraint)

=>테이블에 데이터를 저장할 때 반드시 지켜야 하는 조건

 

=>제약조건을 위반해서 데이터 삽입이 안되는 경우

dept테이블의 기본키는 deptno

deptno 는 중복될 수 없고 null일 수 없습니다.

 

 

INSERT INTO DEPT (DEPTNO, DNAME,LOC)

VALUES (01, '영업','서울');

--10번이 존재하기 때문에 삽입 에러가 발생합니다.

--제약조건 위반이라는 에러 메시지가 출력

 

--SQL Error [1] [23000]: ORA-00001: unique constraint (SCOTT.PK_DEPT) violated

--PK_DEPT라는 제약조건 위반

 

1.제약조건 확인

=>자신이 소유하고 있는 개체에 대한 정보는 USER_개체S 테이블에 저장되어 있습니다.

 

SELECT CONSTRAINT_NAME, CONSTRAINT_TYPE, TABLE_NAME

FROM USER_CONSTRAINTS;

 

2.제약조건 type

1). P: primary key

2). R: foreign key

3). C: CHECK NOT NULL

4). U: UNIQUE

 

 

3,제약조건 설정

create table 테이블이름(

           열이름 자료형 [constraint  제약조건이름] 제약조건 종류,

열이름 자료형 [constraint  제약조건이름] 제약조건 종류,

.........

[constraint  제약조건이름] 제약조건 종류(컬럼이름));

=>열을 만들때 설정하는 제약조건을 컬럼레벨 제약조건이라고 하고 열에 대한 정의를 전부하고 나중에 만드는 제약조건을 테이블 레벨 제약조건이라고 합니다.

=>예외는 하나 있다. not null은 반드시 컬럼 레벨에서 설정해야 합니다

 

null을 저장하는 방식에 대해서 알아두어야 한다.

4.데이터베이스에서 null저장

temp1 varchar(10) not null,

temp2 varchar(10)

 

temp1 10byte를 할당 받는다.

temp2null 여부를 저장하기 위한 1바이트를 추가로 설정합니다.

temp2 11바이트를 할당받아서 사용

 

a = null일 경우 a.하면 오류난다. nullpoint excetption

if a != null:

if a: ->저장공간에 가서 null인지 아닌지 확인해야 한다.

!a->절대 null일 수 없어

1

 

 

 

 

 

 

 

 

 

 

null허용시 1 byte더 준다.

1byte에서 확인한다.

5.작성

회원테이블

-email:문자 50자 이내 변경 불가능 -기분키

-pw:문자 15자 이내 변경을 자주 필수

- nickname:한글 10자 이내이고 변경 불가능 중복 불가능 유일

 

==>컬럼 레벨 제약조건을 이용해서 테이블을 생성

 

 

=> varchar2 저장되는 데이터 크기에 따라 저장공간이 변합니다.

char 설정하면 저장되는 데이터 크기와 상관없이 크기는 고정

자주 변경되는 데이터는 char 만드는데 varchar2 만들게 되면 데이터의 크기가 변경될 때저장 공간이 부족하면 row migaration( 이주)를 수행해서 작업 속도가 현저하게 떨어질 수 있습니다.

 

drop table member;--기존의 member 테이블이 존재하면 삭제

create table member(

       email varchar2(50) primary key,

       pw char(15) NOT NULL,

       nickname varchar2(30) UNIQUE);

--컬럼레벨에서 설정 하는 것이다.

 

 

6.제약조건 이름

==>제약조건을 만들 때 제약조건 이름을 생략하면 오라클이 제약조건 이름을 임의로 생성합니다.

==>제약조건을 삭제하거나 변경하고자 할 때 자신이 만든 이름이 아니기 때문에 찾을 때 어렵습니다.

 

 

위처럼 제약조건 이름없이 생성하는 것 보다는  제약조건 이름을 추가해서 생성하는 것을 권장

 

drop table member;

create table member(

       email varchar2(50) CONSTRAINT member_pk primary key,

       pw char(15) CONSTRAINT member_nn NOT NULL,

  nickname varchar2(30) CONSTRAINT member_uk UNIQUE);

 

=>제약조건 이름을 만들 때는 관습적으로 테이블이름 제약조건 종류를 합쳐서 만듭니다.

 

제약조건을 잘 해야 한다.

연동만 하고 제약조건을 하는게 좋다.

 

check는 열이름을 만든다.

7 체크 제약 조건 설정

check(컬럼이름 조건):

성별은 남 또는 여 만 가져야 한다.

gender varchar2(3) check(gender in (‘’,’’))

 

점수는 0-100사이의 값만 가져야 한다.

score number(3) check (score between 0 and 100)

 

데이터베이스 설계시 숫자데이터 확인하는게 좋다.

백분율 , 1.0 등 문제

 

--바로 하면 안된다.

데이터 정규화 와 표준화

case 1. 국어 0~100

영어 0 ~ 1000

case 2. 국어 80~100

영어 0 ~ 20

최대값 나눈다.

절대적인 수치를 저장할 수 있지만 상대적인 비율로 저장 하는 게 나중에 효율적이다.

 

색상 0 ~ 255 

      127

    0.5 ->수정할 필요 없다.

 

비율 값을 저장하면 효율적이다

 

 

8.외래키 제약조건

=>컬럼레벨에서 설정

references 참조할 테이블 이름(참조할 열 이름)옵션

참조할 테이블 이름->부모이름

 

==>옵션을 생략하면 참조하는 테이블에 있는 값은 참조되는 테이블에서 삭제할 수 없습니다./옵션을 생략하면 부모테이블에서 외래키로 설정된 값을 삭제할 수 없습니다.

==>옵션은 2가지가 있는데 하나는 부모 테이블에서 삭제될 때 자식 테이블에서 같이 삭제되도록 할 수 있고 다른 하나는 값을  null로 변경해주는 것입니다.

on delete cascade:같이 삭제

on delete set null:null로 변경

 

==>외래키로 설정되는 키는 그 테이블에서 primary key 이거나 unique이어야 합니다.

데이터베이스 이론 책에는 primary key이어야 한다고 나옵니다.

 

==>dept테이블에서 deptno 10인 데이터를 삭제

SELECT *

FROM DEPT d;

 

DELETE FROM DEPT d

WHERE DEPTNO = 10;

--SQL Error [2292] [23000]: ORA-02292: integrity constraint (SCOTT.FK_DEPTNO) violated - child record found

==>삭제 실패를 하게 되는데 emp 테이블에서 옵션없이 deptno 참조하기 때문에 emp테이블에서 10 저장하고 있으면 삭제가 안됩니다.

dept 테이블 자체도 삭제가 안됩니다.

 

drop table member;--기존의 member 테이블이 존재하면 삭제

create table member(

       email varchar2(100) primary key,

       pw char(15) NOT NULL,

       nickname varchar2(30) UNIQUE);

 

--데이터 삽입

INSERT INTO MEMBER (email, pw, nickname)

values('djkfd@nave.com','1234','군계');

--게시판

CREATE TABLE board (

       num NUMBER(5) PRIMARY KEY,

       title varchar2(100),

       content varchar2(1000),

       email varchar2(100) REFERENCES "MEMBER"(email) ON DELETE CASCADE

);

 

INSERT INTO board (num, title,content,email)

values(1,'제목','내용','111@naver.com');

--삽입 실패 :email member테이블의 email 참조하는 외래키로 설정

--member테이블에 없는 값은 삽입할 없습니다.

--SQL Error [2291] [23000]: ORA-02291: integrity constraint (SCOTT.SYS_C007013) violated - parent key not found

 

INSERT INTO board (num, title,content,email)

values(1,'제목','내용','djkfd@nave.com');

 

SELECT *

FROM board;

 

=>member테이블에서 emaildjkfd@nave.com 데이터를 삭제

borad테이블을 외래키 옵션이 on delete cascade라서 board테이블에서도 데이터가 삭제됩니다.

DELETE FROM MEMBER

WHERE EMAIL = 'djkfd@nave.com';

 

 

--부모 테이블 삭제 명령

drop table member;

==>SQL Error [2449] [72000]: ORA-02449: unique/primary keys in table referenced by foreign keys

테이블 drop할때는 안된다. 참조하는 테이블 이 없어도

drop, alter을 할경우 데이터 있는 것과 상관 없고 테이블 관계로 삭제하는지 한다.

그래서 drop할려면 게시판 테이블 부터 지워야 한다.

에러가 발생하는데 테이블의 구조를 변경하거나 삭제하는 명령은 데이터를 확인하지 않고 테이블 사이의 관계만 확인해서 수행여부를 결정합니다.

 

9.default

=>데이터를 입력하지 않았을 떄 자동으로 삽입하는 값을 설정할 때 사용하는 옵션

default 값의 형태로 설정

=>regdate는 오늘 날짜를 기본값을 설정

regdate default sysdate

 

 

=>readcnt값은 기본값으로 0을 설정

readcnt default 0

 

10.테이블 레벨 제약조건 설정

==>열을 생성할 때 제약조건을 설정하지 않고 열을 전부 생성한 후 마지막에 제약조건을 설정하는 것

제약조건이름(열 이름)의 형태로 설정

==>외래키는 foreign key(열 이름) references 부모테이블(열 이름) 옵션의 형태로 설정

==>반드시 테이블 레벨에서 제약조건을 설정해야 하는 경우가 있는데 기본키를 2개 이상의 열로 만들 때 입니다.

==>기본키를 2개 이상의 컬럼으로 만들게 되면 컬럼레벨에서 2개 열에 primary key를 설정해야 하는데 이러면 에러입니다.

primary key는 테이블을 만들 때 1번만 설정할 수 있습니다.

 

id varchar2(10) primary key,

num number(5) primary key

==>위와 같은 형태는 에러

==>만약에 id num을 합쳐서 primary key를 만들고자 하면 이 때는 모든 열을 정의하고 마지막에 primary key(id, num)의 형태로 설정해야 합니다.

 

 

11.제약조건 변경

1)제약조건 추가

alter table 테이블이름

add [constraint 제약조건이름]

제약조건종류(열이름);

 

3)제약조건 수정

alter table 테이블이름

modify 열이름 [constraint 제약조건이름] 제약조건 종류;

 

=>not null을 추가하는 경우는 add modify입니다.

null이 가능한 상태에서 null이 불가능한 것으로 수정하는 것으로 간주합니다.

 

3).제약조건 삭제

alter table 테이블이름

drop constraint 제약조건이름;

 

 

12.제약조건의 비활성화 및 활성화

1)비활성화

alter table 테이블이름

disable constraint 제약조건이름;

 

2)활성화

alter table 테이블이름

enable constraint 제약조건이름;

 

===>테스트 할 때 많이 이용

회원 테이블

 아이디는 필수

 비밀번호는 필수

 닉네임은 필수

=>샘플 데이터를 삽입해서 아이디 중복검사를 테스트

중복 검사해야 하는데 비밀번호와 닉네임은 입력해야 하는 불편적이 상황이 있을 경우 필수 조건을 비활성화 하고 중복아이디를 입력하여 테스트 진행한다.

 

 

**테이블을 제외한 개체

1.     View

=>자주 사용하는 select구문을 하나의 이름으로 만들어두고 마치 테이블인 것 처럼 사용하는 가상의 테이블

1)사용이유

=>속도 때문 :select구문은 요청이 오면 그 때 구분을 확인해서 실행

뷰와 프로시저는 처음 한 번 수행하고 나면 메모리에 저장된 상태로 존재해서 다음 호출부터는 구문확인을 하지 않고 메모리에 적재된 내용을 바로 수행합니다.

=>보안:각 사용자에게 모든 데이터를 넘겨주지 않고 필요한 데이터만 별도의 이름으로 사용하게 해서 실제 구조를 알 수 없도록 할 수 있습니다.

 

 

2)View는 삽입 ,삭제 ,갱신에 제약이 있는 것이지 못하는게 아닙니다.

View에 데이터를 삽입하면 View를 만들 때 사용한 원본 데이블에 데이터가 삽입됩니다.

 

3)생성 구문

create [or replace]  view 뷰이름

as

select 구문

[with check option]

[with read only]

 

==>or replace :뷰가 존재하면 수정

뷰는 alter view 명령이 없어서 구조변경이 안됩니다.

=>with check option select 구문에서 조회가 가능한 경우에만 삽입,삭제 ,갱신을 하도록 설정

with read only는 읽기 전용

두개 같이 쓰도 되지만 사용하지 않고 같이 있으면 안된다.

 

4)삭제

drop view 뷰이름:

 

5).실습

=>dept테이블의 모든 내용을 복사해서 tempdept테이블을 생성

create table tempdept

as

select *

from dept;

 

=>어떤 유저가 tempdept테이블에서 deptno dname 만 필요하다면 테이블을 주는 것이 아니라 뷰를 만들어서 제공

CREATE OR REPLACE VIEW deptView

AS

SELECT deptno,dname

FROM TEMPDEPT;

 

=>deptview테이블인 처럼 사용 가능

SELECT * FROM deptView;

deptView 존재하지 않는 테이블이지만 사용은 테이블처럼이다.

 

 

=>별도의 옵션 없이 뷰를 생성했기 때문에 뷰에 데이터 삽입,삭제 ,갱신이 가능

뷰에 작업이 발생하는 것이 아니고 원본 테이블에 작업을 수행

 

 

INSERT INTO deptView(deptno, dname)

values(11,'마케팅');

tempdept에 들어가서 deptView에 들어갔다.

=>원본 테이블에 데이터가 추가된 것이 확인 됨

 

=>뷰를 만들때 with read only옵션을 추가했으면 데이터 삽입에서 에러 발생

 

6)복합 뷰

=>2개 이상의 테이블을 join해서 만든 뷰

=>복합 뷰는  with read only옵션이 없어도 삽입 ,삭제 ,갱신 작업에 제약이 있습니다.

 

뷰는 alter가 안된다.

ALTER VIEW deptView

AS

SELECT deptno,dname

FROM TEMPDEPT;

--SQL Error [922] [42000]: ORA-00922: missing or invalid option

--OR REPLACE ALTER 안되서 이런 방식으로 한다.

CREATE OR REPLACE VIEW deptView

AS

SELECT deptno,dname

FROM TEMPDEPT;

 

-- 삭제

DROP VIEW deptView;

오라클은 inlineview등으로 페이지 처리 해야 한다.

 

2.     inline view

1). 오라클의  rownum

==>오라클이 부여하는 일련번호

==>select 구문을 수행해서 결과를 리턴할 때  보여지는 일련번호입니다.

==>이 번호를 FROM절에서 WHERE로 조건 비교를 할 때 임시로 부여된 후 WHERE 절에 조건을 만족하면 확정되는 형태로 번호가 설정됩니다.

==>어떤 행을 가져왔는데 이 행이  WHERE 절의 조건을 만족하면 ROWNUM 1증가해서 설정되지만 WHERE절의 조건을 만족하지 못하면 다음 행을 가져 올 떄 ROWNUM은 이전과 같은 값으로 설정됩니다.

STUDENT

NAME

SCORE

80

90

87

91

 

SELECT *

FROM STUDENT;

ROWNUM

NAME

SCORE

1

80

2

90

3

87

4

91

우리 눈에는 안보이지만 ROWNUM이 있다.

데이터베이슨 ROWNUM이 있다.

SELECT ROWNUM,NAME,SCORE

FROM STUDENT;

ROWNUM

NAME

SCORE

1

80

2

90

3

87

4

91

우리 눈에 보이지 않는 오라클이 만든 컬럼이다.

번호가 만들어진 원리가 생각보다 쉽지 않다.

 

SELECT ROWNUM,NAME,SCORE

FROM STUDENT;

출력을 할려고 할때 STUDENT하고 WHERE 를 확인한다. WHERE 조건이 없어서 통과한다.

1

80

WHERE 조건 확인

2

90

WHERE 조건 확인하고

3(MAX)

87

WHERE 조건확인하고

4

91

 

 

 

SELECT ROWNUM,NAME,SCORE

FROM STUDENT

WHERE score >= 90

ROWNUM

NAME

SCORE

1

80

2

90

3

87

4

91

 

1번 확인하고 80이여서 출력은 안한다.

데이터가 없어서 다시 1번으로 한다.

1

90

 

2번으로 부터 확인한다.

87 90보다 작아서 못 연다.

번호는     테이블 확인한다.

2

91

출력결과

1

80

2

91

 

 

오라클에서 페이지를 하려고 한다.

페이지 처리시  rownum inline view가 필요하다.

 

select ROWNUM,name,score

from student

where rownum <= 2;

1

80

2

90

 

3 번데이터 확인하고 못들어간다.

그리고 3번으로 student테이블의 4번과 비교한다.

 

select ROWNUM,name,score

from student

where rownum > 2;

데이터가 안나온다.

 

페이지 처리시  sort한다음 처리

 

select rownum,name,score

from student

wehre rownum <= 2

order by score desc; 점수 내림차순

rownum

NAME

SCORE

1

90

2

80

rownum <= 2 먼저하고 order by 한다.

행번호 설정되고 정렬된다.

 

inline view

=>from 절에 사용하는  select구문

select rownum,name,score

from (select * from student order by score desc)

where rownum <= 2

 

1. select * from student order by score desc

점수 정렬한다.

NAME

SCORE

91

90

87

80

2.     rownum

rownum

NAME

SCORE

1

91

2

90

 

rownum <= 할수 있지만 >것은 안된다.

>2를 가져오려면 번호를 한다.

select rownum,name,score

from ( select rownum rnum, name,score

           from (select * from student order by score desc))

where rnum >2;

 

항상 괄호 안에 있는 것이 먼저이다.

1.select * from student order by score desc;

NAME

SCORE

91

90

87

80

2.

select rownum rnum, name,score

           from (select * from student order by score desc)

where 이 없어서 순서데로 한다.

rnum

NAME

SCORE

1

91

2

90

3

87

4

80

rownum where절을 통과하면 되지만 rnum은 행번호가 아니라 컬럼의 값이다.

다음 2개를 뽑아올 수 있는 것이다.

rnum >= 1 and rnum <= 10

rnum >= 11 and rnum <= 20

 

mysql limit사용한다.

mongoDB limit 10이다.

oracle inline view를 이용해야 한다.

 

재일 안쪽에는 무조건 sort하고 바깥에서는 rownum부여하고 밖의 where절에서 이거 가지고 잘라내면 된다.

 

 

3)오라클에서 데이터를 page단위 또는 top-N을 구현할 떄 사용

 

4)구조

select 필요한 컬럼 이름 나열

from (select rownum 별명, 컬럼이름 나열

from (select 필요한 컬럼이름

from 테이블이름 order by 원하는 컬럼으로 정렬))

where 별명을 가지고 페이지 단위 또는 더보기 작성

 

5).실습

=>emp테이블에서 입사일(hiredate)이 가장 늦은 사원 5명의 이름(ename)과 입사일을 가져오기

SELECT *

FROM EMP e

ORDER BY HIREDATE DESC;

--ADAMS,SCOTT,MILLER,FORD,JAMES

 

SELECT ENAME, HIREDATE

FROM (SELECT ROWNUM RNUM, ENAME, HIREDATE

        FROM (SELECT *

               FROM EMP e

               ORDER BY HIREDATE DESC))

WHERE RNUM >= 1 AND RNUM <= 5;

 

top-n paging

inline –view

 

**sequence

=>오라클에 존재하는 일련번호 생성을 위한 개체

=>기본키를 생성하는 것이 애매한 경우 시퀀스를 이용해서 생성하는 경우가 있음

1.생성

create sequence 시퀀스이름

       [start with 시작번호]

       [increment by 간격]

       [maxvalue 최대값 | nomaxvalue]

       [minvalue 최소값 | nominvalue]

       [cycle | nocycle]    

       [cache | nocache]

 

start with 생략하면 관리자 계정에서는 1인데 나머지 계정은 1 아닐 있습니다.

increment by 생략하면 1

maxvalue 생략하면 10 27

minvalue 생략하면 1

cycle 마지막 숫자에 도달하면 처음 숫자로 이동할 여부인 nocycle 지정하면 마지막 숫자 다음에서 오류가 발생하면 cycle 설정하면 primary key 사용할 없습니다.

기본은 nocycle

cache 시퀀스의 값을 메모리에서 관리할 것인지의 여부로 기본은 nocache

실제적으로 start withi increment by 많이 사용하고 다른 것은 사용하지 않는다.

 

2.값사용

시퀀스.nextval:다음 시퀀스

시퀀스.currval:현재 시퀀스 - nextval 번이라도 호출 후에 사용해야 합니다.

 

3.  시퀀스 수정

alter sequence 시퀀스이름

옵션 다시 설정

=>start with 수정할 없습니다.

 

4.시퀀스 삭제

drop sequence 시퀀스 이름

 

5.실습

=>1 부터 1 증가하는 시퀀스 생성

create sequence boardseq

start with 1;

 

=>시퀀스 다음 확인

select boardseq.nextval

from dual;

 

=>현재 시퀀스 확인

select boardseq.currval

from dual;

 

=>시퀀스 삭제

drop sequence boardseq;

 

select boardseq.currval

from dual;->이것 먼저 수행시

--SQL Error [8002] [72000]: ORA-08002: sequence BOARDSEQ.CURRVAL is not yet defined in this session

순서는 boardseq.nextval-> boardseq.currval이다.

 

6.데이터베이스 연동 프로그래밍에서는  sequence대신에 가장 값을 찾아서 +1 하는 경우도 있습니다.

 

 

**index

=>데이터를 빠르게 조회하기 위한 포인터

=>책에서 특정 쳅터를 빠르게 보기 위해서 꽂아놓는 책갈피와 유사

=>데이타베이스 종류에 따라 구현하는 방법은 여러 가지

=>오라클이 사용하는 방식은  b(balance)*트리

=>인덱스를 사용하면 빠르게 조회할 있다는 장점이 있지만 인덱스 만큼 메모리 할당을 해야 하고 삽입이나 삭제 갱신 작업이 발생하면 인덱스 조정으로 인한 속도 저하가 발생할 있습니다.

 

 

데이터가 연속적인 단위

배열 : 크기가 고정

LIST : 크기가 가변

       Linked List :데이터와 다음데이터를 가리키는 포인터를 갖는 자료구조

List ->배열

ArrayList

 

10

30

40

배열은 지운다. 크기가 변경이 안된다 데이터가 연속적으로 저장 되여야 한다.

중간에 30 지우면 배열이 안된다.

 

 

 

 

배열하고 비슷한데  arrayList 비여있다.grow ,shirink한다.

ArrayList 연속적으로 사용하고 땡기고 밀어여고 하는 구조여서 중간에 데이터가 삭제되면 문제가 생겨서 Linked List이다.

 

특징알고 장단점은 알아야 한다.

arrayList ->stack lifo

          ->queue 자판기 fifo 문류 먼저 들어간것이 먼저 들어간다.

          ->deque 양쪽으로 들어오고 나가는 지도 위으로도 가고 아래로도 간다.

 

Linked List ->

data

 다음 데이터 위치

10,40,30

 

 

head

 다음 데이터 위치 3000번지

 

3000번지

10

 700번지

 

700번지

40

 290번지

 

290번지

30

 

 

 

읽어오는 속도가 늦다. head부터 해서 다음 위치 가르키는

삽입과 삭제가 강하다.

 

ArrayList

10

40

30

40 상제하면

10

30

가끔식 삭제 하면 괜찮은데 많이 사용하면 문제가 많다.

 

Linked List

40지워지면

10

 700번지

700번지는 연결이 안되였다. 포인터가 삭제된다.복구 것을 위하여

파일 삭제하면 삭제되는 것이 아니라 휴지통으로 간다.

포인터들만 지운다.

 

10g 1

100m 50 5 g 지우면

개수가 많는게 오래 걸린다. 진짜로 지우는 것이 아니라 포인터 지우는데 오래 걸린다.

 

한쪽으로 연결하면 끊어지면 연결이 안되서

doubleLinkedList

point 2 있다.앞에 뒤에 끊어져도 반대편에 있다.

python list doubleLinkedList이다. reverse기능

 

 

 

 

 

 

 

포인트 앞뒤에 있다.

python lib 대다수 c java이다.

 

트리는 부모자식의 관계가 있다.

파일시스템 ->트리

부모는 첫번째 자식 밖에 가르킨다.

위에서 아래로

balance

b트리:포인터의 1/2이상 채워진 트리

b*트리: 포인터의 2/3이상 채워진 트리

 

100,300,70,40

 

 

 

문제가 경우 출발점 70으로 되여있다. 70을삭제시 트리를 다시 만들어야 한다.index조정 작업 필요

 

 

60추가시 쪼개야 한다. 분할 작업 진행 필요

index 빨리 조회되지만 삽입,삭제,갱신 작업이 늦을 수있다.

mysql 설정을 한다.

읽기만하면 index구조

삽입,삭제,갱신 index사용하면 늦어지고 버벅거린다.

적절한 자료구조 선택해야 한다.

python 배열이나 arraylist 없다.

 

 

1.  인덱스 생성

create index 인덱스이름

on 테이블이름(컬럼이름);

 

2.  인덱스 제거

drop index 인덱스이름;

 

=>blob clob 인덱스 설정을 없습니다.(데이터가 크서 안한다.)

 

3.  인덱스를 생성해야 하는 경우

=>행의 개수가 너무 많을

=>특정 열이 where절에서 자주 사용될

=>null 많은

=>join 자주 사용되는

=>검색할 전체 데이터의 2~4%정도 검색할

 

4.  인덱스를 생성하면 안되는 경우

=>행의 개수가 너무 적을

=>삽입,삭제,갱신 작업이 빈번히 발생할

=>검색 결과가 전체 데이터의 10%이상

 

 

5.  primary key unique속성을 설정하면 자동으로 인덱스가 생성됩니다.

 

 

 

**동의어(synonym)

=>데이터베이스 개체에 별명을 부여하는

1.생성

create synonym 별명

for 원래이름

 

2.삭제

drop sysnonym 별명;

 

=>데이터베이스를 프로그래밍 언어와 연동할 별명을 사용하면 유지보수가 편합니다.

emp -   데이터베이스

 

python 개발자 한테 테이블 이름 으로 개발한다. emp

emp 함부로 바꾼다.

emp바꿀시 화면에서도 바꿔야 한다

 

create synonym e

for emp;

 

구조가 바꾸지 않았더라면 이름 바꾸는데 편해진다.

 

유지보수 편하게 하려면 항상 별명을 하는게 좋다.

 

 

**stored procesure

=>자주 사용하는 sql구문을 프로그래밍 언어의 함수처러 하나의 이름으로 만들어 두고 이름을 이용해서 sql구문을 실행하는

 

1.  장점

=>sql구문을 실행하는 보다는 실행 속도가 빠르고 보안이 유지

 

2.  생성

create [or replace] procedure 프로시저이름(매개변수이름 [mode] 자료형 , ...)

is

지역변수

begin

    수행할 sql 구문

end;

/

 

=>dbeaver에서는 마지막 슬래시를 제외해야 합니다.

=> or replace 있는 경우 수정할 사용

=> mode in,out 그리고 생략도 가능

in이면 입력받는 매개변수이고  out이면 출력을 위한 매개변수

=>자료형을 작성할 때는 직접 자료형을 작성해도 되지만 테이블이름.열이름%TYPE으로 다른 열의 자료형을 이용해도 됩니다.

=>주의할 점은 sql 작성할 때도 마지막에 ; 해주어야 합니다.

 

 

3.  프로시저 호출

1)  sqlplus : execute프로시저이름(매개변수);

2)  dbeaver, sqldeveloper:

begin

       프로시저이름(매개변수);

end;

 

4.  프로시저를 만드는 문법은 관계형 데이터베이스 종류마다 다름

오라클의 프로시저 만드는 문법을 pl/sql이라고 합니다.

pl/sql ->오라클의 프로시저 사용가능 하는

 

5.  프로시저 삭제

drop procedure 프로시저 이름;

 

6.  실습

=>deptno,dname,loc 입력받아서 dept테이블에 데이터를 삽입하는 프로시저를 만들고 호출

1)프로시저 생성

create or replace procedure insert_dept(

       vdeptno dept.deptno%type, ,--여기 변수명은 DEPTNO이면 안된다.입력시 문제 생긴다. vdeptno

 

       vdname dept.dname%type,

       vloc dept.loc%type)

is

begin

       insert into dept(deptno,dname,loc)

       VALUES (vdeptno,vdname,vloc);

END;

/(DBeaver 아닌 경우는 /까지)

 

2.프로시저 실행

BEGIN insert_dept(22,'총무','수원');END;

 

3.확인 하는 것은

SELECT *

FROM dept ;

 

 

**트리거

=>테이블에 데이터를 삽입,삭제 ,갱신할 작업 전후에 다른 작업을 수행하도록 하는 개체

=>작업 전에 수행하는 동작은 유효성을 검사해서 유효성 검사에 실패하면 작업을 수행하지 않기 위해서 이고 작업 후에 수행하는 동작은 작업을 하고 다른 작업을 연쇄적으로 실행하기 위해서 입니다.

=>프로그래밍에서는 이와 유사한 개념으로 필터와 AOP 있습니다.

데이터 작업을 수행하고 로그를 기록해야 하는 경우

실제 수행해야 작업을 비지니스 로직이라고 하고 로그를 기록하는 것처럼 실제 작업은 아닌데 별도로 해야 하는 작업을 공통 관심 사항이라고 합니다.

비지니스 로직의 수행이 끝나고 공통 관심 사항을 실행하도록 일반 코드로 작성하게 되면

-비지니스 로직 수행

-공통 관심 사항 수행

 

데이터베이스에서는 트리거를 이용해서 비지니스로직을 수행하면 공통 관심 사항이 자동으로 수행되록 해서 비지니스 로직을 담당하는 개발자는 비지니스 로직 개발에만 집중하도록 합니다.

 

 

 

업무 -> 관리

순차적으로 작성 경우 업무를 하면 관리가 보인다.

업무를 담당할 경우에는 업무만 관련된 것만 만들고

관리하는 분은 업무와 관리를 합치는 것을 만든다.자동으로 붙인다.이것을 aop라고 한다.

카드업무 -> 관리

카드업무 만들고

관리 만들고

관리 경우 카드업무 수행해야 작업이 가능할 현상이 생긴다.

이럴 경우 문제가 생겨서

 

카드업무하고 관리를 따로 따로 하고 후에 설정을 한다.

유지보수 차원에서 편하다.

 

 

 

 

 

 

 

 

 

 

sqllite에서는 외래키를 설정하고 on delete cascade옵션을 설정해도 부모테이블에서 데이터가 삭제될 자식 테이블에서 데이터가 연쇄적으로 삭제되지를 않습니다.

이런 경우에도 트리거를 이용하면 부모 테이블에서 데이터가 삭제될 자식 테이블에서 자동으로 삭제되도록 구현할 있습니다.

 

1.생성

create or replace trigger 트리거이름

[before| after] [insert|update|delete] on 테이블이름

[for each row]

[when 조건]

begin

수행할 내용

end;

 

=>for each row 여러 개의 행에 update,delete,insert 발생할 반드시 트리거를 여러 수행하고자 사용하는 옵션으로 생략하면 여러 개의 행에 작업이 발생해도 트리거는 번만 동작

=>when 조건을 설정해서 조건에 맞는 경우에만 수행하도록 있고 수행하지 않도록 수도 있습니다.

:old.컬럼이름,:new.컬럼이름 사용할 있는데 앞에 old 붙으면 이전 데이터인데 delete 삭제되는 데이터의 값이고 update에서 변경되기 전의 값입니다.

insert에서는 old 사용 못합

new 새로 대입되는 값으로 update insert에서 사용할 있습니다.

 

=>수행할 내용 자리에

raise_application_error(에러코드번호,메시지);

입력하면 작업을 수행하지 않고 에러 메시지를 출력합니다.

 

when 정기정검시간인지 확인

raise_application_error(에러코드번호,메시지);

 

포인터가 0보다 작으면 여기에 에러코드한다.

관리자가 되면 트리거를 사용

 

로그인 마지막 날짜 업데이트 트리거 가지고 한다.

작업을 못하게 하는 등은 트리거 가지고 한다.

 

반응형

'Study > DB' 카테고리의 다른 글

DB-6  (0) 2020.09.18
DB-5  (0) 2020.09.17
DB-3  (0) 2020.09.15
DB-2  (0) 2020.09.13
DB-1  (0) 2020.09.13
반응형

데이터베이스설계

 

oracle

mysql

Access->가르쳐주기 쉽다.

논리적설계: 개념적설계에서만들어진구조를실제DBMS에맞도록스키마를설계하는단 계로보통이단계에서정규화

물리적설계: 데이터베이스의물리적구조와접근방법을설계

물리는 구조를 만들겠다.

예전에는 구현을 코딩 한다=>최근에는 코딩

프로그램 record

데이터베이스에서는 relation이나 관계

개체가 table

속성

기본키 잴 안좋은 것은 일련번호 ->구별 밖에 못한다.

 

숫자그림 minist

유도속성: 다른속성으로부터유도되어지는값(나이생년월일을알면나이는계산이가 능)

NULL: 아직알려지지않은속성

 

 

설계명세서

 

python자료혀 2가리로 나눈다.

스칼라 여러개 만들 수 있다. 정수

컬렉션 리스트 , tuple,set, dict  class

class 사용자 정의

 

byte

한글이10자리면 10*3

2000byte까지 밖에 못쓴다.

number 최고 38

number(5) 숫자 5자리

number(5,2) 숫자 5자리 까지고 소수점은 2자리 까지

rowid는 저장도 만들지도 못한다.

lob가 중요해지고 있다. 파일의내용 ,음성데이터 , 이미지 등

 

lob large object binary

=>바이트 배열을 저장하기 위한 자료형

=>일반적으로 파일의 내용을 저장

bit :0 1 둘중에 하나 저정 컴퓨터에서 데이터를 저장하는 최소단위

  컴퓨터는 bit단위로 저장을 못한다. 컴퓨터는 볼 수 있다.

byte : 8bit 컴퓨터의 저장단위

           A  B C ->BIT로 저장 못한다.

           2 7 bit  128->asc ii

0 5자리 ->대문자

1 5자리 ->소문자

코드는 분류까지 하면 좋다.

짝수는 반 쪼갤수 있어서 안정적이겠다.해서 8

한글은 완성형 데이터 자음 , 모음 ,받침 문법적으로 구분이 불가하다.

쓴과 동시에 입력이 안된다.

한글은 더 많은 byte가 필요하다.

위에것은 물리적 단위이다.

word는 운영체제 또는 hw가 한번에 데이터를 움직이는 단위

32bit / 64bit단위로 움직이겠다. 이것이 word

32bit  x86 64bit에 깔린다.

64bit 32bit에 안된다.

kb

mb

gb

tb

 

 

img.png 10m

->파일 파일의 이름을 db에 저장소

                       용량이 조금 밖에 안된다.

                       데이터베이스의 용량을 줄일 수 있다.

단점 : 파일의 용량이 현재 컴퓨터의 용량을 넘었을때 위치 옮기면 이름을 다 바꿔야 한다.

확장면에서 단점이 있다.

        ->파일의 내용을 저장(lob)

이사갈때 들고 가면 된다. 이름 바꿀 필요 없다.

확장이나 할경우 좋다.

데이터웨어하우스 ->빅데이터 ->용량

è  velocity

blob, clob ->인덱스 설정이 안된다 빨리 조회할 수 없다.

blob ->파일의 내용을 저장

clog->많은 양의 텍스트 저장

 

 

char & varchar2

char ->고정

varchar2 ->가변

char(10) –영문 10글자 까지 저장

장점:

varchar2(10) 10자까지 가능하다. ->공간 절약한다.

데이터가 변경 가능하다면

hi ->hello

varchar2일 경우 공간확보 다시 해야 한다.

여분의 공간이 없을 경우 옮겨야 한다.

공간측면에서

뒤에 빈칸이 없어서 행이 이사를 가야 한다.  row migration

내가 주로 하는 작업이 read 이나 insert,update, delete

분석은 read가 많다. ->varchar2  :id

일반 응용프로그램은 insert,update, delete ->char ->item , level

오버헤드(overhead) 어떤 처리를 하기 위해 들어가는 간접적인 처리 시간 · 메모리 등을 말한다.

trim을 무조건 생각해야 한다.

문자비교 : 앞뒤  공백

             대소문자

테이블 생성

create table 테이블이름(

           열 이름 자료형,

           열 이름 자료형,....)

문자열 – char(크기-고정), varchar2(크기-가변),clob-많은 문자열:1000자 이상

변경이 자주 일어나는 문자열은 char

변경이 거의 없으면 varchar2

 

숫자 –number(자릿수 ,소수 자릿수) : 소수 자릿수를 생략하면 정수만 입력가능

날짜및 시간 –date

 

파일의 내용 –blob

 

 

=:>회원정보 테이블

테이블 이름 – member

저장할 데이터:

이메일  변하지 않는 100varchar2(100)

이름 :변하지 않는 문자열 한글 10자 이내 varchar2(30)

비밀번호 자주 변하는 문자열 영문과 숫자 15자 이내 char(15)

나이 정수 3자리 이내 number(3)

회원가입일 날짜

마지막 로그인 날짜 날짜

 

**기존 테이블을 가지고 테이블 만들기

CREATE TABLE 테이블이름

AS

SELECT 구문:

 

=>select 구문의 결과를 가지고 테이블을 생성

=>구조만 복사하고자 하는 경우에는 절대 true 나올 없는 조건을 select where절에 대입하면 됩니다.

login 만들떄 주의

 

1.  emp테이블의 모든 내용을 복사해서 새로운 테이블을 생성

=>emp01테이블

CREATE TABLE EMP01

AS

SELECT *

FROM EMP e;

 

=>확인

SELECT *

FROM EMP01;

 

 

2.     emp테이블의 구조만 복사해서 테이블을 생성

=>emp02

CREATE TABLE EMP02

AS

SELECT *

FROM EMP e

WHERE 0 = 1;

 

=>확인

SELECT *

FROM EMP02;

 

1=1이다. 무조건 참이다.

아이디와 비밀번호 참이여야 한다.

SELECT *

FROM MEMBER

WHERE ID = ?

AND PW = ?

ID 없다.

비밀번호는 X

거짓이다. OR 1=1

SELECT *

FROM MEMBER

WHERE ID = ?

AND PW = ? OR 1=1         =>TRUE

OR 하나 TRUE이라도 TRUE 된다.

 

=>로그인을 구현할 떄는 id 가지고 비밀번호를 가져와서 다시 비교하도록 만들거나 아이디와 비밀번호를 입력할 sql 예약어를 사용하지 못하도록 해야 합니다.

 

select *

from member

where id = ?

 

프로그램에서 비밀번호를 비교

 

 

**테이블 수정

1.열을 추가

=>열을 추가하거나 열을 변경하거나 삭제하는 작업

alter table 테이블이름

add(열이름 자료형);

=>emp02 테이블에 전화번호 열을 추기

전화번호는 문자 1자리 자주 변경될 것 같은데 자릿수는 변화가 없습니다.

=>자리수 변화가 없을떄 varchar2해도 문제 없다.

alter table emp02

add(phone varchar2(11));

 

2.열 수정

alter table 테이블 이름

modify(열 이름 자료형):

=>자료형 자체를 변경하거나 길이를 줄이는 것은 고려해봐야 할 내용이 있습니다.

기존데이터가 소멸 될 수 있기 때문입니다.

emp02테이블에서 phone컬럼의 자료형을 varchar2(12)로 변경

작게는 할 때 조심해야 한다. 크게 하는 것이 좋다.

alter table emp02

modify (phone varchar2(12));

 

=>확인

SELECT *

FROM EMP02;

 

 

3. 삭제

alter table 테이블이름

drop column 열이름:

=>살제는 실패 경우가 있다. 열이름을 정확하게 입력했는데 삭제되지 않는 경우는 다른 테이블에서 열을 참조하는 경우입니다.

이를 때는 자식 테이블의 데이터를 삭제하고 삭제해야 합니다.

:외래키

 

=>emp02테이블의 phone 열을 삭제

alter table emp02

drop column phone;

 

=>확인

SELECT *

FROM EMP02;

 

3.  set unused

=>데이터베이스 테이블은 구조를 변경하거나 삭제할 그리고 데이터를 추가하거나 갱신 또는 제거할 lock 걸고 수행합니다.

lock 걸려 있으면 select 제외한 다른 작업은 수행 없습니다.

 

=>대량의 데이터가 저장된 상태에서 열을 삭제 하게 되면 열이 전부 삭제 될때 까지 lock 걸려서 다른 작업을 못하게 합니다.

 

=>열을 삭제할 바로 삭제하는 것이 아니고 사용을 못하게 시간 여유가 삭제하는 것이 효율적입니다.

alter table 테이블이름

set unused(열이름):

 

명령을 수행하게 되면 열을 사용 못함

alter table 테이블이름

drop unused columns;

 

명령으로 사용 금지 열을 삭제합니다.

 

 

4.  테이블을 제거

drop table 테이블이름:

=>테이블이 존재하는데 명령이 실패하는 경우는 중에 하나 이상을 테이블을 참조하는 경우 입니다.

 

 

=>emp테이블 제거

drop table emp02;

 

=>확인

SELECT *

FROM EMP02;

테이블이 존재하지 않는다고 에러가 발생

# ORA-00942: table or view does not exist

 

 

**테이블의 데이터만 삭제

truncate table 테이블이름;

=>개발을 종료하고 서비스 하기 전에 배포할 주로 이용

 

 

**테이블의 이름 변경

rename 예전이름 to 새로운이름;

 

 

**ddl(data definition language)

=>데이터 구조에 관련된 명령어

=>create, alter, drop , truncate, rename

 

**dml(데이터 조작 언어 작업의 단위가 테이블이 아니고 테이블 안의 데이터)

data manipulation language

=>데이터 삽입,갱신,삭제하는 명령어

 

1. 데이터 삽입

insert into 테이블이름( 이름 나열)

values( 이름에 해당하는 데이터 나열);

 

=> 개수에 맞게 데이터를 나열해야 하고 자료형도 일치해야 합니다.

values 앞에 공백이 있어야 합니다.

바꾸기 경우 공백을 조심해야 한다. sql예약어는 공백 하나씩 여야 한다.

옆으로 한줄 쓰면 된다.

 

=>dept테이블에 deptno 99이고 dname 비서 loc 서울인 데이터를 삽입

INSERT INTO DEPT(deptno,DNAME,LOC)

values(99,'비서','서울');

 

=>sql 다른 editor 작성한 복사를 때는 작은 따옴표는 확인

power poin 같은 프로그램에서의 다른 형태로 만들어져서 에러가 발생할 있습니다.

INSERT INTO DEPT(deptno,DNAME,LOC)

values(99,'비서','서울');

 

COMMIT;

 

SELECT *

FROM DEPT d;

 

--loc컬럼의 길이는 13인데 한글 5글자를 입력해서 15byte 되서 삽입 실패

INSERT INTO DEPT(deptno,DNAME,LOC)

values(99,'비서','서울특별시');

 ORA-12899: value too large for column "SCOTT"."DEPT"."LOC" (actual: 15, maximum: 13)

 

 

=>데이터를 삽입할 컬럼 이름 생략 가능

데이블의 구조에 맞게 모든 데이터를 순서대로 전부 입력하는 경우에만 가능

 

 

insert into dept

values(88,'총무','마산');

 

 

=>null삽입

명시적으로 값을 null이라고 설정해도 되고 기본값이 설정되지 않은 컬럼은 생략하고 대입

insert into dept

values(87,'영업',null);

 

insert into dept(deptno,dname)

values(86,'회계');

=> 경우에는 loc 기본값이 설정되지 않은 경우에 null 대입되고 기본값이 설정되어 있으면 기본값이 대입됩니다.

 

조회한 결과(select구분의 결과) 삽입 가능

insert into 테이블이름(컬럼 이름 나열)

select 구문 ;

=>select구문의 결과와 컬럼 이름들이 자료형이 일치하고 개수가 같으면 조회한 결과가 삽입

 

실습을 위해서  dept테이블의 구조를 그대로 같는  dept01 테이블을 생성

 

dept테이블에서 deptno 50이상인 데이터만 dept01 복사

 

INSERT INTO dept01

SELECT *

FROM DEPT d

WHERE deptno >= 50;

 

COMMIT;

 

 

=>확인

SELECT *

FROM DEPT01;

 

=>하나의 테이블에서 조회한 내용을 2 이상의 테이블에 삽입 가능

조회한 내용의 이름과 삽입하고자 하는 테이블의 이름이 일치해야만 가능

insert all

insert into 테이블이름(컬럼이름 나열)

insert into 테이블이름(컬럼이름 나열)

---

select 구문

 

2.데이터 수정

update 테이블이름

set 수정할 이름 = 수정할 내용

[where 조건]

=>where 절은 생략 있는데 생략되면 테이블의 모든 데이터가 수정됩니다.

=>삽입과 다르게 수정이나 삭제는 문법적으로 이상이 없는데도 1개도 수정되거나 삭제되지 않을 있습니다.

삽입은 데이터에 생기지 변화가 생기지 않는다면 실패

수정이나 삭제는 where절이 있기 때문에 조건에 맞는 데이터가 1개도 없으면 수정이나 삭제는 수행되지 않습니다.

select :데이터가 리턴 ->fetched

select 이외 :영향받은 행의 개수 리턴 ->1 row 영향받은 행의 개수

0 실패가 아니고 조건에 맞다.

insert 1이상이야 성공

delete,update 0 이상이여야 성공

 

#DEPTNO테이블에서 DEPTNO 88이상인 데이터만 DEPTNO값을 1증가

 

=>set절에 여러개의 컬럼의 값을 수정하는 것이 가능

, 구분해서 여러개 설정

dept01테이블에서 deptno 86 데이터의 dname SI loc 홍대로 변경

UPDATE DEPT01

set dname = 'SI', LOC = '홍대'

WHERE DEPTNO = 86;

 

 

 

3. 데이터 삭제

DELETE FROM 테이블이름

[WHERE 조건]

ð  데이터베이스 종류에 따라 FROM 생략

ð  조건이 없으면 테이블의 모든 데이터를 삭제

ð  조건에 맞는 데이터가 있는데도 삭제가 안되는 경우가 있는데 다른 테이블에서 데이터를 참조하는 경우입니다.

=> dept01테이블에서 deptno 40이상인 데이터만 삭제

DELETE FROM dept01

WHERE deptno >= 40;

 

 

 

**테이블 merge

=>2개의 테이블의 데이터를 비교해서 없는 데이터는 추가하고 존재하는 데이터는 갱신하는 작업

=>코드 관리 사이트 등을 만들 기존 데이터를 업데이트 하는 용도로 사용

MERGE INTO 기본 테이블 이름

USING 업데이트 데이터를 가진 테이블 이름

ON(어떤 값이 같으면 동일한 데이터로 취급할 것인지 조건을 기술)

WHEN MATCHED THEN

UPDATE SET

기본테이블의 컬럼 이름 = 업데이트 데이터의 테이블이름.컬럼이름,

업데이트 컬럼 동일한 방식으로 나열 

WHEN NOT MATCHED THEN

INSERT VALUES(업데이트 데이터를 가진 테이블 이름.컬럼이름.......)

 

detp01테이블에서 dept테이블에 작성된 데이터를 업데이트

존재하지 않는 데이터는 추가

 

MERGE INTO DEPT01

USING DEPT

ON (DEPT01.DEPTNO = DEPT.DEPTNO)

WHEN MATCHED THEN

UPDATE SET

DEPT01.DNAME = DEPT.DNAME,

DEPT01.LOC = DEPT.LOC

WHEN NOT MATCHED THEN

INSERT VALUES(DEPT.DEPTNO, DEPT.DNAME, DEPT.LOC);

 

덮어서 넣는것을  dump한다.

최신의 것을 업데이트 하고 갱신할

 

 

**tcl(transaction control language –트랜잭션 제어어

=>실무에서는 별도로 구분하는데 데이터베이스 이론에서는 dcl 분류

=>tcl에서는 제어어이기는 하지만 개발자가 주로 사용하기 때문에 별도로 구분

=>이와 비슷한 형태로 이론에서는 insert,delete, update,select dml 분류하지만 실무에서는 insert,delete, update dml그리고  select dql 분류합니다.

dml 데이블에 변화를 가져오지만 select 변화를 가져오지 않습니다.

 

=>transaction:한번에 이루어져야 하는 작업의 논리적인 단위

억지로 번역하면 거래 정도 된다.

1.  트랜잭션의 가져야 하는 성질:ACIT

NO-SQL 것이 거의 없다. 느슨한 TRANSACTION이다.

1)Atomicity(원자성): all or nothing –전부 아니면 전무

2)consistency(일관성): 트랜잭션은 일관성이 있어야 한다.

3).isolation(격리성,독립성):트랜잭션은 독립적으로 수행되어야 한다.다른 트랜잭션의 영향을 받으면 안된다.

4)durability(영속성 ,지속성): 완료된 트랜잭션은 계속되어야 한다. 완료되면 다시 수행하면 안된다.

 

2.  2명의 유저가 있는데 명이 유저의 아이템을 다른 유저가 구매할려고 합니다.

데이터베이스는 4가지 동작이 발생

판매할려고 하는 유저의 금액이 늘어나야 합니다.

판매할려고 하는 유저의 아이템이 소멸되어야 합니다.

구매할려고 하는 유저의 금액이 감소해야 합니다.

구매할려고 하는 유저의 아이템이 추가되어야 합니다.

 

4개의 작업 도중 중간에 장애가 발생하면 어떻게 ?

 

늘어나는 부분을 먼저 한다.

 

3.  트랜잭션 처리 방법

1)  manual commit

==>직접 commt rollback 수행

 2)auto commit

=>하나의 sql문장이 성공하면 자동으로 commit

=>자바나 dbeaver auto commit

4. 트랜잭션 작업 종류

1)commit: 작업이 완료되서 변경된 데이터가 원본 데이터에 반영

2)rollback:변경된 데이터를 삭제 ,원본 데이터에 변경된 내용이 반영이 안됨

3)savepoint:많은 양의 작업을 번에 commit하거나 rollback하면 시스템에 문제가 발생할 있어서 중간 중간 rollback 있는 위치

5. 트랜잭션이 생성

==>새로운 트랜잭션이 없는 상태에서 insert,delete,update 수행해서 성공하면 생성

 

6.  트랜잭션이 완료되서 소멸

==>명시적으로 commit 호출한 경우나 시스템이나 접속도구가 정상 종료된 경우 ddl(create,alter,drop , truncate, rename)이나 dcl(grant,revoke) 정상적으로 수행한 경우는 트랜잭션이 commit되고 소멸됩니다.

==>rollback 호출하거나 시스템이나 접속도구 비정상 종료되면 rollback되고 트랜잭션은 소멸됩니다.

==>rollback to savepoint이름을 입력하면 savepoin이름을 생성한 자리로 rollback됩니다.

 

 

7.  dbeaver 이용해서 실습을 때는 auto commit 해제하고 수행해야 합니다.

toad무료 버전을 사용하면 savepoint 1개만 생성 가능

 

8.  nosql 일반적을 트랜잭션의 개념이 없는 auto commit 형태

 

실습

=>dept테이블의 모든 내용을 복사해서 deptcopy 테이블을 생성

CREATE TABLE deptcopy

AS

SELECT *

FROM dept;

 

=>테이블 생성 확인

SELECT *

FROM deptcopy;

 

 

==>deptcopy테이블의 데이터를 전부 삭제

delete from deptcopy;

 

=> 테이터 확인

SELECT *

FROM deptcopy;

 

 

=>트랜잭션 취소

ROLLBACK;

 

=>테이터 확인

SELECT *

FROM deptcopy;

 

=>deptno 10번인 데이터를 deptcopy테이블에서 삭제

DELETE FROM DEPTCOPY WHERE deptno = 10;

 

=>트랜잭션을 commit하고 완료

commit; -- 이상 복원할 없다.끝났다.

 

=>작업취소인 rollback 수행

rollback;

 

=>테이터 확인

SELECT *

FROM deptcopy;

 

rollback;->copy테이블 복사본의 없앤다.

select *

from deptcopy;

 

commit

하면 copy 있는 것을 deptcopy 덤프하고 완료하면 복사본 버린다.

select *

from deptcopy;

 

 

create, alter, drop, grant, revoke ->성공하면 ->commit;

관리자의 권한으로 생각해서 성공하면 그때 까지 작업은 commit된다고 생각한다.

 

insert,update,delete create, alter, drop, grant, revoke같이 하면 안된다. 일괄 commit되기 때문에

재접속 하는 것은 commit하기 위해서 이다.

commit하지 않으면 제대로 반응이 안되서 이다.

 

savepoint설정해서 rollback to s1

savepoint중간중간에 포인트를 잡고 싶고 데이터가 많을 경우

java ,python등으로 savepoint한다.

 

트랜잭션은 서비스 쪽에서 여러개 sql묶어서 만드는 경우가 많다.

어떤 서비스에 건다.

 

 

**save point   auto commit

=>실습을 위해서  emp테이블의 모든 데이터를 가지고 있는 empcopy테이블을 생성

create table empcopy

as

select *

from emp;

 

=>테이블이 제대로 생성되고 데이터가 어떤 것들이 있는지 확인

select *

from empcopy;

 

--empno 7369 데이터를 empcopy테이블에서 삭제

DELETE FROM EMPCOPY

WHERE empno = '7369';

 

--emp테이블의 데이터를 복사해서 empcopy1이라는 테이블을 생성

create table empcopy1

as

select *

from emp;

 

--이전에 데이터 삭제 구문을 잘못 같아서 rollback 수행

ROLLBACK;

 

 commit 했는데도 불구하고 create 해서 자동 커밋됬다.

=>create 구문을 수행해서 commit 수행합니다.

삭제된 데이터가 복원되지 않습니다.

 

 

=>create, alter, drop, grant, revoke 성공적으로 수행하면 자동으로 commit됩니다.

insert,delete,update 수행하는 애플리케이션과 ddl또는 dcl 수행하는 애플리케이션을 하나로 만들지는 않는 것을 권장합니다.

 

=>데이터를 조작하는 애플리케이션에서 commit이나 rollback만을 사용하게 되면 거래 별로 commit 하게 되면 commit 너무 자주 수행해서 데이터베이스 성능을 떨어뜨리게 되고 마지막에 한번만 commit하는 형태로 만들면 거래가 잘못 경우 rollback해야 하는 거래가 너무 많아집니다.

MMORPG서버나 금융 거래 서버는 1초에도 수십번의 거래가 이루어집니다.

경우 잘못되서 ROLLBACK 하게 되면 너무 많은 거래가 취소됩니다.

이런 경우에는 일정한 시간 또는 거래의 개수만다 ROLLBACK 있는 지점을 생성할 있습니다.

ROLLBACK 있는 지점을 SAVEPOINT라고 합니다.

중간에 SAVEPOINT 이름; 삽입하면 SAVEPOINT 만들어 집니다.

SAVEPOINT ROLLBACK 때는 ROLLBACK TO 이름;으로 합니다.

 

==>empcopy테이블에서 empno 7499 데이터를 삭제

DELETE FROM EMPCOPY

WHERE empno = '7499';

 

--SAVEPOINT 생성

SAVEPOINT s1;

 

--empcopy테이블에서 empno 7521 데이터의  ename 태연으로 수정

UPDATE EMPCOPY

SET ename = '태연'

WHERE empno = 7521;

 

--SAVEPOINT 생성

SAVEPOINT s2;

 

--empcopy테이블에서 empno 7788 데이터를 삭제

DELETE FROM EMPCOPY

WHERE empno = 7788;

 

--empcopy테이블의 현재 상태를 확인

SELECT * FROM EMPCOPY;

 

=>현재 상태가  데이터가 11 7521데이터의 ename 태연으로 설정

 

ROLLBACK TO s2;

-- 명령을 수행하게 되면 s2 만든 위치로 데이터를 되돌립니다.

--empno 7788 데이터가 복구

SELECT *

FROM EMPCOPY;

 

 

ROLLBACK TO s1;

-- 명령을 수행한 위치로 데이터를 되돌립니다.

-- 후에 만든 savepoint 모두 소멸됩니다. s2 s1후에 만들어서 s2 안된다.

--rollback to s2;-> 명령은 에러가 된다.

--SAVEPOINT신중해서 해야 한다.

rollback to s2;--ORA-01086: savepoint 'S2' never established in this session or is invalid

 

프로그램에서의 session 접속하면 session 생긴다.

 

개발자:select->insert,delete,update->commit,rollback->create,alter,drop

운영자 관리자:create,alter,drop ->grant,revoke->commit,rollback->insert,delete,update,select

dba system운영자는 봐야 한다.

분석가:select

 

plsql 오라클에서 사용한다.

관계형에서는 create할때 자료형이 다르다.

sqllite char, text ->용도 : 서버구축은 안한다.

       서버에 데이터가 있고

                 임시정보 저장(실데이터가 아니라 )

       device(browser,smartphone)

앱에다 sqllite 저장하다가 지움은 날아간다.

item사면 임시데이터를 device 저장한다.

서버 갔다왔다하면 트래픽생겨서 줄이기 위해서 sqllite 저장한다.

대표적인 것은 : 메일 이다.

에서  접속하면 댕길떄 변경된 것만 가져온다.

iot 이런것은 sqllite하면 된다.

센서가지고 데이터 수집을 sqllite 사용

용도가 넓어진다.

추세가 데이터가 발생한 곳에서 분석하자.

처리방식이나 구현 방식에서 문제가 있다.

서버에서 하면 보안문제가 있다.

데이터 넣고 뺴는 조회등은 되는데

옵션 선택하는 것은 안된다.

sqllite 복잡한 기능은 가지고 있지 않다.

반응형

'Study > DB' 카테고리의 다른 글

DB-6  (0) 2020.09.18
DB-5  (0) 2020.09.17
DB-4  (0) 2020.09.15
DB-2  (0) 2020.09.13
DB-1  (0) 2020.09.13
반응형

데어터저장소 repository

db가 아니다.

저장소가 repository

repository에 접근하는 데이타 접근서버 별도로 통신

데이타 접근서버 framework 이용(hibernate, mybatis)

application서버

현대자동차는 hana db로 한다.읽기 위해서 특화된 것이다.

속도와 트래픽 문제

데이터를 던져줘서 마음데로 해

데이터 분석이 많이 필요하다.

web platform

socket통신은 프로그램을 깔아야 한다.

web으로 구현하면 browser로 접속 가능하다.

substr 은 글자 단위로 하고

substrb byte단위로 한다.

한글  1글자 -> 2byte 혹은 3byte

사용하지 않을 경우 끄기

listener 외부에서 접근 못하게

localhost는 끄도 안끄도 상관없다.

192.이런식으로 할떄는 listener크고 방화벽 끄야 한다.

나가는 것 제외 proxy

밖에서 들어오는 것 제외  firewall

git 은 가능하는뎅 pip는 안된다.

tibero에서도 listener사용한다.

mysql에서도 service있고 listener열어야 한다.

 

오라클 구동확인

서비스에서 oracle service? 가 실행 중인지 확인:오라클 서버 구동 여부

listener가 실행 중인 지 확인:오라클을 외부에서 접속할 수 있도록 해주는 서비스

 

** 데이터베이스 접속 정보

1.     데이터베이스 종류

2.     데이터베이스 서버 url

3.     계정

4.     비밀번호

=>경우에 따라 3,4번은 없어도 되는 경우가 있습니다.

1521,8890

sid는 이름이고  xe

                       enterprise -> orcl

service name

 

오라클의 단일행 함수

substr 보고 판단하기

프로그램 언어마다 다 다르다.

substr:문자열에서 원하는 위치부터 원하는 글자 수만 큼 추출해주는 함수

SELECT SUBSTR('안녕하세요',2,4)

FROM DUAL;--녕하세요

 

--한글을 SUBSTRB 사용안한다.

SELECT SUBSTRB('안녕하세요',2,4)

FROM DUAL;--

--4번째 바이트 부터 3바이트 가져오기

SELECT SUBSTRB('안녕하세요',4,3)

FROM DUAL;--

영어는 결과가 같다.

--instr->index문자열에서 특정 문자열을 찾아주는 함수

 instr( 문자열,검색할 문자열,시작위치,몇번째)

시작위치는 생략하면 1

몇번째는 생략하면 1

null일 경우 한번 해보기

--문자열 위치 조회

SELECT instr('Hello Oracle','Hello')

FROM DUAL;--1

 

SELECT instr('Hello Oracle','Hi')

FROM DUAL;--0

--프로그래밍에서는  없으면 -1이다. -1 최대이다. 끝까지 가봤는데 없더라

--oralce 0이다. 0 의미 없는 값이다. 없으면 0이다.

 

--python문자열 함수 확인하여야

--slice

--python으로 bubble sort이랑 queue sort이다.

 

trim:

ltrim rtrim

trim 좌우 공백을 제거해서 리턴해주는 함수

문자열 검색 알고리즘에서는 좌우 공백을 제거하고 조회합니다.

계정은 대소문자 구분하지 않고 공백도 제거한다.

 

--좌우공백

SELECT trim('               HI  ')

FROM dual;--HI

-- 프로그램이나 데이터베이스에서 문자열을 비교할 때는 좌우공백을 제거하고 비교하는 경우가 많습니다

-- 영문인 경우는 대소문자 구분 여부를 설정해야 합니다.

-- 비밀번호를 제외하고는 대소문자 구분을 하지 않습니다.

-- 영문 텍스트 마이닝세어 제일 먼저 하는 중의 하나가 소문자로 전부 변화하는 것입니다.

--CONCAT

두개의 문자열을 합쳐서 하나의 문자열로 만들어주는 함수

함수 보다는 || 연산자를 많이 이용한다.

 

함수는 호출한다.

함수는 HEAP에 있는지 없는지 확인하고 메모리 만들고 리턴한다.

연산자를 더 많이 사용한다.

class는 함수 보다 더 늦다.

 

 

 

 

아래 두개 결과는 같다.

--concat

SELECT CONCAT(ename,job)

FROM EMP e;

 

SELECT ename || job

FROM EMP e;

 

convert

문자열의 charset(인코딩)을 변환해주는 함수

convert(데이터,변경할 인코딩,원래 인코딩)

 

많이 사용되는 인코딩 방식은 US7ACII, UTF8,WE8ISO8859-1

한글이 되는 것은 UTF8밖에없다. american standard

ASCII:영문 및 숫자 특수문자를 1byte로 표현하는 방식

utf8:전 세계 모든 문자를 표현하기 위한 코드 한글자가 3bytes

WE8ISO8859-1:서유럽 문자로 한글이 표현되지 않은 iso latin -1이라고도 합니다.

 

convert 한글은 utf8로 밖에 표현이 안되기 때문에 거의 사용되지 않고 유럽 쪽에서는 많이 사용

 

**날짜 관련 함수

sysdate:현재 날짜 및 시간을 리턴

데이터베이스에스는 대부분의 관계형 데이터베이스는 하루를 수자 1로 간주해서 덧셈 및 뺄셈이 가능하다.

 

next_day:특정 날짜에서 입력한 요일이 언제인지 리턴해주는 함수

add_month :특정 날짜에서 월을 더해서 리턴해주는 함수

round,trunc를 이용해서 반올림이나 버림도 가능하다.

날짜 영역으로

주단위 월단위로 계산 하는 부분

구글 analytics

--날짜 사이에 연산자

--몇칠 근무했는지 확인

SELECT ENAME,TRUNC(SYSDATE-HIREDATE)

FROM EMP e;

 

 

SELECT SYSDATE-TO_DATE('1986/05/05','yyyy/MM/dd')

FROM DUAL;

변환함수

숫자 <-> 문자

문자 <-> 날짜

=>문자로 변환할 때는 to_char

=>날자로 변환할 때는 to_date

=>숫자로 변환할 때는 to_number

=>날짜 사이의 연산은 숫자로 변환해서 연산을 합니다.

날짜 날짜를 하면 숫자로 결과가 리턴

=>문자로 변환하는 경우는 대부분 출력을 하기 위해서

=>숫자나 날짜 변환하는 경우는 연산을 하기 위해서 입니다.

=>문자는 더하기 하면 뒤에 붙어진다.

=>숫자나 날짜 서식

1.  숫자서식

0:무조건 표시하는것으로 없으면 0

9:있으면 표시하고 없으면 생략

L:통화기호

.:소수점

,: 단위 구분 기호

2.  날짜 서식

yyyy-연도 4자리

yy – 연도 2자리

mm- 2자리

day –요일

dd-

hh -12시간제

hh24 24시간제

mi

ss

am또는 pm:오전 오후

 

 

엑셀에서 한글 있는지 확인하고 , 이것 있는지 확인 단위 구분기호 있으면 문자로 인식한다.

1,234->엑셀에서는 숫자인데 , R이나 PYTHON 에서는 문자로 한다.

날짜 숫자 저장할때 자리수 맞추어 주는게 좋다.

7  => 07

17 => 17

mac 사용할때 9시간 차이난다.

날짜 오류 경우 날짜 바꿨다고 하면 된다.

날짜 다를 경우 운영체제

 

 

**null대체 함수

nvl(데이터,데이터가 null일때 사용할 )

nvl2(데이터, 데이터가 null 아닐 사용할 ,null 사용할 )

--emp테이블에서 enmaecomm 값에 100 더한 값을 조회

SELECT ENAME, comm+100

FROM EMP e;

--데이터베이스에서는 null 연산을 하면 null

-- 프로그래밍 언어에서는 예외가 발생

SELECT ENAME, NVL(comm,0)+100

FROM EMP e;

 

SELECT ENAME, NVL2(comm,comm,0)+100

FROM EMP e;

 

null 경우 결측치 라고 한다.

 

**그룹화

1.  그룹함수

=>다중 함수라고도 하는데 1 이상의 행을 가지고 연산을 하나의 결과를 리턴하는 함수

=>sum,avg,max,min,count,stddev-표준편차,variance-분산

=>함수의 매개변수로 컬럼이름이나 연산식을 대입하는데 null 데이터는 제외하고 연산을 합니다.

=>데이터의 개수를 셀때 count 사용하는데 컬럼이름을 대입하면 null 데디터는 제외하게 되는데 전체 데이터의 개수를 알고자 때는 컬럼 이름 대신에 * 대입합니다.

모든 컬럼이 null 아니라면 개수를 세는데 포함이 됩니다

=>avg 이용해서 평균을 구할때 null 데이터를 치환을 해서 계산을 하는 경우가 많습니다.

comm컬럼의 경우 14개의 데이터 중에서 4개의 데이터만 입력이 되어있습니다.

avg 바로 구하면 4 데이터의 평균이 리턴됩니다.

=>그룹 함수는 group by 절의 내용과만 같이 출력이 가능합니다.

그룹화하지 않은 컬럼과는 같이 출력할 없습니다.

=>평균과 최대 ,최소 그리고 사분위 수는 같이 출력하는 것이 좋습니다.

값들을 보고 데이터의 대략적인 분포를 알고 이상치 여부를 판단하거나 대표값을 선정합니다.

평균과 차이가 나면 noisy outline이라고 한다.

boxplot

기술 통계학 보고 판단 데이터 분포 확인

 대표값 평균값

70,70,68,72,70 평균 70 경우 70 대표값

85,85,85,85,10 평균 70이지만 대표값은 85이다.

--emp테이블에서 sal 평균

SELECT avg(SAL) AS 급여평균

FROM EMP e;

--emp에서 comm 평균: comm에는 null데이터가 포함되어 있습니다.

SELECT avg(comm) AS 상여금평균

FROM EMP e;

 

SELECT avg(nvl(comm,0))  AS 상여금평균

FROM EMP e;

 

--상여금을 받는 사원의

SELECT count(COMM)

FROM EMP e;

--전체 사원의

SELECT count(*)

FROM EMP e;

 

--sal 가장 많은 사원의 ename sal값을 출력

--ename 여러개의 값이고 max(sal) 하나의 값이라서 같이 출력할 없습니다.

--이런 경우는 서브쿼리나 조인을 이용해서 해결해야 합니다.

SELECT ename,max(sal)

FROM emp

GROUP BY ENAME

ORDER BY max(sal) DESC;

 

2.  group by

=>그룹화에 사용하는

=>컬럼이나 연산식을 이용해서 그룹화

=>group by 절에 기재한 내용은 그룹 함수와 같이 출력 가능

--emp테이블에서 job별로 평균 sal 랎을 조회

SELECT JOB, AVG(SAL)

FROM EMP e

GROUP BY JOB;

 

--emp테이ㅂㄹ에서 입사년도 인원수를 조회

--입사년도는 hiredate컬럼

SELECT TO_CHAR(HIREDATE,'yyyy') ,count(*)

FROM EMP e

GROUP BY TO_CHAR(HIREDATE,'yyyy')

 

SELECT SUBSTR(HIREDATE,1,2) ,count(*)

FROM EMP e

GROUP BY SUBSTR(HIREDATE,1,2);

 

SELECT SUBSTR(HIREDATE,1,2) AS 입사년도,count(*) AS 인원수

FROM EMP e

GROUP BY SUBSTR(HIREDATE,1,2)

ORDER BY 인원수 DESC;

 

SELECT TO_CHAR(HIREDATE, 'yyyy/mm/dd day')

FROM EMP e;

 

--요일별로 인원수를 조회

SELECT TO_CHAR(HIREDATE, 'day') AS 입사요일,count(*) AS 인원수

FROM EMP e

GROUP BY TO_CHAR(HIREDATE, 'day')

ORDER BY 인원수 DESC;

 

=>group by 절에 여러개의 컬럼이나 연산식을 작성할 있는데 첫번째로 그룹화하고 그안에서 다시 그룹화

 

**having

=>그룹화 이후에 조건을 적용할 사용

=>where절은 group by 보다 먼저 실행되기 때문에 그룹 함수를 사용할 없습니ㅏㄷ.

=>그룹 함수를 이용한 조건은 having 작서해야 합니다.

 

select -5

from -1

where -2

group by -3

having -4

order by – 6

 

--5 이상입사한 해를 조회

SELECT SUBSTR(HIREDATE,1,2) ,count(*)

FROM EMP e

GROUP BY SUBSTR(HIREDATE,1,2)

HAVING count(*) >= 5;

 

--그룹함수를 사용하지 않는 조건을 having 사용하는 것은 비효율적입니다.

sql 단위로 수행해서 하나의 결과를 만들어냅니다.

selece 때만 효율을 많이 사용합니다.

 

emp테이블에서 deptno 10 데이터의 sal 평균 조회

4.select avg(sal)

1.from emp

2.where deptno = ‘10’

3.group by deptno ;->추천

=> 결과 1.에서 5

        2.5 가지고 group by 한다.

filter where에서 하는 것이 좋다.

 

4.select avg(sal)

1.from emp

2.group by deptno

3.having deptno = ‘10’;->비효율적이다 .그룹함수가 없다.

=>결과 1.에서 15

       2.에서 3개씩  group by

       3.에서 5

 

emp

deptno 10->5

        20->5

        30->5

데이터 처리 부분

하기전에 필터링 먼저 하자

 

자료형 ,

이상치 제거,

null치환(null제거),

기술통계,

시각화 ,

미리 필터링,

원핫인코딩(a문자를 숫자로 바꿔야 한다.),

필터링, 표준화(데이터를 맞춰야 한다. 정규화)

필터링을 먼저 하는게 좋다.

 

solaris ->sun ->oracle인수

예약  application->코레일

 

** join

=>2개의 테이블을 조합하는

=>구조가 다른 테이블 들끼리 합쳐서 하나의 테이블을 테이블을 만드는 것은 join이라고 동일한 구조를 가진 테이블끼리 세로로 합치는 것을 merge라고 합니다

1. cartesian porduct

=>cross join 이라고도 하는데 2개의 테이블의 모든 테이블들을 조합하는

=>from 절에 테이블이름을 2개를 기재하면 기본적으로 cartesian porduct

=>행의 개수는 양쪽 테이블의 행의 개수의 곱이되고 열의 개수는 양쪽 테이블의 열의 개수의 합이 됩니다.

=>관계형 테이터베이스에서 테이블을 너무 많이 분할했을 발생하는 문제점입니다.

 

emp테이블에는 8개의 열과 14개의 행이 존재

dept테이블에는 3개의 열과 4개의 행이 존재

 

emp테이블과 dept테이블을 cartesian product함ㄴ 11개의 열과 56개의 행이 생성

SELECT *

FROM EMP,DEPT d;

 

 

2.equi joinn

=>2 테이블의 공통된 의미를 갖는 열의 값이 같을 때만 결합하도록 하는

=>실제 동작은 공통된 의미가 아니라 자료형만 같으면 수행할 있습니다.

=>where 절에 양쪽 테이블의 공통된 의미를 갖는 데이터가 같을 때만 결합하도록 기재

=>양쪽 테이블에 있는 열의 이름이 같으면 앞에 테이블이름. 추가해서 구분을 해주어야 합니다.

SELECT *

FROM EMP e,DEPT d

WHERE e.DEPTNO = d.DEPTNO;

=>테이블 이름을 생략하면 열의 이름이 애매하다고 에러 발생

=>새로운 조건을 추가해서 필터링을 때는 위치는 상관없지만 일반적으로 join조건 뒤에 and 추가하고 작성

 

 

-emp테이블에서 sal 3000이상인 사원의 ename  deptno그리고 dept테이블의 loc 조회

=>ename  deptno emp 테이블에 존재

=>loc dept테이블에 존재

=>emp테이블과 dept테이블에 공통된 의미를 갖는 열은 deptno

SELECT e.ENAME, e.DEPTNO,d.LOC

FROM EMP e,DEPT d

WHERE e.DEPTNO = d.DEPTNO

AND e.SAL >= 3000;

 

3.  테이블에 별명 부여

=>테이블 이름이 너무 길거나 알아보기 어려운 경우 또는 self join 경우에는 테이블 이름에 별명을 부여할 있습니다.

=>테이블 이름 뒤에 공백을 추가하고 별명을 입려하면 됩니다.

=>select에서 컬럼의 이름에 별명을 붙인 경우에는 oder by 절에서 별명을 사용해도 되고 원래 이름을 사용해도 되지만 from 절에 테이블 이름에 별명을 붙인 경우에는 이후에는 반드시 테이블 이름 대신 별명을 사용해야 합니다.

R install하면 kernel restart한다.

 

4.  non equi join

=>join 할때 = 대신에 다른 연산자로  join 하는

salgrade테이블은 grade losal그리고 hisal열로 구성

grade 급여 등급이고 losal 등급에서 최저 급여 그리고 hisal 최고 급여입니다.

emp테이블에서 가져온 sal losal이나 hisal 비교하게 되면 = 로는 안될 있습니다.

 

--emp테이블의 ename sal 그리고 salgrade테이블에서 sal 해당하는 grade 조회하고 합니다.

SELECT e.ENAME, e.SAL, s.GRADE

FROM EMP e, SALGRADE s

WHERE (e.SAL >= s.LOSAL AND e.SAL <= s.HISAL);

--학점이나 등급 계산 할때

 

 

SELECT e.ENAME, e.SAL, s.GRADE

FROM EMP e, SALGRADE s

WHERE e.SAL BETWEEN s.LOSAL AND s.HISAL;

 

5.  self join

=>자신의 테이블과 join

=>하나의 테이블에 동일한 의미를 갖는 열이 2 이상 있는 경우에 사용

=>from절에 동일한 테이블의 이름을 2 기재하므로 반드시 별명을 부여해야 합니다.

 

emp테이블에서 empno 사원번호 이고 mgr 관리자 사원번호

이런 경우 사원이름과 관리자의 이름을 같이 조회할려고 하면 self join 사용해야 합니다.

친구 추천

추천 시스템 -> 감성을 이용해서 추천 ,내가 좋아요 눌리면 다른 사람 추천

è  구매목록을 확인하여 확률 높은 것을 추천

è   

è  SELECT e1.ENAME , e2.ENAME 관리자

è  FROM EMP e1 , EMP e2

è  WHERE e1.mgr = e2.EMPNO;

 

 

=>emp테이블에서 ename scott 사원의 관리자 이름을 조회

결과는 jones

SELECT E2.ENAME

FROM EMP e , EMP e2

WHERE e.MGR = e2.EMPNO

  AND UPPER(e.ENAME)='SCOTT';

=>EMP테이블에서 ENAME SCOTT 사원의 관리자의 관리자 사원번호를 조회

결과는 7839

SELECT E2.MGR

FROM EMP e , EMP e2

WHERE e.MGR = e2.EMPNO

AND UPPER(e.ENAME)='SCOTT';

 

 

6.  outer join

=>inner join equi join

=>outer joind 어느 한쪽에만 존재하는 데이터도 join 참여시키는

=>emp테이블에는 deptno 10,20,30 있고 dept테이블에는 deptno 10,20,30,40 존재

경우 equi join 하게 되면 양쪽 테이블에 모두 존재하는 10,20,30 조회

이때 DEPT테이블에만 존재하는 40 JOIN 참여시키고자 수행하는 JOIN OUTER JOIN입니다.

=>OUTER JOIN 떄는 참여시키고자 하는 테이블의 조인조건 기술할 반대편에 (+) 추가

EMP.DEPTNO(+)  = DEPT.DEPTNO

=>DEPTNO테이블에 있는 모든 데이터가 JOIN 참가

=>양쪽 모두에 사용하는 것은 안됩니다.

 

SELECT D.DEPTNO,D.DNAME,E.ENAME

FROM EMP e , DEPT d

WHERE E.DEPTNO(+) = D.DEPTNO;--15

=>40번도 나온다. 이름이 없는데 나온다.

 

SELECT D.DEPTNO,D.DNAME,E.ENAME

FROM EMP e , DEPT d

WHERE E.DEPTNO = D.DEPTNO(+);--14

sqllite 외래키 이런것 문법적으로 되는데 기능제약이 있다.

embeded 간단하게 나와서 복잡해서 안될 경우가 있다.

 

7.  ansi join

=>미국 표준 협회에서 만든 join문법으로 대다수의 관계형 데이터베이스에서 적용이 되지만 일부 관계형 데이터베이스에서는 안될 수도 있습니다.

1). cartesian porduct(cross join)

from 테이블이름 cross join 테이블이름

SELECT *

FROM EMP e cross join DEPT d ;

 

2). equi join-join조건을 on절에 기재: join조건과 where 구분하기 위해서 사용

from 테이블이름1 inner join 테이블이름2

on 테이블이름1.컬럼이름 = 테이블이름2.컬럼이름

SELECT D.DEPTNO,D.DNAME,E.ENAME

FROM EMP e INNER join DEPT d

       ON e.DEPTNO = d.DEPTNO;

 

경우 양쪽 컬럼이름이 같으면 on대신에 using 사용할 있습니다

from 테이블이름1 inner join 테이블이름2

using(컬럼이름)

SELECT *

FROM EMP e INNER join DEPT d

USING(DEPTNO);

 

컬럼이름이 같으면 inner join대신에 natural jon이라고 입력하고 조인 조건 생략 가능

from 테이블이름1 natural join 테이블이름2

SELECT *

FROM EMP e natural join DEPT d ;

 

3).outer join

from 테이블이름1 [left|right|full] outer join 테이블이름2

on 테이블이름1.컬럼이름 = 테이블이름2.컬럼이름

=>full 어느 한쪽 테이블에만 존재하는 데이터도 조인에 참여

SELECT D.DEPTNO,D.DNAME,E.ENAME

FROM EMP e , DEPT d

WHERE E.DEPTNO(+) = D.DEPTNO;

 

 

SELECT D.DEPTNO,D.DNAME,E.ENAME

FROM EMP e RIGHT OUTER join DEPT d

ON  E.DEPTNO = D.DEPTNO;

 

 

8.  set연산

=>동일한 구조를 가진 2개의 테이블에서 가능

=>구조가 같다는 의미는 열의 개수가 같아야 하고 열의 자료형이 같아야 한다.

=>세로 방향으로 작업을 한다.

구별 경찰서와 강력 범죄 발생 건수

구별 경찰서와 위치

 

1)  합집합 –union(중복제거),union all(중복 제거하지 않는다.)

 

2)  교집합-intersect 공통적인 부분

 

3)  차집합-minus

 

select 구문

set 연산자

select 구문

 

 

select deptno

from emp

UNION all

select deptno

from dept;--18

 

 

select deptno

from emp

UNION

select deptno

from dept;--4

 

 

select deptno

from emp

INTERSECT

select deptno

from dept;--3

 

select deptno

from emp

MINUS

select deptno

from dept;--0

 

 

예측은 데이터 많으면 많을 수록 오른 결과가 나올 있을 가능성이 높다.

머신런닝은

join하면 시간이 오래 걸린다.

 

 

**sub query

=>sql문장안에 포함된 sql

=>대부분의 경우는 select

1.작성 방법

=>포함된 구문은 반드시 () 감싸서 우선순위를 높여서 먼저 실행하도록 해야 합니다.

2.서브쿼리의 실행

=>서브쿼리는 메인쿼리가 실행되기 전에 1번만 실행

 

3.  종류

1)  단일 서브쿼리: 서브쿼리의 결과가 하나의 행인 경우

=>단일 연산자를 사용가능(=,!=,>,>=,<,<=)

2)  다중 서브쿼리: 서브쿼리의 결과가 2 이상의 행인 경우

=>단일 연산자를 단독으로 사용 불가능

=> in,not in ,all, any 같은 다중 연산자를 같이 사용해야 합니다.

 

4.  단일 서브쿼리

1)  emp 테이블에서 ename scott 사원의 관리자 이름을 조회

=>join으로 해결

select

from emp e1, emp e2

where e1.ename = ‘SCOTT’ and e1.mgr = e2.empno

 

SUB QUERY  하면 하는게 좋다 .JOIN 경우 데이터 사용량이 많다.

SELECT e.ename

FROM EMP e

WHERE e.EMPNO = (SELECT MGR

                         FROM EMP

                     WHERE ename ='SCOTT');

=>SELECT절에 출력하는 열의 이름들이 하나의 테이블에서 추출이 가능하다면 SUB QUERY 해결 가능하다.

괄호가 먼저 해야 해서

 

 

2)  emp테이블과 dept테이블은 deptno 같이 소유하고 있습니다.

dept테이블의 loc dallas 사원의 emp테이블의 ename sal

 

SELECT ename,SAL

FROM emp

WHERE DEPTNO = (SELECT DEPTNO

                              FROM DEPT d

                          WHERE loc ='DALLAS');

3).detp테이블의 dname sales 데이터의 ename job 조회

부서명이 sales 사원의 이름과 직무를 조회

ename job emp 존재

dept테이블과 emp테이블은 deptno 공유

 

SELECT ename,job

FROM EMP

WHERE DEPTNO = (SELECT DEPTNO

                              FROM DEPT d

                          WHERE DNAME = 'SALES');

 

 

5.다중 서브쿼리

emp테이블과 dept테이블은 deptno 같이 소유하고 있습니다.

dept테이블의 loc dallas chicago 사원의 emp테이블의 ename sal 조회

 

select ename,sal

from emp

where deptno = (select deptno

                             from dept

                             where loc ='DALLAS' OR loc ='CHICAGO' );

=> 문장은 에러

문법적으로는 에러가 아닐 있지만 'DALLAS', 'CHICAGO' 근무하는 사원의 DEPTNO 20 30 두개입니다.

두개의 데이터를 = 비교할 없습니다.

경우에는 = 대신에 in 사용해야 합니다.

!= 경우에는 not in 사용해야 합니다.

 

 

select ename,sal

from emp

where deptno in (select deptno

                             from dept

                             where loc ='DALLAS' OR loc ='CHICAGO' );

 

=>2 이상의 숫자가 결과로 리턴되는 경우에 2 숫자보다 모두 경우에 해당하는 데이터를 조회 > (100,200) 형식은 안됩니다.

크다나 작다는 하나의 값과만 비교 가능

여러 개의 데이터와 크다 작다로 비교하는 경우에는 all이나 any 라는 연산자를 이용할 있습니다.

 

>ALL (100,200): 100 200보다 모두 경우에는 TRUE리턴

이와 동일한 결과를 가져오는 형태는 >MAX(100,200)

>ANY(100,200):100이나 200데이터 중에서 하나라도 크면 TRUE리턴

이와 동일한 결과를 가져오는 형태는 >MIN(100,200)

 

=>emp테이블에서 deptno 10 또는 20 부서의 평균 sal보다 sal 사원의 이름과 sal 조회

 

SELECT ENAME,SAL

FROM EMP e

WHERE sal >(SELECT AVG(SAL)

                      FROM EMP e

                      WHERE DEPTNO IN ('10','20')

                      GROUP BY DEPTNO );

-- single-row subquery returns more than one row

-- 문장은 서브쿼리의 결과가 2개라서 에러가 발생

 

SELECT ENAME,SAL

FROM EMP e

WHERE sal > ALL (SELECT AVG(SAL)

                             FROM EMP e

                             WHERE DEPTNO IN ('10','20')

                             GROUP BY DEPTNO );

 

SELECT ENAME,SAL

FROM EMP e

WHERE sal > (SELECT max(AVG(SAL))

                             FROM EMP e

                             WHERE DEPTNO IN ('10','20')

                             GROUP BY DEPTNO );

 

---------------------

SELECT ENAME,SAL

FROM EMP e

WHERE sal > ANY (SELECT AVG(SAL)

                             FROM EMP e

                             WHERE DEPTNO IN ('10','20')

                             GROUP BY DEPTNO );

 

SELECT ENAME,SAL

FROM EMP e

WHERE sal >  (SELECT min(AVG(SAL))

                             FROM EMP e

                             WHERE DEPTNO IN ('10','20')

                             GROUP BY DEPTNO );

 

반응형

'Study > DB' 카테고리의 다른 글

DB-6  (0) 2020.09.18
DB-5  (0) 2020.09.17
DB-4  (0) 2020.09.15
DB-3  (0) 2020.09.15
DB-1  (0) 2020.09.13
반응형

데이터베이스 개론

데이터베이스  파일 관리 시스템

rdbms많이 사용하고

NoSQL ->새로운 기술에 인력소요가 많기 때문에

oracle->가장 강력한 데이터베이스

db2

sap의 사이베이스나 하나db

하나db->많은 양의 데이터 읽는뎅 강하다.

orcle->많은 양의 데이터 쓰기에 강하다.

티맥스 tibero->

비밀버호 1234

mysql, maria db

java

페도라 ->centos->redhat

 

 

관계형 데이터베이스를 구성하는 용어

릴레이션(Relation) : 정보저장의기본형태가2차원구조의테이블

속성(attribute) : 테이블의각열을의미 ->coloumn filed

도메인(Domain) : 속성이가질수있는값들의집합 ->하나의 컬럼이 가질 수 있는 값의 집합 ->자료형->제약조건도 포함

                       ->업무에 관련된 것도 도메인이다.

                       ->도메인 지식이 중요하다.

튜플(Tuple) : 테이블이한행을구성하는속성들의집합 ->레코드 row

카디널리티(Cardinality) : 서로다른테이블사이에대응되는수-내 데이터 하나에 몇개 연결되여있는가

 

(key) 하나의 행을 구분할 수 있는 것들

->릴레이션을구성하는각튜플들을데이터값들에의해유일하게식별할수있는속성또 는속성의집합

 

후보키(Candidate Key) ->최소의 키로 구분할수 있는것 예: 학번

->릴레이션의한속성집합(K)이릴레이션이전체속성집합A의부분집합이면서유일 성(uniqueness)과최소성(minimality)을만족하는속성또는속성의집합(K)

 

기본키(PimaryKey) 후보키중에서 개발자가 선정하는 것 테이블에 하나만 가능하다.

하나만 가능한 것인지 하나의 속성으로 할 필요 없다.

->후보키중에서선정한키로릴레이션의튜플들을유일하게식별할수있는키

필수는 아니지만 하는 게 좋다.

pk ->index가 생성된다. 조회 빠르게 된다.구분하기 위해서

 

대체키(Alternate Key) 

           기본키를제외한나머지후보키(Candidate Key)

 

외래키(Foreign Key) 

           다른테이블의행을식별할수있는속성

           다른테이블에서는기본키이거나유일한값을갖는속성

 

제약조건

개체무결성(Entity Inetgrity) 

           기본키는null이거나중복될수없음

참조무결성(Referential Intigrity) 

           릴레이션은 참조할수없는외래키의값을가져서는안됨

           외래키의값은다른테이블에존재하는값이거나null 이어야함

 

NoSQL이무엇의약자인지는No SQL, Not Only SQL, Non-Relational Operational Database

SQL로엇갈리는의견들이있습니다만,현재Not Only SQL로풀어설명하는것이다수를차지

 

NoSQL 분류 ->dict map

Key Value DB: KeyValue의쌍으로데이터가저장되는가장단순한형태의솔루션으로 AmazonDynamo Paper에서유래되었으며Riak, Vodemort, Tokyo

          Wide Columnar Store: Big Table DB라고도하며GoogleBigTablePaper에서유래되었 으며Key Value 에서발전된형태의Column Family 데이터모델을사용하고있고HBase, Cassandra, ScyllaDB->windows에서 안됨 linux등에서 가능

          Document DB: Lotus Notes에서유래되었으며, JSON, XML과같은Collection 데이터모 델구조를채택하는형태로MongoDB, CoughDB

Cassandra ->java로 만들었다.

MongoDB->c++기반으로 되여있다.

          Graph DB: Euler & Graph Theory에서유래한DBNodes, Relationship, Key-Value 데이 터모델을채용하는형태인데Neo4J, OreientDB

           기존의 관계형 등 여러가지 많이 사용한다.

 

Oracle은 보통  linux  unix에서 한다. Mac에서 설치되지 않는다.windows에서 불안전하다.

Mac은 서버쪽 관련 공부하는 것이 안좋아서 container우에 깔아야 한다.

9i ->internet

10g, 11g->grid

12c ->cloud

 

Sid  두개

Orcl(enter prise)

Xe(expre )->비밀번호만 여는 것

서비스에 가서

저장소 xe

원본을 사용하는 것이 아니다. 저장소에서 한다.

Sqlplus->원본을 사용한다.

Sqldeveloper java가 있어야 한다.

dbbeaver유료버전은 mongodb등 접속가능하다.

Os authen  아이디 비밀번호 없는 것이다.

어디에 있는 것인가 ?

System

 

Driver oracle과 툴

driver혹은 interface이다.

 

사용자가 없어서 만들어줘야 한다.

 

--USER추가

CREATE USER scott IDENTIFIED BY tiger;

ALTER USER scott DEFAULT TABLESPACE USERS;

ALTER USER scott TEMPORARY TABLESPACE TEMP;

GRANT CONNECT , DBA, RESOURCE TO SCOTT;

;->한명령어를 여기까지 한번에 해주세요

 

Set ->데이터가  7 ,9 ,14

List는 순서데로 저장한다.없는 데이터 찾는데 오래 걸린다. 다 검색해야 한다.

Set 7을 열경우 계산한다. 3으로 나눈 나머지 가지고 저장해야 한다.

0 ,1 , 2->이런석으로 해서 bucket에 나눈다.중복은 안된다.hash로 한다.

찾는데 걸리는 시간이 같다.

시노님 : 개체에 대한 별명 ->별명을 한다.

식별하기 좋게 한다. 알아보기 쉽게 유지보수 하기 쉽게 위해서

오라클 시퀸스는 좀더 강력하다.

Index 대상을 빨리 찾기 위해서 한다.

우리는 순서데로 옇지만 index한다. index가지고 빠르게 찾는다.

 

Function return하는데

Procedure return이 필요없다. 일만 하면 된다.  Plsql

package묶어 논다.

PL/SQL (Procedural Language/Structured Query Language) 

 SQL  관계형 데이터베이스(오라클) 위한 오라클 사의 절차적인 확장 언어이다.
Transact-SQL (T-SQL)  

 마이크로소프트 사와 사이베이스  소유의  SQL 확장 언어이다. Transact-SQL SQL Server 사용하기 위해 중심이 된다모든  어플리케이션은 사용자 인터페이스에 개의치 않고

Transact-SQL 구문을 서버로 전송함으로써  SQL Server 인스턴스와 통신한다.
trigger삭제 할 때 탈퇴 등 관련하여 가입시 여기 확인해서 탈퇴시 여기 가입해야한다.

명령어를 하나의 것으로 해야한다. 이것을 사용하는 것이 transaction이다.

특정한 날짜에만 사용못하게 하세요 ->trigger를 한다.

명령어 실행 못하게 끔 하는 것

SQL(Structured Query Language)

SEQUEL(Structured English QUeryLanguage)

SQL은비절차적

대화식언어로사용가능

다른종류의범용프로그래언어로작성된프로그램에내장(embed)시킨형태로도 사용가능

각각의튜플단위가아니라튜플들을집합단위로처리

반복문으로 하는것이다.

데이터 분석의 데이터는 vector데이터 이다.

R은 통계학자  return하다 분석을 할 때 원본 데이터 망가지면 안되서 원본데이터 보존해야 한다.

           분석 ->읽기 전용

python은 프로그래머 읽기 쓰기 전용

dql데이터 읽기만 하는 것

7. SQL

D->데이터 관리 하는 분만 한다.

로그아웃 하면서 하는 것이 복사본에 저장한다.

Show user

Conn scott/tiger;

 

 

--DROP TABLE DEPT;

CREATE TABLE DEPT

       (DEPTNO NUMBER(2) CONSTRAINT PK_DEPT PRIMARY KEY,

       DNAME VARCHAR2(14) ,

       LOC VARCHAR2(13) ) ;

--DROP TABLE EMP;

CREATE TABLE EMP

       (EMPNO NUMBER(4) CONSTRAINT PK_EMP PRIMARY KEY,

       ENAME VARCHAR2(10),

       JOB VARCHAR2(9),

       MGR NUMBER(4),

       HIREDATE DATE,

       SAL NUMBER(7,2),

       COMM NUMBER(7,2),

       DEPTNO NUMBER(2) CONSTRAINT FK_DEPTNO REFERENCES DEPT);

INSERT INTO DEPT VALUES

       (10,'ACCOUNTING','NEW YORK');

INSERT INTO DEPT VALUES (20,'RESEARCH','DALLAS');

INSERT INTO DEPT VALUES

       (30,'SALES','CHICAGO');

INSERT INTO DEPT VALUES

       (40,'OPERATIONS','BOSTON');

INSERT INTO EMP VALUES

(7369,'SMITH','CLERK',7902,to_date('17-12-1980','dd-mm-yyyy'),800,NULL,20);

INSERT INTO EMP VALUES

(7499,'ALLEN','SALESMAN',7698,to_date('20-2-1981','dd-mm-yyyy'),1600,300,30);

INSERT INTO EMP VALUES

(7521,'WARD','SALESMAN',7698,to_date('22-2-1981','dd-mm-yyyy'),1250,500,30);

INSERT INTO EMP VALUES

(7566,'JONES','MANAGER',7839,to_date('2-4-1981','dd-mm-yyyy'),2975,NULL,20);

INSERT INTO EMP VALUES

(7654,'MARTIN','SALESMAN',7698,to_date('28-9-1981','dd-mm-yyyy'),1250,1400,30);

INSERT INTO EMP VALUES

(7698,'BLAKE','MANAGER',7839,to_date('1-5-1981','dd-mm-yyyy'),2850,NULL,30);

INSERT INTO EMP VALUES

(7782,'CLARK','MANAGER',7839,to_date('9-6-1981','dd-mm-yyyy'),2450,NULL,10);

INSERT INTO EMP VALUES

(7788,'SCOTT','ANALYST',7566,to_date('13-7-1987','dd-mm-yyyy')-85,3000,NULL,20);

INSERT INTO EMP VALUES

(7839,'KING','PRESIDENT',NULL,to_date('17-11-1981','dd-mm-yyyy'),5000,NULL,10);

INSERT INTO EMP VALUES

(7844,'TURNER','SALESMAN',7698,to_date('8-9-1981','dd-mm-yyyy'),1500,0,30);

INSERT INTO EMP VALUES

(7876,'ADAMS','CLERK',7788,to_date('13-7-1987','dd-mm-yyyy'),1100,NULL,20);

INSERT INTO EMP VALUES

(7900,'JAMES','CLERK',7698,to_date('3-12-1981','dd-mm-yyyy'),950,NULL,30);

INSERT INTO EMP VALUES

(7902,'FORD','ANALYST',7566,to_date('3-12-1981','dd-mm-yyyy'),3000,NULL,20);

INSERT INTO EMP VALUES

(7934,'MILLER','CLERK',7782,to_date('23-1-1982','dd-mm-yyyy'),1300,NULL,10);

 

--DROP TABLE SALGRADE;

CREATE TABLE SALGRADE

      ( GRADE NUMBER,

       LOSAL NUMBER,

       HISAL NUMBER );

INSERT INTO SALGRADE VALUES (1,700,1200);

INSERT INTO SALGRADE VALUES (2,1201,1400);

INSERT INTO SALGRADE VALUES (3,1401,2000);

INSERT INTO SALGRADE VALUES (4,2001,3000);

INSERT INTO SALGRADE VALUES (5,3001,9999);

COMMIT;

 

SELECT * FROM DEPT;

SELECT * FROM EMP;

SELECT * FROM SALGRADE;

 

@script파일 명령어 쓰면 된다.

@하고 sql관련 내용을 땡기면 된다.

DESC dept;--ORA-00900: invalid SQL STATEMENT

--dbeaver에서 안된다. 왜냐하면 현제것 보여주기때문에

SELECT * FROM show_user;# SELECT * FROM show_user;

--dbeaver에서 사용안한다.

 

--색갈이 다른것은 제약어이다.

오라클 대문자

Mysql 소문자. Ibatis

 

3 select

 

 

1.기본적인Select

From -> where->condition ->Select ->order by

1bytes  10bytes

1이면 null

0이면 not null

Nvl()로 준다.

Null+숫자 ànull이다.

 

LITERAL 정해진 값 집여 옇기  사용자가 입력한 상수 ‘a’

숮자 안쓰고

문자 날짜 ‘’

Null은 그냥 쓴다.

Constant ready only 변수  a= 10 a는 변수

Const a = 10 ->수정불가

 

Distinct는 전체 영향을 준다.

한번밖에 못 쓴다.

 

곱하기 * 이것이다. X가 아니다.

And 앞에것 거짓이면 뒤에것 안한다.

%3 == 0 and %4 ==0

%4 == 0 and %3 ==0->이것으로 하는게 좋다. 뒤에것 안해도 되기 때문에

and앞에것 거짓이 확률이 높은 것

or앞에것 참인 확률이 높은 것

WHERE 절의 연산자

BETWEEN A AND B : A B사이 (A B 포함)

NOT BETWEEN A AND B:A B 사이가 아닌

 

 

SELECT *

FROM EMP e;

--특정 클럼만 조회

--emp 테이블에서 empno ename 조회

SELECT EMPNO,ENAME

FROM EMP e;

 

--컬럼 별명 부여

SELECT EMPNO AS 사원번호

        , ENAME AS 사원이름 --벌명에 영문 대문자가 있으면 ""안에 기제

FROM EMP e

 

---23페이지

--EMP 테이블의모든데이터를조회

SELECT *

FROM emp;

 

--EMP 테이블에서중복되지않는deptno를조회

SELECT DISTINCT deptno

FROM EMP e;

 

--EMP 테이블의enamejob를연결하여조회

SELECT ENAME || ' ' ||JOB

FROM EMP e;

 

--날짜도 숫자이기 때문에 크기 비교가능

--EMP테이블에서 HIRDATE 1982 1 1 부터 1982 12 31 데이터의 HIREDATE 조회

--날짜는 일반적인 형식의 문자열로 작성이 가능

SELECT ENAME,HIREDATE

FROM EMP e

WHERE HIREDATE BETWEEN '1982/01/01' AND '1982/12/31';

 

--sal 값이 1000-3000사이

SELECT ENAME, SAL

FROM EMP e

WHERE SAL BETWEEN 1000 AND 3000;

 

--in (목록)

--보통은 or 대체가 가능하지만 subquery에서는 or 대체가 안됨

--emp table에서 jobdl clerk또는 salesman 데이터의 모든 컬럼을 조회

SELECT *

FROM EMP

WHERE JOB IN ('CLERK','SALESMAN')

 

--like

--패턴에 일치하는 데이터를 조회할 사용

--2개의 wild card문자를 이용

--% 글자 수와 상관없이 매칭

--_ 1글자와만 매칭

--%A% A 포함됨

--%A  A 끝나는

--A%  A 시작하는

--_A A 끝나는 2글자

--WILD CARD문자를 조회하는 경우

--_ 포함함

--LIKE '%\_%' escape '\':\다음에 나오는 글자는 하나의 문자로 해석 있는 거데로 인식하라

--hiredate 1982 데이터의 ename hiredate 조회

--HIREDATE 12월인 데이터의 ENAME HIREDATE 조회

SELECT ename,hiredate

FROM EMP e

WHERE HIREDATE LIKE '___12%';

--yy/MM/dd

--___01%

--___01___

 

--NULL조회 IS NULL,IS NOT NULL

-- NULL 조회하게 되면 입력된 데이터가 'NULL' 데이터를 조회

SELECT ENAME,COMM

FROM EMP e

WHERE COMM = NULL;

 

 

SELECT ENAME,COMM

FROM EMP e

WHERE COMM IS NULL;

-- = NULL 대신 IS NULL 조회

 

-- AND OR사용시 주의점

-- AND 앞쪽의 조건이 FALSE이면 뒤의 조건을 확인하지 않습니다.

-- OR 앞쪽의 조건이 TRUE이면 뒤의 조건을 확인하지 않습니다.

-- AND OR 사용할 떄는 조건을 확인해서 AND 앞쪽에 FALSE 가능성이 높은 조건을 배치하고 OR 경우에는 TRUE 가능성이 높은 조건을 하는 것이 좋습니다.

-- AND OR 같이 사용될 때는 AND 우선순위가 높습니다.

-- A OR B AND C:(B이고 C 데이터 )또는 A 데이터로 해석

-- OR 우선순위를 높일려면 괄호를 해야 합니다. (A OR B) AND C

 

-- ORDER BY

-- SELECT구문의 결과를 정렬하기 위한

-- SELECT 가장 마지막 절이고 마지막으로 수행됩니다.

-- 2 이상의 데이터를 조회하는 경우 해주는 것이 좋습ㄴ디ㅏ.

-- 관계형 데이터베이스에 데이터를 저장하게 되면 데이터의 순서는 데이터베이스가 결정합니다.

-- 입력 순서와는 무관하게 저장됩니다.

-- 사용형식

-- ORDER BY 컬럼이름  [ASC|DESC],컬럼이름  [ASC|DESC]

-- ASC ->DEFUALT(작은 것에서 순으로 ) 오름차순

-- DESC ->내림차순( 것에서 순으로 )

-- 컬럼이름 대신에 SELECT에서 만든 별명 사용가능

-- SELECT에서의 INDEX 사용해도 가능(데이터베이스에서는 인덱스가 1부터 시작)

-- 컬럼이름을 2 이상 사용하면 앞의 데이터 값이 동일할 적용

-- 컬럼 이름 대신에 연산식도 가능하다.

 

--EMP테이블의 모든 데이터를 조회

--HIREDATE 오름차순으로 정렬

SELECT EMPNO,ENAME,JOB,MGR,HIREDATE 입사일,SAL, COMM, DEPTNO

FROM EMP e

ORDER BY HIREDATE;

 

SELECT EMPNO,ENAME,JOB,MGR,HIREDATE 입사일,SAL, COMM, DEPTNO

FROM EMP e

ORDER BY 입사일;

 

SELECT EMPNO,ENAME,JOB,MGR,HIREDATE,SAL, COMM, DEPTNO

FROM EMP e

ORDER BY 5;

--DEPTNO 내림차순 정렬하고 동일한 값이면 EMPNO 오름차순으로 정렬

SELECT *

FROM EMP

ORDER BY DEPTNO DESC, EMPNO;

 

--SELECT 구문

--SELECT       -5

-- FROM        -1

-- WHERE       -2

-- GROUP BY -3

-- having      -4

-- ORDER BY -6

--select from 필수 이다.

 

 

 

--1.EMP 테이블에서sal3000이상인사원의empno, ename, job, sal을조회하는SELECT 문장을 작성

SELECT EMPNO,ENAME,job,SAL

FROM EMP e

WHERE sal >= 3000;

--결과는  SCOTT,KING,FORD

 

--2.EMP 테이블에서empno7788인사원의enamedeptno를조회하는SELECT 문장을작성

SELECT ENAME,DEPTNO

FROM EMP e

WHERE EMPNO = 7788;

--결과는  SCOTT

 

--3.EMP 테이블에서hiredate1981220일과198151일사이에입사한사원의 ename, job, hiredate을조회하는SELECT 문장을작성(hiredate순으로조회)

--1).

SELECT ENAME,JOB, HIREDATE

FROM EMP e

WHERE HIREDATE BETWEEN '1981/02/20' AND '1981/05/01'

ORDER BY hiredate;

 

--2).

SELECT ENAME,JOB, HIREDATE

FROM EMP e

WHERE HIREDATE >= '1981/02/20'; --13

 

SELECT ENAME,JOB, HIREDATE

FROM EMP e

WHERE HIREDATE <= '1981/05/01'; --5

 

SELECT ENAME,JOB, HIREDATE

FROM EMP e

WHERE HIREDATE <= '1981/05/01' AND HIREDATE >= '1981/02/20';

 

 

-- 4.EMP 테이블에서deptno10, 20인사원의모든정보를조회하는SELECT 문장을작성( ename순으로조회)

SELECT *

FROM EMP e

WHERE DEPTNO IN ('10','20')

ORDER BY ENAME;

 

 

-- 5.EMP 테이블에서sal1500이상이고deptno10, 30인사원의enamesal를조회하는 SELECT 문장을작성(HEADINGemployeeMonthly Salary로조회)

SELECT ENAME employee, SAL "Monthly Salary"

FROM EMP

WHERE SAL >= 1500; --8

 

SELECT ENAME employee, SAL "Monthly Salary"

FROM EMP

WHERE DEPTNO IN ('10','30');--9

 

 

SELECT ENAME employee, SAL "Monthly Salary"

FROM EMP

WHERE SAL >= 1500

  AND DEPTNO IN ('10','30');

 

-- 6.EMP 테이블에서hiredate1982년인사원의모든정보를조회하는SELECT 문을작성

SELECT *

FROM EMP e

WHERE HIREDATE LIKE '82%';

 

-- 50페이지

-- 1.EMP 테이블에서MGR NULL 인사원의enamejob 컬럼을조회

SELECT ENAME, JOB

FROM EMP e

WHERE MGR IS NULL;

 

-- 2.EMP 테이블에서COMMNULL이아닌사원의모든정보를조회하는SELECT 문을작성

SELECT *

FROM EMP e

WHERE COMM IS NULL;

-- 3.EMP 테이블에서comm sal보다10% 이상많은사원에대하여ename, sal, comm를조회하 SELECT 문을작성

SELECT *

FROM EMP E

WHERE COMM IS NOT NULL

  AND COMM  >= (SAL * 1.1);

 

 

-- 4.EMP 테이블에서jobCLERK이거나ANALYST이고sal1000, 3000, 5000이아닌사원의모 든정보를조회하는SELECT 문을작성

SELECT *

FROM EMP e

WHERE JOB IN ('CLERK','ANALYST'); --6

 

SELECT *

FROM EMP e

WHERE SAL NOT IN ('1000','3000','5000');--11

 

SELECT *

FROM EMP e

WHERE JOB IN ('CLERK','ANALYST')

  AND SAL NOT IN ('1000','3000','5000');

 

-- 5.EMP 테이블에서enameA E를모두포함하고있는사원의enamesal을조회

SELECT ENAME, SAL

FROM EMP e

WHERE (ENAME LIKE '%A%') ;-- 7

 

 

SELECT ENAME, SAL

FROM EMP e

WHERE (ENAME LIKE '%E%') ; --6

 

--A E를모두포함

SELECT ENAME, SAL

FROM EMP e

WHERE (ENAME LIKE '%E%') AND (ENAME LIKE '%A%');

 

-- 6.EMP 테이블에서(enameL이두자이상이포함되어있고deptno30)이거나mgr7566 인사원의모든정보를조회하는SELECT 문을작성

--enameL이두자이상

SELECT *

FROM EMP e

WHERE ENAME LIKE '%L%L%';--2

 

--deptno30

SELECT *

FROM EMP e

WHERE deptno IN ('30');--6

 

--mgr7566

SELECT *

FROM EMP e

WHERE MGR = '7566';

 

SELECT *

FROM EMP e

WHERE ENAME LIKE '%L%L%'

  AND deptno IN ('30')

   OR MGR = '7566';

 

 

 

 

 

** 오라클 제공함수

1.     함수 분류

1). 단일 행 함수 :하나의 행에 적용되는 함수

2). 다중 행 함수 : 0개 이상의 행에 적용되는 함수

 

2.     dual테이블

=>오라클에서 제공하는 가상의 테이블

=>실제 데이터를 저장할 목적이 아니라 연산의 결과나 확인 등을 하기 위한 테이블

=>select구문에서 from이 없으면 에러가 발생하는데 오늘날짜 같은 데이터는 실제 테이블에 존재하는 데이터가 아닙니다.

오늘 날짜 확인

Select sysdate

From dual;

 

3.     숫자 관련 함수

=>ABS(절대값), COS, EXP(지수), FLOOR(올림), LOG(로그),POWER,SIGN, TAN, ROUND(반올림),TRUNC(올림), MOD

ROUND(데이터[,자릿수]):자릿수가 없으면 소수 첫째 자리에서 반올림 정수로 리턴

자릿수를 적으면 그 자리 뒤에서 반올림해서 리턴

자릿수를 음수를 적으면 정수부분에서 반올림을 합니다.

-1: 1의 자리 반올림

-2: 10의 자리 반올림

 

 

 

--EMP테이블에서 입사 몇칠을 근무했는지 조회

SELECT ENAME, ROUND(SYSDATE - HIREDATE,2) AS 근무일수

FROM EMP e;

 

SELECT ENAME, ROUND(SYSDATE - HIREDATE,-2) AS 근무일수

FROM EMP e;

--14250.72 ->14300

 

SELECT ENAME, TRUNC(SYSDATE - HIREDATE,-2) AS 근무일수

FROM EMP e;

 

 

SELECT ENAME, FLOOR(SYSDATE - HIREDATE) AS 근무일수

FROM EMP e;

 

4.  대소문자 관련 함수

UPPDER:모두 대문자로 변경

LOWER:모두 소문자로 변경

INITCAP:단어의 첫글자만 대문자로 변경

영문 조회할 때는 대소문자 관련 부분을 고려

iOS,iPhone

 

Select ename,sal

From emp

Where job= ‘manager’;

 

Select ename,sal

From emp

Where lower(job)= ‘manager’;

 

 

Select ename,sal

From emp

Where UPPER(job)= ‘MANAGER;

 

encoding:데이터를 컴퓨터에 저장하는 형태로 변경하는 것

Decoding:컴퓨터에 저장된 데이터를 출력하기 위한 형태로 변경하는 것

 

영문은 전세계 모든 코드 체계에서 동일한 방식으로 인코딩과 디코딩을 수행

A->65

a->97

 

한글은 ms949(cp949),euc-kr,utf-8 방식의 인코딩이 있습니다.

ms949: ms-windows인코딩 방식 한글 한글자가 2byte

euc-kr:예전 웹에서 한글을 표현하기 위한 인코딩 방식 한글자가 2byte

utf-8: 전 세계 모든 문자를 표현하기 위한 인코딩 방식 한글자가 3byte

 

다른 인코딩 방식으로 인코딩 된 데이터를 읽으면 제대로 디코딩을 못하기 때문에 글자가 깨집니다.

오픈 소스들에서는 기본 인코딩이 .iso-8859-1(iso latin 1)으로 되어 있는 경우가 많은데 이 방식에서는 한글 표현이 안됩니다.

mysql 은 기본이 iso-8859-1이기때문에 한글 사용불가하다.

그래서 “utf-8”로 지정해야 한다.

b ->byte 오라클 3byte인데 byte로 하면 9byte이다.

substr 문자 수 가지고

substrb byte수로 해야 한다 . 한글자에 에 3byte

      한글은 2혹은 3으로 되여있다.

반응형

'Study > DB' 카테고리의 다른 글

DB-6  (0) 2020.09.18
DB-5  (0) 2020.09.17
DB-4  (0) 2020.09.15
DB-3  (0) 2020.09.15
DB-2  (0) 2020.09.13

+ Recent posts