나는 위에처럼 char는 고정형이고 남는 공간을 공백으로 채우고

varchar는 가변적이고 공백을 안남기는데

당연히 varchar쓰지 왜 메모리 낭비하는 char를 쓸까에 대한 의문이 있었다

그런데 알고보니 적절히 쓰면 오히려 char가 메모리 공간을 절약할 수 있다는걸 알았다

당연히 그러니까 두개 다 쓰겠지.. 

 

고정형이고 공백으로 채우는 대신 글자수가 정해져있다면?

닉네임이나 아이디같이 길어봤자 10~20글자 내라면?

작은 데이터지만 2배나 되는게 네이버나 구글같이 규모가 큰 사이트의 데이터를 쌓게 된다면?

저 바이트 하나의 차이가 엄청난 데이터를 차지하게 될 것이다.

데이터를 최대한 활용해 관리에 들어가는 비용을 줄여가는것이 회사 입장에서 데이터 관리자의 필요성이니까

 

아래는 너무 비교를 잘해놓으신 분의 글이다

 

 

CHAR VARCHAR 차이점

 

CHAR는 말 그대로 고정형

ex) CHAR(8)로 선언 시 글자를 한 개를 넣든 두 개를 넣든 8바이트의 공간을 차지합니다.

VARCHAR는 반대로 가변형 문자열이기 때문에 데이터의 길이에 따라서 가변적으로 길이가 정해집니다.

ex) VARCHAR(8)로 선언 시 글자를 한 개를 넣으면 1바이트, 2개를 넣으면 2바이트의 공간을 유동적으로 차지합니다.

※ VARCHAR = variable + char

 

CHAR는 경우에 따라 데이터가 낭비될 수 있지만 추후 연산이 필요 없기 때문에 검색속도 및 읽히는 속도가 VARCHAR에 비해 빠르다는 장점이 있습니다. 글자 수가 고정되는 경우에 사용하면 데이터를 보다 효율적으로 관리할 수 있습니다.

ex) 주민등록번호, 전화번호, 사원번호 등

 

VARCHAR 입력받은 데이터의 크기가 작을 경우, 그 크기만큼만 메모리를 차지하므로 메모리 사용량을 줄일 수 있다는 장점이 있습니다.

 

또한 VARCHAR는 insert나 update가 있을 때 현재 자신이 차지하고 있는 영역이 얼마인지 확인하고, 부족한 경우 더 할당하고 남으면 줄여서 insert합니다. 하지만 CHAR는 고정된 길이의 값을 넣는 것이기 때문에 일단 밀어 넣고, 남는 부분을 공백으로 채우게 됩니다.

 

차이점만 있는 것은 아니고, 공통점도 있습니다.

 

 

CHAR VARCHAR 공통점

 

1. 문자열을 데이터 타입으로, 싱글쿼터(' ')로 값을 나타냅니다.

 

2. 대소문자를 구분합니다.

 

3. 한글은 한 글자당 3byte, 영문자는 알파벳 하나당 1byte의 크기를 가집니다.

 

4. 설정된 크기를 초과할 경우, 메모리를 초과한 나머지 값은 저장되지 않습니다.

ex) CHAR(20)으로 했을 경우 20byte만큼만 공간이 할당되기 때문에 20byte를 넘어가면 데이터가 잘리게 됩니다.

이러한 특성은 VARCHAR도 동일합니다.

※ mysql 5 버전부터는 괄호 안의 숫자가 byte가 아닌 글자 수를 의미합니다.

 

VARCHAR와 TEXT의 차이점

 

Index의 일부로 사용 가능 여부

 

  • VARCHAR : 가능
  • TEXT : 불가능

 

max size limit 가능 여부

 

  • VARCHAR : 있다, 1~65535
  • TEXT : 없다, only 65535

 

저장된 character 이외의 현재 저장된 String의 저장 공간

 

  • VARCHAR : x <= 255 then, 1byte, 256 <= x <= 65535 then, 2byte
  • TEXT : only 2byte

 

실제 사용에 있어서 ID, 이메일, 제목과 같은 간단한 정보(비교적 짧은 문자열)는 주로 VARCHAR를 이용하고, 댓글이나 신문기사와 같은 긴 문장 종류들은 TEXT를 이용한다고 합니다. 또한 데이터가 자주 검색되는 경우 VARCHAR로 저장하는 것이 더 빠르다고 합니다.

 

 

출처:https://cobook.tistory.com/m/60

Primary key 와 foreign key 비교

SQL에서 Primary Key와 Foreign Key는 데이터베이스에서 관계형 데이터를 구성하는 데 중요한 역할을 합니다.

Primary Key는 테이블 내의 각 행을 고유하게 식별하는 데 사용되는 열 또는 열의 집합입니다. Primary Key는 테이블 내에 있는 다른 열들과 중복되지 않으며, Null 값을 가질 수 없습니다. Primary Key를 지정하면 해당 테이블에서 행을 쉽게 찾을 수 있으며, 다른 테이블과의 관계를 맺을 때 사용할 수 있습니다.

