2017년 10월 24일 화요일

MySQL JOIN 정리

JOIN

다른 테이블 간의 데이터를 연결시켜 사용하는 것 

INNER 조인

일반적인 용도에 사용되며, 조건에 맞는 데이터를 두 테이블에서 모두 추출해낸다.

예) 
1
2
3
4
select board.bnum, board.title, reply.rnum
from free_board as board join
free_reply as reply 
on board.bnum = reply.bnum
cs
결과를 보면 게시물의 bnum과 댓글의 bnum이 같은 결과만 가져오는걸 알 수 있다. 

LEFT/RIGHT 조인

기준 테이블을 설정해 준다. 
FROM A LEFT/RIGHT JOIN B ON ~ 형태이며 레프트 조인은 A가 기준 라이트 조인은 B가 기준이 된다.  

예)
1
2
3
4
select board.bnum, board.title, reply.rnum
from free_board as board left join
free_reply as reply 
on board.bnum = reply.bnum
cs
결과를 보면 board가 기준의 되었기 때문에 조건에 맞지 않아 rnum이 없더라도 board의 bnum은 모두 불러오고 rnum이 없더라도 null 값으로 표기함을 알 수 있다.

INNER JOIN = JOIN
LEFT OUTER JOIN = LEFT JOIN
RIGHT OUTER JOIN = RIGHT JOIN 


CROSS JOIN 조인

집합에서의 곱 개념이며, A={a, b, c} B={1,2,3,4} 이면
A CROSS JOIN은 (a,1)(a,2)(a,3)(a,4)(b,1)(b,2).....(c,3)(c,4)가 된다. 


참고

2017년 10월 23일 월요일

Node.js 공부[4]

4챕터

노드의 기본 기능 알아보기 이다.
이 챕터에서는 서버를 만들기 전에 알아야 할 기본 내용을 다루고 있다.

주소 문자열과 요청 파라미터 다루기

url 모듈을 사용하여 일반 주소 문자열을 URL객채로 만들거나 URL객체서 일반 문자열로 변환하는 것을 쉽게 할 수 있다.

URL객체의 속성 중 query속성은 요청 파라미터의 정보를 가지고 있다. 요청 파라미터는 & 기호로 구분되는데 querystring모듈을 통해 쉽게 분리할 수 있다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/*
주소 문자열
*/
var url = require('url');
//주소 문자열을 URL 객체로 만들기
//parse(): 주소 문자열으 ㄹ파싱하여 URL 객체로 만들어준다.
var curURL = url.parse('https://www.google.co.kr/search?q=%E3%85%8E&oq=%E3%85%8E&aqs=chrome..69i57j69i61l3j0l2.1980j0j7&sourceid=chrome&ie=UTF-8');
//URL 객체를 주소 문자열로 만들기
//format(): URL객체를 주소 문자열로 반환한다.
var curStr = url.format(curURL);
console.log('주소 문자열: %s', curStr);
console.dir(curURL);
/*
요청 파라미터 확인하기
*/
var querystring = require('querystring');
var param = querystring.parse(curURL.query);
console.log('요청 파라미터 중 query의 값: %s', param.query);
//stringify() : 요청 파라미터 객체를 문자열로 
console.log('원본 요청 파라미터 : %s', querystring.stringify(param));
cs

이벤트

노드는 대부분 이벤트를 기반으로 하는 비동기 방식으로 처리한다.  그리고 비동기 방식으로 처리하기 위해서는 서로 이벤트를 전달한다. 이벤트는 한쪽에서 다른 쪽으로 알림 메시지를 보내는 것과 비슷하다. 노드는 이런 이벤트를 보내고 받을 수 있도록 EventEmitter라는 것을 만들었다.
노드의 객체는 EventEmitter를 상속받을 수 있으며, 상송 받은 후에는 EventEmitter 객체의 on()과 emit()메소드를 사용할 수 있다.

EventEmitter의 주요 메소드이다
on(event, listener): 지정한 이벤트의 리스터를 추가한다.
once(event, listener): 지정한 이벤트의 리스터를 추가하지만 한 번 실행한 후에는 자동으로 리스너가 제거된다.
removeListener(event, listener): 지정한 이벤트에 대한 리스너를 제거한다.
1
2
3
4
5
6
7
8
9
10
11
process.on('tick'function(count){
    console.log('tick 이벤트 발생함 : %s ', count);
});
//setTimeout을 이용하여 2초 후에 동작 설정
setTimeout(function(){
    console.log('2초 후에 tick 이벤트 전달 시도');
    
    //emit를 이용해 tick이벤트를 process객체로 전달
    process.emit('tick''2');
},2000);
cs


파일 다루기

