Infra/cloud

[AFOS] 6주차 데이터베이스 서비스

미니문92 2021. 7. 19. 21:33

1. 기초 DB 이론

DBMS 개요

  • 데이터베이스 : '데이터의 집합' 혹은 '데이터의 저장공간' 자체 (주로 파일로 구성됨)을 의미
  • DBMS(Database Management System) : 데이터베이스를 관리/운영하는 역할(시스템)
  • DBMS 종류

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

 

  • DBMS 특징
    1. 데이터의 무결성, 보안, 데이터 중복의 최소화
    2. 프로그래밍 언어를 통하여 응용 프로그램 제작 및 수정이 쉬워짐(자동화 등)

 

  • 데이터베이스의 발전
    • 오프라인 -> 파일시스템 사용 -> DBMS

 

  • DBMS 분류
    1. 계층형 DBMS
    2. 망형 DBMS
    3. 관계형 DBMS(MySQL, Oracle 등)
    4. 객체지향형 DBMS
    5. 객체관계형 DBMS
  • 관계형 DBMS 는 '데이터베이스 테이블' 이라 불리는 최소단위로 구성, 테이블은 하나 이상의 열로 구성
  • 테이블을 부르는 다른 용어 : relation, entity 

 

  • SQL : 데이터베이스를 조작하는 언어
    1. DBMS 제작 회사와 독립적
    2. 다른 시스템으로 이식성이 좋다
    3. 표준이 계속 발전한다 - SQL은 국제 표준화 기관에서 표준화된 내용을 계속 발표
    4. 대화식 언어
    5. 분산형 클라이언트/서버 구조

 


MySQL

  • Oracle 사에서 제작한 DBMS 소프트웨어로 오픈소스로 제공
  • 비상업용, 교육용으로는 제한이 없지만 상용으로 사용시 라이선스 취득 비용 필요
  • 초기 MySQL 개발자들이 독립해서 만든 MariaDB 사용 권장. MySQL 과 대부분 호환

 

 

MariaDB 간단 실습

  • CloudFormation 스택 생성 - 링크 클릭 후 템플릿 파일로 기본 환경 자동 배포 
  • 파라미터(KeyName - 자신의 SSH 키 선택) 다음 클릭 → 다음 클릭 → 스택 생성 클릭
  • WebSrv 의 퍼블릭 IP 로 SSH 접속
# IP확인 및 DBSrv ping 테스트
[ec2-user@WebSrv ~]$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 02:55:07:27:07:3a brd ff:ff:ff:ff:ff:ff
    inet 10.1.1.10/24 brd 10.1.1.255 scope global dynamic eth0
       valid_lft 3515sec preferred_lft 3515sec
    inet6 fe80::55:7ff:fe27:73a/64 scope link
       valid_lft forever preferred_lft forever
       
[ec2-user@WebSrv ~]$ ping 10.1.2.10
PING 10.1.2.10 (10.1.2.10) 56(84) bytes of data.
64 bytes from 10.1.2.10: icmp_seq=1 ttl=255 time=1.13 ms
64 bytes from 10.1.2.10: icmp_seq=2 ttl=255 time=1.10 ms
64 bytes from 10.1.2.10: icmp_seq=3 ttl=255 time=1.15 ms
64 bytes from 10.1.2.10: icmp_seq=4 ttl=255 time=1.10 ms
^C
--- 10.1.2.10 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 1.101/1.123/1.155/0.021 ms


# DBSrv 로 MySQL 접속 (계정 정보: root/qwe123)
[ec2-user@WebSrv ~]$ mysql -h 10.1.2.10 -uroot -pqwe123
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 6
Server version: 5.5.68-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>
  • DBSrv 의 퍼블릭 IP로 SSH 접속
# IP 확인
[ec2-user@DBSrv ~]$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 0a:d4:3a:99:cb:2e brd ff:ff:ff:ff:ff:ff
    inet 10.1.2.10/24 brd 10.1.2.255 scope global dynamic eth0
       valid_lft 3492sec preferred_lft 3492sec
    inet6 fe80::8d4:3aff:fe99:cb2e/64 scope link
       valid_lft forever preferred_lft forever
       

# MySQL 접속 (계정 정보: root/qwe123)
[ec2-user@DBSrv ~]$ mysql -uroot -pqwe123
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 7
Server version: 5.5.68-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>
  • MariaDB monitor 에서 기본적인 SQL 문 사용
# MariaDB monitor 접속
Welcome to the MariaDB monitor.  Commands end with ; or \g.
...

# DB 서버의 상태 정보
MariaDB [(none)]> status;

# 데이터베이스(=스키마) 확인
SHOW DATABASES;

# employees 데이터베이스 선택 하기
USE employees;
MariaDB [(none)]> USE employees;
MariaDB [employees]>

# 테이블 확인
SHOW TABLES;

# 테이블 필드와 타입 등 정보 확인
DESC employees;