Foreign Key는 다른 테이블의 Primary Key를 참조하는 열입니다. 다른 테이블의 Primary Key와 일치하는 값을 Foreign Key로 지정함으로써 두 테이블 사이에 관계를 맺을 수 있습니다. Foreign Key는 데이터의 무결성을 보장하고 데이터를 일관성 있게 유지하는 데 도움을 줍니다. 예를 들어, 주문 테이블에서는 고객 테이블의 Primary Key인 고객 ID를 참조하는 Foreign Key가 존재할 수 있습니다. 이렇게 하면 고객 테이블에서 해당하는 고객 정보를 변경하거나 삭제해도 주문 테이블에서 해당 정보를 참조할 수 있으므로 데이터 일관성이 유지됩니다.

즉, Primary Key는 테이블 내의 각 행을 고유하게 식별하고 참조할 때 사용하고, Foreign Key는 다른 테이블의 Primary Key와 관계를 맺고 데이터 일관성을 유지하는 데 사용됩니다.

 

Primary key 와 Unique Key 비교

Primary Key와 Unique Key는 모두 테이블 내에서 중복을 허용하지 않는 열 또는 열의 집합을 지정하는 데 사용됩니다. 하지만 둘은 몇 가지 차이점이 있습니다.

먼저, Primary Key는 테이블에서 각 행을 식별하는 데 사용됩니다. Primary Key는 테이블에서 유일해야 하며, Null 값을 가질 수 없습니다. 또한, 하나의 테이블에는 Primary Key가 하나만 지정될 수 있습니다. 그리고 Primary Key는 해당 테이블의 다른 테이블과의 관계를 맺을 때 사용됩니다.

반면에, Unique Key는 해당 열의 값을 고유하게 유지하기 위해 사용됩니다. Unique Key는 Primary Key처럼 Null 값을 가질 수 없으며, 테이블에 중복 값을 가지는 행을 삽입하는 것을 방지합니다. 또한, 하나의 테이블에는 여러 개의 Unique Key가 지정될 수 있습니다.

즉, Primary Key는 테이블의 각 행을 고유하게 식별하는 데 사용되고, 해당 테이블과 다른 테이블 간의 관계를 맺을 때 사용됩니다. Unique Key는 해당 열의 값을 고유하게 유지하는 데 사용되고, 여러 개의 Unique Key가 테이블 내에 지정될 수 있습니다.

 

출처 : 챗 gqt님

기본 키 (Primary Key) #

  • Data-Table에 있는 유일하게 구분되는 Data-Key를 기본 키(Primary Key)라 부른다.
  • Primary Key는 유일한 값이기 때문에 중복된 값을 가질 수 없다.
  • Primary Key는 공백을 가질 수 없습니다.

외래 키 (Foreign Key) #

  • 한 Table과 참조되는 다른 Table 간의 연결되는 Primary Key Column을 Foreign Key라 합니다.
  • Foreign Key는 다른 Primary Key를 참조하는 속성 또는 속성들의 집합을 의미한다.
  • Foreign Key는 참조관계의 기본 키와 같은 속성을 가진다.

후보 키 (Candidate Key) #

  • Primary Key와 Foreign Key와 같은 각 Data를 식별하기 위해 사용되는 속성들의 집합입니다.
  • Candidate Key는 유일성과 최소성을 모두 만족합니다.
  • 유일성(Unique) : 하나의 Key 값으로 하나의 Data를 식별하는 성질
  • 최소성(Minimality) : 모든 Data를 유일하게 식별하는 속성으로만 구성되는 성질

슈퍼 키 (Super Key) #

  • 하나 이상의 속성이 하나의 Data를 구별하면 그것은 슈퍼 키 (Super Key)라 정의한다.
  •  

출처 : http://www.incodom.kr/Primary_Key_%26_Foreign_Key

'DB > DB 필요한 지식' 카테고리의 다른 글

SQL 인젝션이란?  (0) 2023.04.09
클라이언트와 서버  (0) 2023.04.08
포트 포워딩이란?(port forwarding)  (0) 2023.04.08

들어가기 전에..

- 경우의 수

여러 개의 사건이 일어날 때 경우의 수를 따지는 방법. 조합론에서 다루는 수많은 논의를 가능케하는 가장 기본적인 두 원리.
  • 합의 법칙: 경우의 수를 구해야 할 여러 사건들이 영향을 주거나 일어나는 상황의 구조가 닮지 않은 다른 경우, 경우의 수를 쪼개서 계산하게 된다. or이 합의 법칙이다.
    두 사건 A, B의 경우의 수를 따진다면, 사건 A가 일어나는 경우의 수가 가지, 사건 B가 일어나는 경우의 수는 가지라면 A와 B 어느 쪽이 일어나는 경우의 수는 m + n 가지다. '또는', '~이거나'라는 표현을 사용한다면 합의 법칙 문제이다.
  • 곱의 법칙: 경우의 수를 구해야 할 여러 사건들이 서로 영향을 주지 않거나 일어나는 상황이 구조가 닮은 경우, 경우의 수를 뭉쳐서 계산하게 된다. and가 곱의 법칙이다.
    두 사건 A, B의 경우의 수를 따진다면, 사건 A가 일어나는 경우의 수가 가지, 사건 B가 일어나는 경우의 수는 가지라면 A와 B가 동시에 일어나는 경우의 수는  가지다.