노드는 동기식 IO와 비동기식 IO 기능을 함께 제공한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/*
동기식 읽기
*/
var fs = require('fs');
//readFileSync: 동기식 파일 읽기
var data = fs.readFileSync('./package.json''utf-8');
console.log(data);
/*
비동기식 읽기
*/
//raedFile 메소드를 실행하면서 세번째 파라미터로 전달된 함수는 파일을 읽어들이는 작업이 끝났을때 호출됨
//이때, 2개의 파라미터 err와 data를 전달 받아 오류가 발생했는지 아니면 제대로 실행했는지 알 수 있음
fs.readFile('./package.json','utf-8'function(err, data2){
    console.log(data2);
});
console.log('package 파일을 읽도록 요청');
/*
파일에 데이터 쓰기 예제
*/
fs.writeFile('./output.txt''Hello'function(err){
    if(err){
        console.log('Error: ' + err);
    }
    
    console.log('output.txt 쓰기 완료');
})
cs


버퍼

버퍼 객체는 바이너리 데이터를 읽고 쓰는데 사용한다. new연산자를 사용해 새로운 바퍼 개체를 만들 수 있으며, 바이트 데이터 크기만 지정해주면 된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/*
버퍼*/
//버퍼 객체를 크기만 지정하여 만든 후 문자열 작성
var output = '안녕1';
var buffer1= new Buffer(10);
var len = buffer1.write(output, 'utf8');
console.log('첫 번째 버퍼의 문자열: %s', buffer1.toString());
//버퍼 객체를 문자열을 이용해 만들기
var buffer2 = new Buffer('안녕2''utf8');
console.log('두 번째 버퍼 객체의 문자열: %s', buffer2.toString());
//타입 확인
console.log('버퍼 객체의 타입: %s', Buffer.isBuffer(buffer1));
//버퍼 객체에 들어 있는 문자열 데이터를 문자열 변수로 만들기
var byteLen = Buffer.byteLength(output);
var str1 = buffer1.toString('utf8'0, byteLen);
var str2 = buffer2.toString('utf8');
//첫 번째 버퍼 객체의 문자열을 두 번째 버퍼 객체로 복사
buffer1.copy(buffer2, 0,0 , len);
console.log('두 번째 버퍼에 복한 후의 문자열: %s', buffer2.toString('utf8'));
//두 개의 버퍼 붙이기
var buffer3 = Buffer.concat([buffer1,buffer2]);
console.log('두 개의 버퍼를 붙인 후의 문자열: %s', buffer3.toString('utf8'));
cs


스트림 단위로 파일 읽고 쓰기 

파일을 읽거나 쓸 때는 데이터 단위가 아닌 스트림 단위로 처리할 수 있다. 스트림은 데이터가 전달되는 통로와 같은 개념..?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var fs = require('fs');
//createReadStream(path[,options]) - 파일을 읽기 위한 스트림 객체 만들기
var infile = fs.createReadStream('./output.txt', {flags:'r'});
//createWriteStream(path[,options]) - 파일을 쓰기 위한 스트림 객체 만들기
var outfile = fs.createWriteStream('./output2.txt', {flags:'w'});
infile.on('data', function(data){
    console.log('읽어 들인 데이터', data);
    outfile.write(data);
});
infile.on('end', function(){
    console.log('파일 읽기 종료');
    outfile.end(function(){
        console.log('파일 쓰기 종료');
    });
});
var outfile2 = fs.createWriteStream('./output3.txt',{flags:'w'});
//pipe를 이용해 두 개의 스트림을 붙일 수 있다.
infile.pipe(outfile2);
console.log('파일복사 방법2')
cs

fs모듈로 디렉터리 만들기

1
2
3
4
5
6
7
8
9
10
11
var fs = require('fs');
fs.mkdir('./docs'0666, function(err){
    if(err) throw err;
    console.log('새로운 docs 폴더를 만들었습니다.');
    
    fs.rmdir('./docs', function(err){
        if(err) throw err;
        console.log('docs 폴더를 삭제했습니다.');
    });
});
cs

로그 파일 남기기