# employees 테이블 조회 하기
SELECT * FROM employees;
SELECT * FROM employees LIMIT 10;
SELECT * FROM employees LIMIT 100;

# 특정 열(컬럼=필드) 기준 오름/내림차순으로 정렬 조회 하기
# -- 공백이 있는 개체의 이름 사용 시는 백틱(backtick) `` 으로 묶어줘야 하나의 이름으로 인식함
SELECT * FROM employees ORDER BY `emp_no` DESC LIMIT 100;
SELECT * FROM employees ORDER BY `birth_date` ASC LIMIT 100;

# 특정 열(컬럼) 만 출력
SELECT first_name, last_name, gender FROM employees LIMIT 50;

# 특정 행(=로우=레코드)만 출력 - Mary 이름(first_name) , Baba 성(last_name)
SELECT * FROM employees WHERE first_name = 'Mary';
SELECT * FROM employees WHERE last_name = 'Baba';

 


데이터베이스 구축 및 활용 절차

  • 생성 및 데이터(레코드) 생성 변경 삭제
# 스키마(=데이터베이스) 생성
CREATE SCHEMA `shopdb`;
SHOW DATABASES;
USE shopdb;

# 테이블 생성 - (Workbench) GUI 설정 보여주기 - 아래 복붙해서 적용하기
CREATE TABLE `shopdb`.`memberTBL` (
  `memberID` CHAR(8) NOT NULL,
  `memberName` CHAR(5) NOT NULL,
  `memberAddress` CHAR(20) NULL,
  `age` INT NOT NULL,
  PRIMARY KEY (`memberID`));

# 테이블 정보 확인
DESC memberTBL;

# 데이터 넣기 - (Workbench) GUI 설정 보여주기 - (카톡 멤버 정보 받기) - 아래 복붙해서 적용하기
SELECT * FROM memberTBL;

# 행(=데이터=레코드) 1개 넣기
INSERT INTO memberTBL VALUES ('Beas', '베아스', '인천 연수구 송도동', '77');
-- 위 아래 명령어 동일
INSERT INTO `shopdb`.`memberTBL` (`memberID`, `memberName`, `memberAddress`, `age`) VALUES ('Beas', '베아스', '인천 연수구 송도동', '77');

## 카톡 멤버 정보 받아서 넣기
INSERT INTO memberTBL VALUES ('Gasida', '가시다', '서울 잠실동 분당구', '30');
INSERT INTO memberTBL VALUES ('User4', '유나', '경기 성남시 분당구', '27');
INSERT INTO memberTBL VALUES ('Minyoung', '민영', '경기도 부천시 중동', '30'); 
INSERT INTO memberTBL VALUES ('Eunji', '은지', '인천 남구 주안동', '28');
INSERT INTO memberTBL VALUES ('Yujeong', '유정', '서울 은평구 증산동', '29'); 

# 조회
SELECT * FROM memberTBL;
SELECT memberName, memberAddress FROM memberTBL;
SELECT * FROM memberTBL ORDER BY `age` ASC;
SELECT * FROM memberTBL WHERE age = 27;

# 행(=데이터=레코드) 삭제
DELETE from memberTBL where memberID='Beas';
SELECT * FROM memberTBL;

# 행(=데이터=레코드) 변경(=업데이트)
UPDATE memberTBL SET memberID='Yuna' WHERE memberName='유나';
SELECT * FROM memberTBL;

 

Web Server vs WAS

더보기

Web server : Apache, IIS, Nginx ...

  • 웹 브라우저(클라이언트)로부터 HTTP 요청을 받아 HTML 문서와 같은 정적 컨텐츠를 클라이언트에게 제공하는 컴퓨터
  • 정적 컨텐츠
    1. 요청 인자 값에 상관없이 달라지지 않는 컨텐츠(html, jpeg, css ...)
    2. 어느 사용자 요청이든 항상 동일한 컨텐츠

 

  • Web Server의 기능
    1. 클라이언트로부터 HTTP 요청을 받을 수 있다.
    2. 정적 컨텐츠 요청시 정적 컨텐츠(html,jpeg,css ...)를 제공
    3. 동적 컨텐츠 요청시 WAS로 전달하여 WAS가 처리한 결과를 클라이언트에 전달

 

Web Application Server (WAS) : Tomcat ,WebSphere, JEUS ...

  • DB 조회나 다양한 로직 처리를 요구하는 동적인 컨텐츠를 제공하기 위해 만들어진 컴퓨터
  • 웹 애플리케이션과 서버 환경을 만들어 동작시키는 기능을 제공하는 소프트웨어 프레임워크
  • 웹 애플리케이션을 실행시켜 필요한 기능을 수행하고 그 결과를 웹 서버에 전달
  • php, jsp, asp와 같은 언어들을 사용해 동적인 페이지를 생성할 수 있는 서버
  • 프로그램 실행 환경과 데이터베이스 접속 기능 제공
  • 비즈니스 로직 수행 가능
  • 웹서버 + 웹 컨테이너(jsp, servlet을 실행시킬 수 있는 소프트웨어)
  • 자바 계열에서는 웹 애플리케이션 컨테이너라 부름(웹 애플리케이션이 배포되는 공간)

 

  • 동적 컨텐츠
    • 요청 인자에 따라 바뀔 수 있는 컨텐츠

 

  • WAS의 기능
    1. 클라이언트로부터 HTTP 요청을 받을 수 있다. (대부분의 WAS는 Web Server 내장)
    2. 요청에 맞는 정적 컨텐츠(html, jpeg, css ...)를 제공
    3. DB 조회나 다양한 로직 처리를 통해 동적 컨텐츠를 제공

 