합의 법칙은 주사위의 눈이 2 또는 5가 나올 경우의 수를 생각하면 된다. 주사위의 눈이 2 또는 5가 나오면 되므로 2가 나올 경우의 수 1가지와 5가 나올 경우의 수 1가지를 더하여 2가지가 나온다. 1+1=2

곱의 법칙은 주사위를 두 번 던져 처음엔 짝수가 나오고 그 다음 홀수가 나올 경우의 수를 생각하면 된다. 처음에 짝수가 나올 경우의 수 3가지(2, 4, 6)에 두번째 홀수가 나올 경우의 수 3가지(1, 3, 5)를 곱하면 9가지이다. 3×3=9

그런데 이 두 가지를 구분하는 부분에서 많이 헷갈리게 되는데, 간단히 말해 사건과 사건이 이전의 결과에 영향을 받거나 관계가 서로 엮여있을 때 합의 법칙을 사용하고, 영향을 받지 않는 독립적인 사건이라면 곱의 법칙을 사용하면 된다. '동시성'이라는 단어가 애매한 것이, 예를 들어 3개의 갈림길을 지나 다시 2개의 갈림길중 하나를 선택하는 문제라면, 분명 동시에 일어나는 사건은 아니지만 곱의 법칙을 사용해야 한다. 어떤 두 사건이 즉 동시에 일어날 경우 곱의 법칙을 쓰지만(동시에 일어나지만 합의 법칙을 쓰는 경우는 없으므로) 곱의 법칙을 쓴다고 해서 어떤 두 사건이 항상 동시에 일어나는 것은 아니다.정 모르겠다면 문제에서 숫자를 줄여서 상상해보자. EBS강좌에서 한 강사는 동시성의 혼란을 방지하고자 '잇달아'라는 개념을 도입하면 이해하기 쉽다고 하니 참고할 것.어디까지나 캐바케지만 이런 연습을 여러번 거치다 보면 자유자재로 두 법칙을 사용하게 될 것이다.

고등학교 과정에서 법칙이란 이름을 붙이기 부끄러운 간단한 내용에 다짜고짜 '법칙'인가 싶지만 공부를 깊이 하면 결국 순열과 조합의 기술적인 부분을 제치고 결정적으로 중요한 내용이라는 것을 깨달을 수 있다. 문제를 풀 때 흔히 쓰는 공식과 기술은 고난도 문제가 다루는 변태적으로 특수한 상황에서는 결국 상황을 많이 복잡하게 만들 뿐이다. 결국엔 상황을 최대한 단순화시킨 후 각각의 케이스에 대해서 곱의 법칙으로 뭉친 항들을 곱하는 것이나, 상황이 여의치 않거나 단순하게 해결할 수 있다면 합의 법칙으로 해결하는 것도 나쁘지 않다.

기호로 간단하게 n!로 나타내며 부터 까지의 자연수를 모두 곱하는 것을 의미한다. 팩토리얼이라고도 불린다.

출처:나무위키

 

 

순열이란

서로다른 n개에서 r(0<r≤n)개를 택하여

일렬로 나열하는 것을

n개에서 r개를 택하는 순열이라 한다.

 식으로 표현하면 이렇다.

 

첫 번째 순열은 원순열

 

말그대로 원으로 배열하는 것인데 그림으로 보면 이렇다

위 사진과 같이 A, B, C, D를 배치시키는데

원형 탁자에 배열 시킨다면

위 네가지 경우가 똑같은 경우라고 할 수 있다

항상 A의 좌우측에는 B와 D가 배치되어 있고,

B,C,D 좌우측에도 변화가 없다.

그렇기에 4가지 경우는 같은 경우.

 

그럼 우리가 처음 배웠던 순열로 보면

4명을 일렬로 세우는 방법의 수는 4! 이지만

원형탁자에 배열 한다면 서로 같은 경우가 4가지씩 있으므로

확장해서 서로 다른 n개를 원형탁자에 배열한다고 하면

원순열의 수는

 

Q1. 원형 탁자에 A, B, C, D, E가 둘러 앉을 때 다음을 구하시오.

(1) 6명이 앉는 모든 경우의 수

(2) A, B가 이웃하여 앉는 모든 경우의 수

(3) D, E가 마주 보고 앉는 모든 경우의 수

 

두 번째 순열은 중복순열.

 