프로그램의 크기가 커질 수록 로그의 양도 많아지고 로그를 보고간했다가 나중에 확인해야하는 경우도 생긴다. 
책에선 winston 모듈을 사용한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
var winston = require('winston');                    // 로그 처리 모듈
var winstonDaily = require('winston-daily-rotate-file');        // 로그 일별 처리 모듈
var moment = require('moment');                    // 시간 처리 모듈
function timeStampFormat() {
    return moment().format('YYYY-MM-DD HH:mm:ss.SSS ZZ'); 
};
var logger = new (winston.Logger)({
    transports: [
        new (winstonDaily)({
            name: 'info-file',
            filename: './log/server',
            datePattern: '_yyyy-MM-dd.log',
            colorize: false,
            maxsize: 50000000,
            maxFiles: 1000,
            level: 'info',
            showLevel: true,
            json: false,
            timestamp: timeStampFormat
        }),
        new (winston.transports.Console)({
            name: 'debug-console',
            colorize: true,
            level: 'debug',
            showLevel: true,
            json: false,
            timestamp: timeStampFormat
        })
    ],
    exceptionHandlers: [
        new (winstonDaily)({
            name: 'exception-file',
            filename: './log/exception',
            datePattern: '_yyyy-MM-dd.log',
            colorize: false,
            maxsize: 50000000,
            maxFiles: 1000,
            level: 'error',
            showLevel: true,
            json: false,
            timestamp: timeStampFormat
        }),
        new (winston.transports.Console)({
            name: 'exception-console',
            colorize: true,
            level: 'debug',
            showLevel: true,
            json: false,
            timestamp: timeStampFormat
        })
    ]
});
//로그 테스트
var fs = require('fs');
var inname = './output.txt';
var outname = './output2.txt';
fs.exists(outname, function (exists) {
    if (exists) {
        fs.unlink(outname, function (err) {
            if (err) throw err;
            logger.info('기존 파일 [' + outname +'] 삭제함.');
        });
    }
    
    var infile = fs.createReadStream(inname, {flags: 'r'} );
    var outfile = fs.createWriteStream(outname, {flags: 'w'});
    infile.pipe(outfile);
    logger.info('파일 복사 [' + inname + '] -> [' + outname + ']');
});
cs

2017년 10월 22일 일요일

Node.js 공부[3]

3챕터

노드의 자바스크립트와 친해지기 이다. 
이 챕터에서는 노드에 본격적으로 들어가기 전에 자바스크립트에 대해 간단히 소개하고 있다.

객체와 함수

자바 스크립트는 자바나 c와 다르게 자료형을 명시하지 않아도 된다.
자바스크립트에서는 Boolean, Number, String, undefined, null, Object 등의 자료형을 사용할 수 있으며, 코드에서는 var 키워드만을 사용하므로 타입을 바로 확인할 수 는 없다.
하지만 typeof연산자로 타입을 확인할 수 있다.