Web Server는 왜 필요할까?

  • Web Server를 같이 사용했을 때의 장점
    1. 책임 분할을 통한 서버 부하 방지 : 정적 컨텐츠는 Web server, 동적 컨텐츠는 WAS
    2. 여러 대의 WAS 로드 밸런싱 : WAS가 처리해야 하는 요청을 여러 WAS가 나누어서 처리 가능
    3. 여러 대의 WAS Health check
    4. 보안 : 리버스 프록시를 통해 실제 서버를 외부에 노출하지 않을 수 있음
Health check란?
1. 서버에 주기적으로 HTTP 요청을 보내 서버의 상태를 확인(ex 특정 url 요청에 200응답이 오는지?)
2. Interval : health check를 통해 서버 상태를 확인하는 요청을 날리는 주기(default : 5초)
3. Fails : 몇 번 연속 실패하면 서버가 비정상이라고 인지(default : 1회)
4. Passes : 서버가 복구되어 요청이 몇 번 연속 성공하면 서버가 정상이라고 인지(default : 1회)

 

 

 


HTML과 PHP와 MySQL 관계

생활코딩

  • HTML 파일에 <FORM> 태그 사용. 입력한 정보가 서버의 PHP 파일에 전달.
  • <FORM> 태그 안에 데이터를 채우기 위해서 <INPUT> 태그도 사용.
  • MySQL 과 다른 응용 프로그램(PHP, C#, Java, Python 등)과 연계

 

  • WebSrv의 퍼블릭 IP로 SSH 접속 후 아래 작업 실행 -> 웹브라우저에서 접속 확인

http://13.125.47.174 접속

 

파일 트리 확인

 

 

 


PHP와 MySQL의 기본 연동

더보기

WebSrv 의 퍼블릭 IP로 SSH 접속 후 아래 작업 실행 -> 웹 브라우저에서 접속 확인

  • [1.php] DB 접속
http://13.125.47.174/php_mysql/1.php 접속
<?php
   $db_host="10.1.2.10"; # MySQL IP 주소
   $db_user="root"; # MySQL 계정
   $db_password="qwe123"; # MySQL 암호 
   $db_name=""; # 스키마 이름
   $con=mysqli_connect($db_host, $db_user, $db_password, $db_name);
   if ( mysqli_connect_error($con) ) {
	   echo "MySQL 접속 실패 !!", "<br>";
	   echo "오류 원인 : ", mysqli_connect_error();
	   exit();
   }
   echo "MySQL 접속 완전히 성공!!";
   mysqli_close($con);
?>
  • [2.php] sqlDB 데이터베이스를 생성하는 PHP 코드 작성 : 4행에 sql 문 넣고 5행에서 SQL 실행해서 데이터베이스를 생성
[ec2-user@WebSrv ~]$ while true; do mysql -h 10.1.2.10 -uroot -pqwe123 -e "show databases;"; date; sleep 1; done
+--------------------+
| Database           |
+--------------------+
| information_schema |
| employees          |
| mysql              |
| performance_schema |
| sample             |
| shopdb             |
| sqlDB              |
+--------------------+
Tue Jul 20 07:39:54 UTC 2021
+--------------------+
| Database           |
+--------------------+
| information_schema |
| employees          |
| mysql              |
| performance_schema |
| sample             |
| shopdb             |
| sqlDB              |
| sqlDB2             |
+--------------------+
Tue Jul 20 07:42:40 UTC 2021
<?php
   $con=mysqli_connect("10.1.2.10", "root", "qwe123", "") or die("MySQL 접속 실패 !!");
         
   $sql="CREATE DATABASE sqlDB2";
   $ret = mysqli_query($con, $sql);
   
   if($ret) {
	   echo "sqlDB가 성공적으로 생성됨.";
   }
   else {
	   echo "sqlDB 생성 실패!!!"."<br>";
	   echo "실패 원인 :".mysqli_error($con);
   }
   
   mysqli_close($con);
?>
  • [3.php] 테이블 생성
[ec2-user@WebSrv ~]$ while true; do mysql -h 10.1.2.10 -uroot -pqwe123 -e "USE sqlDB2;show tables;"; date; sleep 1; done
Tue Jul 20 07:41:55 UTC 2021
+------------------+
| Tables_in_sqlDB2 |
+------------------+
| userTbl          |
+------------------+
Tue Jul 20 07:43:24 UTC 2021
<?php
   $con=mysqli_connect("10.1.2.10", "root", "qwe123", "sqlDB2") or die("MySQL 접속 실패 !!");

   $sql ="
	   CREATE TABLE userTbl 
		( userID  	CHAR(8) NOT NULL PRIMARY KEY,
		  name    	VARCHAR(10) NOT NULL,
		  birthYear   INT NOT NULL,
		  addr	  	CHAR(2) NOT NULL,
		  mobile1	CHAR(3),
		  mobile2	CHAR(8),
		  height    	SMALLINT,
		  mDate    	DATE
		)
   ";
 
   $ret = mysqli_query($con, $sql);
 
   if($ret) {
	   echo "userTBL이 성공적으로 생성됨..";
   }
   else {
	   echo "userTBL 생성 실패!!!"."<br>";
	   echo "실패 원인 :".mysqli_error($con);
   }
 
   mysqli_close($con);
?>
  • [4.php] 데이터 입력
[ec2-user@WebSrv ~]$ while true; do mysql -h 10.1.2.10 -uroot -pqwe123 -e "USE sqlDB2;select * from userTbl;"; date; sleep 1; don    e
Tue Jul 20 07:46:50 UTC 2021
Tue Jul 20 07:46:51 UTC 2021
Tue Jul 20 07:46:52 UTC 2021
Tue Jul 20 07:46:53 UTC 2021
Tue Jul 20 07:46:54 UTC 2021
Tue Jul 20 07:46:55 UTC 2021
Tue Jul 20 07:46:56 UTC 2021
Tue Jul 20 07:46:57 UTC 2021
Tue Jul 20 07:46:58 UTC 2021
Tue Jul 20 07:46:59 UTC 2021
+--------+-----------+-----------+--------+---------+---------+--------+------------+
| userID | name      | birthYear | addr   | mobile1 | mobile2 | height | mDate      |
+--------+-----------+-----------+--------+---------+---------+--------+------------+
| BBK    | 바비킴    |      1973 | 서울   | 010     | 0000000 |    176 | 2013-05-05 |
| EJW    | 은지원    |      1972 | 경북   | 011     | 8888888 |    174 | 2014-03-03 |
| JKW    | 조관우    |      1965 | 경기   | 018     | 9999999 |    172 | 2010-10-10 |
| JYP    | 조용필    |      1950 | 경기   | 011     | 4444444 |    166 | 2009-04-04 |
| KBS    | 김범수    |      1979 | 경남   | 011     | 2222222 |    173 | 2012-04-04 |
| KKH    | 김경호    |      1971 | 전남   | 019     | 3333333 |    177 | 2007-07-07 |
| LJB    | 임재범    |      1963 | 서울   | 016     | 6666666 |    182 | 2009-09-09 |
| LSG    | 이승기    |      1987 | 서울   | 011     | 1111111 |    182 | 2008-08-08 |
| SSK    | 성시경    |      1979 | 서울   | NULL    | NULL    |    186 | 2013-12-12 |
| YJS    | 윤종신    |      1969 | 경남   | NULL    | NULL    |    170 | 2005-05-05 |
+--------+-----------+-----------+--------+---------+---------+--------+------------+
Tue Jul 20 07:47:00 UTC 2021
<?php
   $con=mysqli_connect("10.1.2.10", "root", "qwe123", "sqlDB2") or die("MySQL 접속 실패 !!");

   $sql ="
		INSERT INTO userTbl VALUES
		('LSG', '이승기', 1987, '서울', '011', '1111111', 182, '2008-8-8'),
		('KBS', '김범수', 1979, '경남', '011', '2222222', 173, '2012-4-4'),
		('KKH', '김경호', 1971, '전남', '019', '3333333', 177, '2007-7-7'),
		('JYP', '조용필', 1950, '경기', '011', '4444444', 166, '2009-4-4'),
		('SSK', '성시경', 1979, '서울', NULL  , NULL      , 186, '2013-12-12'),
		('LJB', '임재범', 1963, '서울', '016', '6666666', 182, '2009-9-9'),
		('YJS', '윤종신', 1969, '경남', NULL  , NULL      , 170, '2005-5-5'),
		('EJW', '은지원', 1972, '경북', '011', '8888888', 174, '2014-3-3'),
		('JKW', '조관우', 1965, '경기', '018', '9999999', 172, '2010-10-10'),
		('BBK', '바비킴', 1973, '서울', '010', '0000000', 176, '2013-5-5')
   ";
 
   $ret = mysqli_query($con, $sql);
 
   if($ret) {
	   echo "userTBL이 데이터가 성공적으로 입력됨.";
   }
   else {
	   echo "userTBL 데이터 입력 실패!!!"."<br>";
	   echo "실패 원인 :".mysqli_error($con);
   }
 
   mysqli_close($con);
?>
  • [5.php] 데이터 조회
<?php
   $con=mysqli_connect("10.1.2.10", "root", "qwe123", "sqlDB2") or die("MySQL 접속 실패 !!");

   $sql ="
		SELECT * FROM userTbl
   ";
 
   $ret = mysqli_query($con, $sql);
 
   if($ret) {
	   echo mysqli_num_rows($ret), "건이 조회됨.<br><br>";
   }
   else {
	   echo "userTBL 데이터 조회 실패!!!"."<br>";
	   echo "실패 원인 :".mysqli_error($con);
	   exit();
   }
   
   while($row = mysqli_fetch_array($ret)) {
	   echo $row['userID'], " ", $row['name'], " ", $row['height'], " ", "<br>";
   }   
 
   mysqli_close($con);
?>
  • mysql monitor 접속 후 직접 레코드 추가 후 웹 페이지(5.php) 반영 확인 ⇒ 삭제 후 반영도 확인 가능
변경됨
[ec2-user@WebSrv ~]$ mysql -h 10.1.2.10 -uroot -pqwe123
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 46
Server version: 5.5.68-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> USE sqlDB2;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [sqlDB2]> INSERT INTO userTbl VALUES ('AAA', '가시다', 2000, '전주', '019', '1234567', 179, '2015-5-5');
Query OK, 1 row affected (0.00 sec)
  • sqlDB 백업 및 복원
# sqlDB 데이터베이스를 백업
mysqldump -uroot -pqwe123 --database sqlDB2 > backup_sqlDB2.sql

# 테스트를 위해서 sqlDB 삭제
mysql -uroot -pqwe123 -e "drop database sqlDB2;"

# 데이터베이스로 복원
mysql -uroot -pqwe123 -e "CREATE SCHEMA sqlDB2;"
mysql -uroot -pqwe123 -e "source backup_sqlDB2.sql;"
 혹은 mysql -uroot -pqwe123 sqlDB2 < backup_sqlDB2.sql

PHP와 MySQL의 기본 연동 예시 - 회원관리 시스템

더보기
  • [main.html] 초기 화면 : 입력된 아이디를 get 방식으로 PHP에 넘겨줌
<HTML>
<HEAD>
<META http-equiv="content-type" content="text/html; charset=utf-8">
</HEAD>
<BODY>

<h1> 회원 관리 시스템 </h1>

<a href='select.php'> (1) 회원 조회 (조회 후 수정/삭제 가능) </a> <br><br>
<a href='insert.php'> (2) 신규 회원 등록 </a> <br><br>
<FORM METHOD="get"  ACTION="update.php">
	(3) 회원 수정 - 회원 아이디 : <INPUT TYPE ="text" NAME="userID"> 
	<INPUT TYPE="submit"  VALUE="수정">
</FORM>
<FORM METHOD="get"  ACTION="delete.php">
	(4) 회원 삭제 - 회원 아이디 : <INPUT TYPE ="text" NAME="userID"> 
	<INPUT TYPE="submit"  VALUE="삭제">
</FORM>

</BODY>
</HTML>
  • [select.php] 회원 조회 화면
<?php
   $con=mysqli_connect("10.1.2.10", "root", "qwe123", "sqlDB") or die("MySQL 접속 실패 !!");

   $sql ="SELECT * FROM userTbl";
 
   $ret = mysqli_query($con, $sql);   
   if($ret) {
	   //echo mysqli_num_rows($ret), "건이 조회됨..<br><br>";
	   $count = mysqli_num_rows($ret);
   }
   else {
	   echo "userTBL 데이터 조회 실패!!!"."<br>";
	   echo "실패 원인 :".mysqli_error($con);
	   exit();
   } 
   
   echo "<h1> 회원 조회 결과 </h1>";
   echo "<TABLE border=1>";
   echo "<TR>";
   echo "<TH>아이디</TH><TH>이름</TH><TH>출생년도</TH><TH>지역</TH><TH>극번</TH>";
   echo "<TH>전화번호</TH><TH>키</TH><TH>가입일</TH><TH>수정</TH><TH>삭제</TH>";
   echo "</TR>";
   
   while($row = mysqli_fetch_array($ret)) {
	  echo "<TR>";
	  echo "<TD>", $row['userID'], "</TD>";
	  echo "<TD>", $row['name'], "</TD>";
	  echo "<TD>", $row['birthYear'], "</TD>";
	  echo "<TD>", $row['addr'], "</TD>";
	  echo "<TD>", $row['mobile1'], "</TD>";
	  echo "<TD>", $row['mobile2'], "</TD>";
	  echo "<TD>", $row['height'], "</TD>";
	  echo "<TD>", $row['mDate'], "</TD>";
	  echo "<TD>", "<a href='update.php?userID=", $row['userID'], "'>수정</a></TD>";
	  echo "<TD>", "<a href='delete.php?userID=", $row['userID'], "'>삭제</a></TD>";
	  echo "</TR>";	  
   }   
   mysqli_close($con);
   echo "</TABLE>"; 
   echo "<br> <a href='main.html'> <--초기 화면</a> ";
?>
  • [insert.php] 신규 회원 등록
<HTML>
<HEAD>
<META http-equiv="content-type" content="text/html; charset=utf-8">
</HEAD>
<BODY>

<h1> 신규 회원 입력 </h1>
<FORM METHOD="post"  ACTION="insert_result.php">
	아이디 : <INPUT TYPE ="text" NAME="userID"> <br>
	이름 : <INPUT TYPE ="text" NAME="name"> <br> 
	출생년도 : <INPUT TYPE ="text" NAME="birthYear"> <br>
	지역 : <INPUT TYPE ="text" NAME="addr"> <br>
	휴대폰 국번 : <INPUT TYPE ="text" NAME="mobile1"> <br>
	휴대폰 전화번호 : <INPUT TYPE ="text" NAME="mobile2"> <br>
	신장 : <INPUT TYPE ="text" NAME="height"><br>
	<BR><BR>
	<INPUT TYPE="submit"  VALUE="회원 입력">
</FORM>

</BODY>
</HTML>
  • [insert_result.php] 신규 회원 등록 결과
<?php
   $con=mysqli_connect("10.1.2.10", "root", "qwe123", "sqlDB") or die("MySQL 접속 실패 !!");

   $userID = $_POST["userID"];
   $name = $_POST["name"];
   $birthYear = $_POST["birthYear"];
   $addr = $_POST["addr"];
   $mobile1 = $_POST["mobile1"];
   $mobile2 = $_POST["mobile2"];
   $height = $_POST["height"];   
   $mDate = date("Y-m-j");
   
   $sql =" INSERT INTO userTbl VALUES('".$userID."','".$name."',".$birthYear;
   $sql = $sql.",'".$addr."','".$mobile1."','".$mobile2."',".$height.",'".$mDate."')";
   
   $ret = mysqli_query($con, $sql);
 
    echo "<h1> 신규 회원 입력 결과 </h1>";
   if($ret) {
	   echo "데이터가 성공적으로 입력됨.";
   }
   else {
	   echo "데이터 입력 실패!!!"."<br>";
	   echo "실패 원인 :".mysqli_error($con);
   } 
   mysqli_close($con);
   
   echo "<br> <a href='main.html'> <--초기 화면</a> ";
?>
  • [update.php] 회원 정보 수정 : 단, 아이디와 회원가입일은 READONLY 속성으로 수정하지 못하게 했다
<?php
   $con=mysqli_connect("10.1.2.10", "root", "qwe123", "sqlDB") or die("MySQL 접속 실패 !!");
   $sql ="SELECT * FROM userTbl WHERE userID='".$_GET['userID']."'";

   $ret = mysqli_query($con, $sql);   
   if($ret) {
	   $count = mysqli_num_rows($ret);
	   if ($count==0) {
		   echo $_GET['userID']." 아이디의 회원이 없음!!!"."<br>";
		   echo "<br> <a href='main.html'> <--초기 화면</a> ";
		   exit();	
	   }		   
   }
   else {
	   echo "데이터 조회 실패!!!"."<br>";
	   echo "실패 원인 :".mysqli_error($con);
	   echo "<br> <a href='main.html'> <--초기 화면</a> ";
	   exit();
   }   
   $row = mysqli_fetch_array($ret);
   $userID = $row['userID'];
   $name = $row["name"];
   $birthYear = $row["birthYear"];
   $addr = $row["addr"];
   $mobile1 = $row["mobile1"];
   $mobile2 = $row["mobile2"];
   $height = $row["height"];   
   $mDate = $row["mDate"];      
?>

<HTML>
<HEAD>
<META http-equiv="content-type" content="text/html; charset=utf-8">
</HEAD>
<BODY>

<h1> 회원 정보 수정 </h1>
<FORM METHOD="post"  ACTION="update_result.php">
	아이디 : <INPUT TYPE ="text" NAME="userID" VALUE=<?php echo $userID ?> READONLY> <br>
	이름 : <INPUT TYPE ="text" NAME="name" VALUE=<?php echo $name ?>> <br> 
	출생년도 : <INPUT TYPE ="text" NAME="birthYear" VALUE=<?php echo $birthYear ?>> <br>
	지역 : <INPUT TYPE ="text" NAME="addr" VALUE=<?php echo $addr ?>> <br>
	휴대폰 국번 : <INPUT TYPE ="text" NAME="mobile1" VALUE=<?php echo $mobile1 ?>> <br>
	휴대폰 전화번호 : <INPUT TYPE ="text" NAME="mobile2" VALUE=<?php echo $mobile2 ?>> <br>
	신장 : <INPUT TYPE ="text" NAME="height" VALUE=<?php echo $height ?>> <br>
	회원가입일 : <INPUT TYPE ="text" NAME="mDate" VALUE=<?php echo $mDate ?> READONLY><br>
	<BR><BR>
	<INPUT TYPE="submit"  VALUE="정보 수정">
</FORM>

</BODY>
</HTML>
  • [update_result.php] 수정 결과
<?php
   $con=mysqli_connect("10.1.2.10", "root", "qwe123", "sqlDB") or die("MySQL 접속 실패 !!");

   $userID = $_POST["userID"];
   $name = $_POST["name"];
   $birthYear = $_POST["birthYear"];
   $addr = $_POST["addr"];
   $mobile1 = $_POST["mobile1"];
   $mobile2 = $_POST["mobile2"];
   $height = $_POST["height"];   
   $mDate = $_POST["mDate"]; 
   
   $sql ="UPDATE userTbl SET name='".$name."', birthYear=".$birthYear;
   $sql = $sql.", addr='".$addr."', mobile1='".$mobile1."',mobile2='".$mobile2;
   $sql = $sql."', height=".$height.", mDate='".$mDate."' WHERE userID='".$userID."'";
   
   $ret = mysqli_query($con, $sql);
 
    echo "<h1> 회원 정보 수정 결과 </h1>";
   if($ret) {
	   echo "데이터가 성공적으로 수정됨.";
   }
   else {
	   echo "데이터 수정 실패!!!"."<br>";
	   echo "실패 원인 :".mysqli_error($con);
   } 
   mysqli_close($con);
   
   echo "<br> <a href='main.html'> <--초기 화면</a> ";
?>
  • [delete.php] 회원 정보 삭제 → 전체 정보는 불필요하니 아이디와 이름만 보여줌
<?php
   $con=mysqli_connect("10.1.2.10", "root", "qwe123", "sqlDB") or die("MySQL 접속 실패 !!");
   $sql ="SELECT * FROM userTbl WHERE userID='".$_GET['userID']."'";

   $ret = mysqli_query($con, $sql);   
   if($ret) {
	   $count = mysqli_num_rows($ret);
	   if ($count==0) {
		   echo $_GET['userID']." 아이디의 회원이 없음!!!"."<br>";
		   echo "<br> <a href='main.html'> <--초기 화면</a> ";
		   exit();	
	   }		   
   }
   else {
	   echo "데이터 조회 실패!!!"."<br>";
	   echo "실패 원인 :".mysqli_error($con);
	   echo "<br> <a href='main.html'> <--초기 화면</a> ";
	   exit();
   }   
   $row = mysqli_fetch_array($ret);
   $userID = $row['userID'];
   $name = $row["name"];
   
?>

<HTML>
<HEAD>
<META http-equiv="content-type" content="text/html; charset=utf-8">
</HEAD>
<BODY>

<h1> 회원 삭제 </h1>
<FORM METHOD="post"  ACTION="delete_result.php">
	아이디 : <INPUT TYPE ="text" NAME="userID" VALUE=<?php echo $userID ?> READONLY> <br>
	이름 : <INPUT TYPE ="text" NAME="name" VALUE=<?php echo $name ?> READONLY> <br> 
	<BR><BR>
	위 회원을 삭제하겠습니까?	
	<INPUT TYPE="submit"  VALUE="회원 삭제">
</FORM>

</BODY>
</HTML>
  • [delete_result.php] 삭제 결과
<?php
   $con=mysqli_connect("10.1.2.10", "root", "qwe123", "sqlDB") or die("MySQL 접속 실패 !!");

   $userID = $_POST["userID"];
     
   $sql ="DELETE FROM userTbl WHERE userID='".$userID."'";
   
   $ret = mysqli_query($con, $sql);
 
    echo "<h1> 회원 삭제 결과 </h1>";
   if($ret) {
	   echo $userID." 회원이 성공적으로 삭제됨..";
   }
   else {
	   echo "데이터 삭제 실패!!!"."<br>";
	   echo "실패 원인 :".mysqli_error($con);
   } 
   mysqli_close($con);
   
   echo "<br><br> <a href='main.html'> <--초기 화면</a> ";
?>

 

 



2. AWS 데이터베이스 서비스 

 

  • 비관리형(Non-Managed)
    • 사용자가 직접 관리
    • 사용자가 데이터센터를 운영하는 경우
    • 장비 운영, OS 설치 및 운영, 데이터베이스 솔루션 설치 및 운영까지 모두 담당

 

  • 관리형(Managed)
    • 사용자와 AWS가 함께 관리
    • AWS EC2 서버에 데이터베이스 솔루션을 설치 하고 운영하는 경우
    • 장비 운영, OS 설치 및 운영은 AWS가 담당하고, 데이터베이스 솔루션의 설치 및 운영은 사용자가 담당

 

  • 완전관리형(Fully-Managed)
    • AWS가 모두 관리
    • AWS에서 제공하는 RDS 솔루션을 이용하는 경우
    • 장비 운영, OS 설치 및 운영, 데이터베이스 솔루션 설치 및 운영까지 AWS에서 모두 담당

 

  • 서버리스(Serverless)
    • 서버 및 클러스터 관리 전혀 필요 없음
    • 사용량에 따라 자동으로 확장 가능
    • 고 가용성 및 자동 장애 복구 지원
    • 컴퓨팅 사용량 기준으로만 과금

 

출처: https://118k.tistory.com/849 [개발자로 살아남기]

 


AWS 데이터베이스 서비스

 

Amazon RDS

  •  
  • 간단하고 빠른 성능 확장
    1. 데이터베이스 인스턴스 타입을 원하는 타입으로 변경 지원
    2. 필요에 따라 데이터베이스 저장 공간 확장 지원

 

  • 다양한 저장소 옵션 제공
    1. Gereral Purpose(SSD) : 다양한 용도의 비용 효율적인 스토리지
    2. Provisioned IOPS(SSD) : 최대 30,000 IOPS를 지원하는 OLTP 를 위한 고성능 스토리지
    3. Magnetic : 요청수가 적고 작은 워크로드에 적합한 스토리지

 

  • 고가용성을 위한 Multi-AZ 지원
    • 리전 내 다른 리전으로 읽기 복제 구성
    • RDS - Multi-AZ / Read Replica

 

 

  • Amazon RDS Multi-AZ
    • 평상 시 다른 AZ에 백업본 구성
    • AZ로 주 DB 장애 시 자동으로 백업 DB가 동작
    • Active-Standby 구조
    • 동기식 복제

RDS Multi-AZ

 

  • Amazon RDS Read replica
    • 평시 시 DB 동기화
    • 평상 시 읽기 Endpoint URL(Query = SELECT)는 Read Replica 사용 가능 (AWS RDS는 최대 5copy 가능)
    • 읽기 부하 분산
    • 기본값 백업 설정 X
    • 단일리전 / cross-AZ / cross-region 가능
    • 비동기식 복제
    • 장애 시 수동으로 승격

RDS Read replica

 

  • 손쉬운 백업 기능 지원
    • 자동백업
    • 수동 스냅샷

 

  • 사용한만큼만 비용 지불
  • Amazon Aurora : 오픈 소스 호환 상용 수준의 데이터베이스
    • 클라우드에서 제공되는 MySQL과 PostgreSQL 호환 관계형 데이터베이스
    • 1/10 비용으로 상용 데이터베이스 수준의 성능과 가용성 제공
      1. 성능 및 확장성 : Standard MySQl의 5배, Standard PostgreSQL의 3배 쓰루풋; 최대 15개의 읽기 전용 복제본으로 확장
      2. 가용성 및 내구성 : Fault-tolerant, 자가치유 스토리지; 3개의 AZ에 걸쳐 6개의 데이터 복사본 저장; S3에 지속적 백업
      3. 높은 보안성 : 네트워크 분리, Encryption at rest/transit
      4. 완전 관리형 : RDS에서 관리 : 서버관리, 소프트웨어패치, 구성관리, 백업관리 자동화

 

  • Aurora Serverless
    1. 요청시 기동, 사용하지 않을 때 종료
    2. 자동으로 용량 조정
    3. 유연한 확장 구조
    4. 초당 지불, 최소 1분
    5. 자주 사용되지 않거나 예측할 수 없거나 주기적인 워크로드에 적합
    6. HTTP를 통해 쿼리를 실행하기 위한 데이터 API 제공

 

 

 


Amazon DynamoDB

  • 어떤 규모에서든 빠르고 유연한 Key-Value NoSQL 서비스
    1. 대규모로 성능확장 : 일관된 한자리수 밀리초 응답시간; 사실상 무제한 처리량으로 애플리케이션 구축
    2. 서버리스 아키텍처 : 하드웨어 프로비저닝, 소프트웨어 패치 또는 업그레이드는 없음. 자동으로 확장 또는 축소. 데이터를 지속적으로 백업
    3. 엔터프라이즈 수준 보안 : 기본적으로 모든 데이터를 암호화하고 강력한 보안을 위해 IAM과 완전 통합
    4. 글로벌 복제 : 여러 AWS 리전에서 테이블을 쉽게 복제하여 로컬 데이터처럼 빠르게 액세스 할 수 있는 글로벌 애플리케이션 구축

  • DynamoDB On-Demant 기능
    1. 트래픽에 따른 용량 모니터링이나 확장 설정 등이 필요 없음
    2. 트래픽 상승 및 하강 시 읽기/쓰기별 워크로드 자동 수용
    3. 수 밀리초 지연 시간 보장(SLA) 및 동일한 보안 기능 제공
    4. 미리 최소 용량 설정이 필요 없음여, 최대 용량 제한 없이 요청 당 요금 지불 가능

 

출처 : AWS
https://www.slideshare.net/awskorea/database-aws-aws-builders-online-series?qid=c4a92790-f954-453b-9338-e256d778e868&v=&b=&from_search=2

https://www.slideshare.net/awskorea/aws-builders-online-series-aws-184649996?qid=e1e638b4-9674-423e-9cc3-cec10535ee11&v=&b=&from_search=1