중복순열이란

서로 다른 n개에서 중복을 허용하여

r개를 택하여 일렬로 배열하는 것을

n개에서 r개를 택하는 중복순열이라 한다.

중복순열은 위와 같이 표현하는데,

중복을 허용하기 때문에

첫 번째 자리에 올 수 있는 경우의 수도 n,

두 번째 자리에 올 수 있는 경우의 수도 n,

계속해서 r번째 자리에 올 수 있는 경우의 수 또한 n개다.

 

Q2. 비밀번호를 만들 때 0부터 9까지의 번호를 사용할 수 있으며,

    비밀번호는 총 5개의 숫자로 이루어져 있다.

    만들 수 있는 비밀번호의 개수를 구하시오.

 

세 번째 순열은 중복순열이라고도 하는데,

같은 것이 있는 순열의 수를 구하는 경우.

 

만약 파란색 카드 2장과 빨간색 카드 3장이 있는데,

이 카드 5장을 일렬로 줄 세우는 방법은 당연히

5!.

 

하지만 같은 색끼리 카드는 구별이 불가능 하다면?

파란색 카드 2장끼리 순서가 바뀌는 경우 2!과

빨간색 카드 3장끼리 순서가 바뀌는 경우 3!만큼

나누어 주게되면 그 답을 쉽게 구할 수 있다?

 

정리하자면

 

 

출처 :https://mathmen.tistory.com/11

DB와 DBMS는 데이터 관리와 관련된 용어이다.

비슷하지만 다른 개념인것이다 -> DB != DBMS

  • DB (Database)는 데이터베이스를 의미한다. 데이터베이스는 여러 개의 테이블이나 관련된 객체들의 집합으로 구성되며, 데이터를 구조화하고 조직화한 것이다.
  • DBMS (Database Management System)는 데이터베이스 관리 시스템을 의미. DBMS는 데이터베이스를 생성, 수정, 검색, 삭제하는 데 사용되는 소프트웨어다. DBMS는 데이터를 저장, 관리 및 보호하기 위한 다양한 기능을 제공한다. 또한, 여러 사용자가 동시에 데이터베이스에 접근하여 데이터를 공유하고 관리할 수 있도록 도와준다.

즉, DB는 데이터를 구조화하고 저장하는 데 사용되는 개념적인 개체이며, DBMS는 데이터베이스를 관리하기 위한 소프트웨어이다다. DBMS는 데이터베이스의 구성, 유지, 관리 및 보호를 담당하며, DB와 DBMS는 서로 밀접하게 연관되어 있다. 데이터베이스를 사용하려면 반드시 DBMS가 필요하며, DBMS는 데이터베이스의 구축 및 운영에 필수적인 역할을 한다.

다음은 'DB'를 관리하는 'DBMS' 프로그램들의 순위이다

오라클을 가장 많이 쓰고 그 다음은 mysql ....등등이다

예전에는 오라클과(보통 기업용,유료) MySQL(민간용,무료) 로 나누어져 있었다고 한다

그런데 오라클이 MySQL을 인수하면서 오픈소스를 지향하는 이들이 나가 만든것이

MariaDB라는 것이다 나는 배우는 학생이라 MariaDB를 사용하지만 MySQL과 상속관계 이므로

거의 비슷하게 쓴다고 보면 된다.

Database Model도 중요한데 다음 글에서 알아보자.

내가 주로 다룰 모델은 관계형 데이터베이스 관리 시스템(RDBMS) 이다.

'DB' 카테고리의 다른 글

DBMS,Spring 3월 23일 5회차  (0) 2023.03.30
DBMS,Spring 3월 22일 4회차  (0) 2023.03.30
DBMS,Spring 3월 21일 3회차  (0) 2023.03.30
DBMS,Spring 3월 17일 2회차  (0) 2023.03.30
DBMS,Spring 3월 16일 1회차  (0) 2023.03.30
package com.KoreaIT.java.AM;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		System.out.println("==프로그램 시작==");

		Scanner sc = new Scanner(System.in);

		int lastArticleId = 0;
		List<Article> articles = new ArrayList<>();

		while (true) {

			System.out.print("명령어 > ");
			String command = sc.nextLine().trim();

			if (command.length() == 0) {
				System.out.println("명령어를 입력해주세요");
				continue;
			}

			if (command.equals("exit")) {
				break;
			}

			if (command.equals("article list")) {
				if (articles.size() == 0) {
					System.out.println("게시글이 없습니다");
				} else {
					System.out.println(" 번호  //  제목  ");
					for (int i = articles.size() - 1; i >= 0; i--) {
						Article article = articles.get(i);
						System.out.printf("  %d   //   %s  \n", article.id, article.title);
					}
				}

			} else if (command.equals("article write")) {
				int id = lastArticleId + 1;
				System.out.print("제목 : ");
				String title = sc.nextLine();
				System.out.print("내용 : ");
				String body = sc.nextLine();

				Article article = new Article(id, title, body);
				articles.add(article);

				System.out.printf("%d번글이 생성되었습니다\n", id);
				lastArticleId++;

			} else if (command.startsWith("article detail")) {

				String[] cmdDiv = command.split(" ");

				if (cmdDiv.length < 3) {
					System.out.println("명령어를 확인해주세요");
					continue;
				}

				int id = Integer.parseInt(cmdDiv[2]);

				Article foundArticle = null;

				for (int i = 0; i < articles.size(); i++) {
					Article article = articles.get(i);
					if (article.id == id) {
						foundArticle = article;
						break;
					}
				}

				if (foundArticle == null) {
					System.out.printf("%d번 게시물은 존재하지 않습니다\n", id);
					continue;
				}
				System.out.println("번호 : " + foundArticle.id);
				System.out.println("날짜 : " + "2023-12-12 12:12:12");
				System.out.println("제목 : " + foundArticle.title);
				System.out.println("내용 : " + foundArticle.body);

			} else {
				System.out.println("존재하지 않는 명령어입니다");
			}
		}

		System.out.println("==프로그램 끝==");

		sc.close();
	}
}