다음은 간단한 변수와 객체를 간단히 생성해본 예제이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var age=20;
console.log('나이: %d', age);
var name='소녀시대';
console.log('이름: %s'name);
//간단한 객체 생성
var Person ={};
Person['age'=20;
Person['name'= '소녀시대';
Person.mobile = '010-1000-1000';
console.log('나이: %d', Person.age);
console.log('이름: %s', Person.name);
console.log('전화번호: %d', Person.mobile);
cs

자바스크립트가 자료형을 표시하지 않기 때문에 함수를 호출하는 형도 약간 달라진다.
함수 선언 방식을 예제를 통해 보자
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//함수 선언 -자료형을 따로 안해준다는 특징이 있다. 
function add(a,b){
    return a+b;
};
var result = add(10,10);
console.log('더하기(10,10) : %d', result);
//다른 방식의 함수 선언
var add2 = function(a,b){
    return a+b;
}
var result2 = add2(10,10);
console.log('더하기2(10,10) : %d', result2);
cs
자바스크립트는 이렇게 변수에 함수를 할당하는 경우도 많다고 한다.

함수는 객체 안에 속성으로도 들어갈 수도 있다. 2가지 예제가 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var Person={};
Person['age'=20;
Person['name'='소녀시대';
var oper =function(a,b){
    return a+b;
};
Person['add'= oper;
console.log('더하기: %d', Person.add(10,10));
//객체를 만들면서 동시에 속성 초기화
var Person2={
    age:20,
    name:'소녀시대',
    add2: function(a,b){
        return a+b;
    }
};
console.log('더하기2: %d', Person2.add2(10,10));
cs
같은 결과가 나온다. 

배열

배열은 여러 개의 데이터를 하나의 변수에 담아 둘 수 있다.
배열은 대괄호를 통해 만들 수 있다. 그렇게 어렵지 않는 내용이니 예제들을 통해 이해하자
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
//Users라는 배열 생성
var Users = [{name:'소녀시대', age:20}, {name'걸스데이', age:22}];
//이름이 티아라인 객체를 push()를 통해 추가한다.
Users.push({name:'티아라',age:23});
//변수에 함수를 할당할 수 있는 것처럼 배열의 각 요소에도 함수를 직접 할당할 수 있다.
var add = function(a,b){
    return a+b;
};
Users.push(add);
//add가 4번째로 추가되었기때문에 User[3]으로 접근한다
console.log('함수 실행: %d', Users[3](10,10));
//배열 요소 확인하는 방법
console.log('배열 요소 확인 %s', Users[1].name);
//forEach 문을 통해 반복문을 수행하고 있다. 
Users.forEach(function(item, index){
    console.log('배열 요소 #'+ index + ':%s', item.name);
});
//배열의 끝에 있는 요소를 삭제한다. 
Users.pop();
//요소 확인을 해보면 마지막에 push된 add가 삭제된 것을 알 수 있다.
Users.forEach(function(item, index){
    console.log('pop 후 배열 요소 확인 #'+ index + ':%s', item.name);
});
//unshift는 배열의 맨앞에 추가한다. shift는 반대로 맨앞 요소를 제거한다. 
Users.unshift({name:'add', age:10});
Users.forEach(function(item, index){
    console.log('unshift 후 배열 요소 확인 #'+ index + ':%s', item.name);
});
//delete를 통해 중간의 요소를 삭제할 수 있다. 삭제해도 빈칸으로 남는듯? 길이를 출력해보면 여전히 4로 나온다.
delete Users[1];
console.log('delete로 삭제');
console.dir(Users);
console.log(Users.length); 
//slice를 통해 배열 요소를 여러개를 한꺼번에 추가하거나 삭제할 수 있다.
//두번째 인자를 0으로 준 후 추가하려는 객체를 파라미터로 전달하면 추가할 수 있다. 
Users.splice(0,0,{name:'추가'});
console.log('splice로 추가');
console.dir(Users);
//1번인덱스 부터 3개를 삭제한다.
Users.splice(1,3);
console.log('splice로 삭제');
console.dir(Users);
//또한 변수에 splice로 자른 배열을 저장할 수 있다.
var sliceUsers = Users.splice(0,1);
console.log('변수에 splice로 자른 배열 저장');
console.dir(sliceUsers);
cs

결과 



콜백 함수

자바스크립트 변수에는 숫자나 문자열 같은 데이터, 객체, 함수를 할당할 수있다. 이렇게 변수에 함수를 할당할 수 있다는 특징은 함수를 호출할 때 다른 함수를 파라미터로 전달하거나 함수 안에서 또 다른 함수를 만들어 반환할 수 있다는 뜻이다.

책의 예제이다.
이해가 조금 부족한 것 같으니 더 공부해야할 것같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/*
함수를 호출했을 때 또 다른 함수를 파라미터로 전달하는 방법
*/
//add에 callback 이라는 함수의 파라미터가 쓰인다
function add (a,b, callback){
    var result = a + b;
    
    //더한 값을 파라미터로 전달된 콜백 함수를 호출하면서 그 콜백함수로 전달한다. 
    callback(result);
};
//add함수 호출
//아까 callback(result)형태로 전달했으므로 function(res)형태엔 res에 더한 값이 저장 된다.
add(10,10function(res){
    console.log('파라미터로 전달된 콜백 함수 호출됨');
    console.log('더하기 (10,10)의 결과: %d', res);
    
});
/*
함수 안에서 값을 반환할 때 새로운 함수를 만들어 반환하는 방법
*/
//add2에는 callback2 라는 함수를 파라미터로 쓴다
function add2(a,b,callback2){
    var result2 = a+b;
    //더한 값 result2 를 callback에 넣는다
    callback2(result2);
    
    //count를 줘서 add2안의 history가 몇번 실행됬는지 볼 수 있다.
    var count = 0;
    var history = function(){
        count++;
        return count + '>>' + a + '+' + b + '=' + result2;
    };
    
    return history;
};
var add_history = add2(1010function(res2){
    console.log('파라미터로 전달된 콜백함수 호출됨');
    console.log('더하기(10,10)의 결과: %d', res2);
});
//콘솔창으로 count의 변화를 볼 수 있다. 
console.log('결과 값으로 받은 함수 실행 결과: '+ add_history());
console.log('결과 값으로 받은 함수 실행 결과: '+ add_history());
cs

프로토타입 객체

자바스크립트는 클래스는 개념이 없고, 기존의 객체를 복사하거나 객체의 특성을 확장하여 새로운 객체를 생성하는 프로토타입 기반의 언어이다. 프로토타입을 이용하여 새로운 객체를 만들고 이것이 또 다른 객체의 원형이 될 수 있다.

책의 예제 이다. 이것도 공부를 좀 더 해야할 것같다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function Person(name, age){
    this.name = name;
    this.age = age;
}
//객체에 속성을 추가하고 싶다면 객체.prototype.속성 = ~~ 으로 할 수 있다.
//Person의 속성에 walk라는 함수를 추가한다. 
Person.prototype.walk = function(speed){
    console.log(speed +'속도로 걸어갑니다.');
}
var person1 = new Person('소녀시대'20);
var person2 = new Person('걸스데이'22);
console.log(person1.name + '객체의 walk(10)을 호출합니다.');
person1.walk(10);
cs

참고할 것!
콜백 관련

프로토타입 관련