class Article {
	int id;
	String title;
	String body;

	Article(int id, String title, String body) {
		this.id = id;
		this.title = title;
		this.body = body;
	}
}

이제 article detail의 상세보기 기능을 제대로 구현해보자

startWith으로 article detail로 시작하는 문장을

split으로 공백으로 구분했으며 3번째 오는 숫자를 문자열로 치환해 id값에 저장한다.

그리고 추가 된 코드

if(cmdDiv.length < 3) {    //만약 ㅁ ㅁ ㅁ 형식을 취하지 않은것이라면

  System.out.println("명령어를 확인해주세요");  // 다시 치라는 것을 출력

  continue;  // 반복문으로  되돌려 보낸다

}

Ind id = Integer.parseInt(cmdDiv[2]);

Article foundArticle = null;

for(int i = 0 ; i < articles.size(); i++){

  Article article = articles.get(i);

   if(article.id == id) {

   foundArticle = article;

   break;

     }

}

 if(foundArticle == null) {

    System.out.printf("%d번 게시물은 존재하지 않습니다\n",id)

   continue;

}

package Main;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		System.out.println("==프로그램 시작==");
		Scanner sc = new Scanner(System.in);
		int lastArticleId = 0;
		List<Article> articles = new ArrayList<>();
		while (true) {
			System.out.print("명령어 > ");
			String command = sc.nextLine().trim();
			if (command.length() == 0) {
				System.out.println("명령어를 입력해주세요");
				continue;
			}
			if (command.equals("exit")) {
				break;
			}
			if (command.equals("article list")) {
				if (articles.size() == 0) {
					System.out.println("게시글이 없습니다");
				} else {
					System.out.println(" 번호  //  제목  ");
					for (int i = articles.size() - 1; i >= 0; i--) {
						Article article = articles.get(i);
						System.out.printf("  %d   //   %s  \n", article.id, article.title);
					}
				}
			} else if (command.equals("article write")) {
				int id = lastArticleId + 1;
				System.out.print("제목 : ");
				String title = sc.nextLine();
				System.out.print("내용 : ");
				String body = sc.nextLine();
				Article article = new Article(id, title, body);
				articles.add(article);
				System.out.printf("%d번글이 생성되었습니다\n", id);
				lastArticleId++;

			} else if (command.startsWith("article detail ")) {

				String[] cmdDiv = command.split(" ");

				int id = Integer.parseInt(cmdDiv[2]);

				boolean found = false;

				for (int i = 0; i < articles.size(); i++) {
					Article article = articles.get(i);
					if (article.id == id) {
						found = true;
						break;
					}
				}

				if (found == false) {
					System.out.printf("%d번 게시물은 존재하지 않습니다\n", id);
				} else {
					System.out.printf("%d번 게시물 있던데?\n", id);
				}

			} else {
				System.out.println("존재하지 않는 명령어입니다");

			}
		}
		System.out.println("==프로그램 끝==");
		sc.close();
	}
}

class Article {
	int id;
	String title;
	String body;

	Article(int id, String title, String body) {
		this.id = id;
		this.title = title;
		this.body = body;
	}
}

article detail 의 명령어에 기능을 제대로 구현해보자.

startWith과 split Integer.parseInt 를 이용해 명령어 실행과 배열의 구분까지 가능해졌다

그럼 글이 존재하는지 안하는지 배열을 뒤져볼 필요가 있다 그 코드로는

for(int i = 0 ; i < articles.size(); i++) { // i 변수가 0부터 "articles.size()-1 까지 1씩 증가하며 Article객체들중에 id가 일치하는걸 찾는것

boolean found = false; // ㅊfound 변수를 false 라는 것을 기본값으로 넣어준다 boolean의 기본값으로 설정해 준것

    Article article = articles.get(i); //각 반복마다 "articles" 리스트에서 "i"번째 인덱스에 해당하는 "Article" 객체를 가져와 "article" 변수에 저장한다다.

    if(article.id == id) { //만약에 id값이 맞다 찾았다면

      found = true;  // found 에 true 값을 저장하고

      break;   // 반복문을 빠져나간다
    }

}

if (found == false) {   //못찾았으면

     System.out.printf("%d번 게시물은 존재하지 않습니다\n",id);  //못찾았다는 출력문을 보내고

}else{  //찾았다면

    System.out.printf("%d번 게시물 있던데요?\n",id);  // 찾았다는 출력을 보낸다

}
} else{   // 엉뚱한 명령어를 입력 했을 경우.

     System.out.println("존재하지 않는 명령어 입니다");

}

 

위의 기능에서 핵심이 되는건 반복문의 추가다

"articles"라는 ArrayList(리스트)에 저장된 "Article" 객체들 중에서 "id"값이 일치하는 객체를 찾는 작업을 수행한다.

for문에서는 "i"변수가 0부터 "articles.size()-1"까지 1씩 증가하며 반복 실행된다. 각 반복마다 "articles" 리스트에서 "i"번째 인덱스에 해당하는 "Article" 객체를 가져와 "article" 변수에 저장한다.

그리고 if문에서는 현재 가져온 "article" 객체의 "id"값과 찾으려는 "id"값이 일치하는지 비교한다. 만약 일치한다면 "found"라는 변수에 true 값을 저장하고 반복문을 빠져나온다.

즉, 위 코드는 "articles" 리스트에서 "id"값이 일치하는 "Article" 객체를 찾고, 해당 객체가 존재하는지 여부를 "found" 변수에 저장하는 것이다.

package Main;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		System.out.println("==프로그램 시작==");
		Scanner sc = new Scanner(System.in);
		int lastArticleId = 0;
		List<Article> articles = new ArrayList<>();
		while (true) {

			System.out.print("명령어 > ");
			String command = sc.nextLine().trim();

			if (command.length() == 0) {
				System.out.println("명령어를 입력해주세요");

				continue;
			}
			if (command.equals("exit")) {
				break;
			}
			if (command.equals("article list")) {
				if (articles.size() == 0) {
					System.out.println("게시글이 없습니다");
				} else {
					System.out.println(" 번호  //  제목  ");
					for (int i = articles.size() - 1; i >= 0; i--) {
						Article article = articles.get(i);
						System.out.printf("  %d   //   %s  \n", article.id, article.title);
					}
				}
			} else if (command.equals("article write")) {
				int id = lastArticleId + 1;
				System.out.print("제목 : ");
				String title = sc.nextLine();
				System.out.print("내용 : ");
				String body = sc.nextLine();
				Article article = new Article(id, title, body);
				articles.add(article);
				System.out.printf("%d번글이 생성되었습니다\n", id);
				lastArticleId++;

			} else if (command.startsWith("article detail ")) {

				String[] cmdDiv = command.split(" "); // article detail 1

//				System.out.println(cmdDiv[0]);
//				System.out.println(cmdDiv[1]);
//				System.out.println(cmdDiv[2]);

				int id = Integer.parseInt(cmdDiv[2]);

				// article detail 1 => "1" => 1

				System.out.printf("%d번 게시물은 존재하지 않습니다\n", id);

			} else {
				System.out.println("존재하지 않는 명령어입니다");
			}

		}
		System.out.println("==프로그램 끝==");
		sc.close();
	}
}

class Article {
	int id;
	String title;
	String body;

	Article(int id, String title, String body) {
		this.id = id;
		this.title = title;
		this.body = body;
	}
}

게시물 상세보기를 구현해보자 명령어는 article detail이라 한다

스캐너 옆에 String command = sc.nextLine().trim();     trim();이라는 명령어가 하나 붙었다 문자열 command 변수에 공백이 있으면 알아서 잘라주겠단 얘기다

 

추가 된 건 명령어이므로 else if 로 틀을 비슷하게 구현해준다

 

else if(command.startWtih("article detail")){

      String[] cmdDiv = command.split(" ");

      int id = Interger.parseInt(cmdDiv[2]);

     System.out.prinf("%d번 게시물은 존재하지 않습니다\n",id);

} else {

     system.out.prtinln("존재하지 않는 명령어 입니다");

}

몇개의 키워드가 추가 되었다 'startWith' ,'split' , 'Integer.parseInt();'

사용 의도는 다음과 같다

```

-startWith ~~로 시작되는 단어가 입력 된다면?

  String[] cmdDiv = command.split(" "); << 을 이용해서 article detail ~ 을 공백을 기준 ㅁ ㅁ ㅁ 세 덩이로 나누겠단 의미다

문자열 command를 " "(공백)을 기준으로 나누어 문자열 배열(String[]) cmdDiv에 저장하는 코드입니다.

split() 메소드는 문자열을 특정 구분자(delimiter)를 기준으로 나누어 문자열 배열로 반환하는 메소드이다. 위 코드에서는 " "(공백)을 구분자로 사용하였다. 따라서, command 문자열이 " "(공백)을 포함하는 경우, split() 메소드는 해당 공백을 기준으로 문자열을 나누어 문자열 배열로 반환하게 된다.

반환된 문자열 배열은 String[] cmdDiv 변수에 저장된다. 이후 코드에서 cmdDiv 배열을 이용하여 다양한 작업을 수행할 수 있다. 예를 들어, cmdDiv[0]은 나누어진 문자열 중 첫 번째 단어를 나타내며, cmdDiv[1]은 두 번째 단어를 나타낸다다.

```

그리고 int id = Interger.parseInt(cmdDiv[2]);

```

해당 코드는 문자열 배열 cmdDiv의 세 번째 요소(cmdDiv[2])를 정수형(int)으로 변환한 후, 그 값을 변수 id에 할당하는 코드다.

Integer.parseInt() 메소드는 문자열을 정수형으로 변환하는 메소드다. 위 코드에서는 cmdDiv[2]에 저장된 문자열을 정수형으로 변환하여 id 변수에 할당한다.

예를 들어, cmdDiv[2]가 "123"과 같은 문자열을 포함하고 있다면, Integer.parseInt() 메소드는 해당 문자열을 정수형으로 변환한 후, id 변수에 123의 값이 할당된다. 만약 cmdDiv[2]가 정수로 변환할 수 없는 문자열이 포함되어 있다면, parseInt() 메소드는 NumberFormatException 예외를 발생시킨다. 이 예외는 try-catch 문을 사용하여 처리해야 한다.

```

결론은 article detail이란 코드를 사용하면 article detail로 시작하는 명령어를 공백의 기준에 따라 실행하게 되고

글 번호는 숫자로 시작할테니 ㅁ ㅁ 'ㅁ '<- 세번째에 할당되는 문자열을 숫자로 바꿔서 입력하겠단 소리다

세번째인데 cmdDiv[2] 인 이유는 배열을 생성할 땐 0,1,2,3,4,..... 으로 시작하기에 3번째 단어라면 [2]에 저장되기 때문이다.

 

마지막으로 else를 이용해 잘못 된 명령어를 고치라는 출력을 한다.

리포지터리중에 일부분을 삭제하고 싶어서 아무 생각없이 삭제했다

삭제하는데 코드를 치고 비번까지 치라고? 여기서 이상함을 눈치챘어야 한다

1개의 자료만 없애고 싶었지만 지금까지 올렸던 파일 전체가 없어진것이다..

다행히 복구 방법이 있었다

1.내 프로필을 클릭하고 세팅즈에 들어간다

2.오른쪽에 리포지터리스에 들어가서 딜리트 리포지터리스를 클릭 (휴지통 개념)

3.삭제한 내 리포지터리가 있었고 복원이 가능했다

그런데 복원시켜도 일부는 날아갔다. 모르면 함부로 건들지 말아야겠다

 

ps.

복구에도 시간이 걸리나보다 다시 들어가보니 완전 복구가 되었다

삭제는 웬만하면 하지말자..

package com.KoreaIT.java.AM;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		System.out.println("==프로그램 시작==");
		Scanner sc = new Scanner(System.in);
		int lastArticleId = 0;
		List<Article> articles = new ArrayList<>();
		while (true) {
			System.out.print("명령어 > ");
			String command = sc.nextLine();
			if (command.length() == 0) {
				System.out.println("명령어를 입력해주세요");
				continue;
			}
			if (command.equals("exit")) {
				break;
			}
			if (command.equals("article list")) {
				if (articles.size() == 0) {
					System.out.println("게시글이 없습니다");
				} else {
					System.out.println(" 번호  //  제목  ");
					for (int i = articles.size() - 1; i >= 0; i--) {
						Article article = articles.get(i);
						System.out.printf("  %d   //   %s  \n", article.id, article.title);
					}
				}

			} else if (command.equals("article write")) {

    
          
            
    

          
    
    
  
				int id = lastArticleId + 1;
				System.out.print("제목 : ");
				String title = sc.nextLine();
				System.out.print("내용 : ");
				String body = sc.nextLine();
				Article article = new Article(id, title, body);
				articles.add(article);
				System.out.printf("%d번글이 생성되었습니다\n", id);
				lastArticleId++;
			} else {
				System.out.println("존재하지 않는 명령어입니다");
			}
		}
		System.out.println("==프로그램 끝==");
		sc.close();
	}
}
class Article {
	int id;
	String title;
	String body;
	Article(int id, String title, String body) {
		this.id = id;
		this.title = title;
		this.body = body;
	}
}

 

aritle list 기능이 완성 되어간다

글이  없으면 없다하고 있으면 있던데? 보다는 코드적으로 글의 목록을 표현 하고싶다

else{

System.out.println("번호  //  제목");

for (int i = articles.size() - 1 ; i>= 0 ; i --);

   Aricle article = aricles.get(i);

   System.out.print("   %d    //   %s    \n ",article.id, article.title);

 

코드를 추가한다

 

위 코드는 리스트 articles에 저장된 게시물 정보를 출력하는 코드로 먼저 "번호 // 제목"을 출력하고, 리스트의 뒤에서부터 순회하면서 각 게시물의 id와 title을 출력한다 (명령어) article list를 입력했을 때 일어나는 일이다)

for 루프는 리스트 articles의 끝에서부터 시작하여 i 변수를 1씩 감소시키면서 반복한다. 각 반복에서 articles.get(i)를 통해 현재 위치의 게시물 정보를 가져와 article 변수에 저장한다

articles.size() - 1을 하는 이유는 리스트의 인덱스가 0부터 시작하기 때문. articles.size()는 리스트의 원소 개수를 반환하므로, 인덱스가 0부터 시작하면 마지막 원소의 인덱스는 size() - 1가 된다.

마지막으로 System.out.print()를 통해 " %d // %s \n" 형식의 문자열을 출력. %d는 정수를, %s는 문자열을 대체할 수 있는 포맷 문자열이다. 이 때, 포맷 문자열 내에 %d와 %s가 있음에도 불구하고, System.out.print() 메소드는 두 번째 인자부터 포맷 문자열에 포함될 값을 차례로 전달해야 함. 따라서 위 코드에서는 article.id와 article.title을 각각 %d와 %s에 대입하여 보여준다. 그럼 번호 , 제목이 나오겠지 

최종적으로 위 코드는 리스트 articles의 모든 게시물 정보를 역순으로 출력

실행결과? 내 의도대로 나온다

package com.KoreaIT.java.AM;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class TestMain {

	public static void main(String[] args) {
		System.out.println("==프로그램 시작==");
		Scanner sc = new Scanner(System.in);

		int lastArticleId = 0;
		List<Article> articles = new ArrayList<>();

		while (true) {

			System.out.print("명령어 > ");
			String command = sc.nextLine();

			if (command.length() == 0) { //아무것도 입력 x 
				System.out.println("명령어를 입력해주세요"); // 이게 출력된다
				continue; // while문 초기로 돌려보냄!
			}
			if (command.equals("exit")) {
				break;
			}

			if (command.equals("article list")) { // 이 명령어를 이제 유의미하게 만들었다
				if (articles.size() == 0) { // 게시글이 없다면
					System.out.println("게시글이 없습니다"); // 출력
				} else {                                       //있다면?
					System.out.println("있던데???");            //출력
				}

			} else if (command.equals("article write")) {
				int id = lastArticleId + 1;
				System.out.print("제목 : ");
				String title = sc.nextLine();
				System.out.print("내용 : ");
				String body = sc.nextLine();

				Article article = new Article(id, title, body); //객체 생성자 호출
				articles.add(article);  //생성된 객체를 articles 변수 리스트에 추가!

				System.out.printf("%d번글이 생성되었습니다\n", id);
				lastArticleId++;

			} else {
				System.out.println("존재하지 않는 명령어입니다");
			}
		}
		System.out.println("==프로그램 끝==");

		sc.close();
	}
}

class Article {
	int id;
	String title;
	String body;

	Article(int id, String title, String body) {
		this.id = id;
		this.title = title;
		this.body = body;
	}
}

 

 

나는 article list 명령어를 입력했을때 이제 유의미한 프로그램 가동을 하고싶다

 

List<Article> articles = new ArrayList<>(); 으로 배열 객체를 만들어주고

List와 ArrayList라는 자바에 있는 기능을 썼으므로 각각 import를 해준다

그리고 변수 articles에 그 값을 저장할 것이고

new로 객체를 지정해주었으므로 Article 클래스를 하나 만들어준다

Article은 게시글이란 뜻인데 개발자들이 통상 쓰는듯하다

일단 간단하게 몇번글인지,제목,내용만 나오는 명령어로 만들고 싶어서

변수를 Int id; , String title , String body 로 3개 지정해준다

실행 시키자마자 저 값을 입력 시키고 싶으니 생성자 Article을 만들어준다

int lastArticleId = 0;

List<Article> articles = new ArrayList<>(); 을 while문 바깥에다 쓰는 이유는 전에도 말했다 싶이

반복문안에 놓으면 무한적으로 초기화 되기 때문에 바깥에다가 값을 저장해놔야 글1,글2,글3 이런식으로 순서대로 저장이 될 것이다

 

클래스와 객체 생성자를 만들어 줬으니 써먹어야 한다.

// Article 객체 생성자 호출


Article article = new Article(id, title, body);

// 생성된 Article 객체를 articles 리스트에 추가


articles.add(article);

 

코드를  실행해보니 잘 되는 것 같다

 

 

+ Recent posts