[DB] CRUD 의 개념과 Maria DB 의 데이터 구조

◼ CRUD
 ▫ C(Create) :  (없던 것을)만드는 것. 게시글 작성, 게시글 작성, 회원가입 등. 
 ▫ R(Read) :  어떠한 데이터가 있는 지 확인하거나, 있는 데이터를 읽는 것. 게시글 읽기, 로그인 등.
 ▫ U (Update) :  존재하는 데이터를 수정하는 것. 게시글 수정, 회원정보 수정 등.
 ▫ D(Delete) : 존재하는 데이터를 삭제하는 것.게시글 삭제, 회원탈퇴 등.
 ▫ (WA,WS를 제외한)웹의 대부분의 기능은  CRUD 에 입각하여 개발할 수 있다.
 👀 유튜브 시청기록 알고리즘 : C


◼ MairaDB의 데이터 구조
▫ MairaDB의 데이터구조는 스키마(Schema)⊃테이블(Table)⊃ 레코드(Record)의 포함관계로 되어있다. (⊃: ㄷ+한자)
▫ 스키마(Schema)
 ▪ 스키마는 다른 이름으로 데이터베이스(Database)라고 부른다.
 ▪ 스키마는 서로 관련있는 테이블을 포함하는 용도로 사용한다.
 ▪ 스키마는 실제 데이터(레코드)를 직접가지고 있지 않는다.
 ▪ 엑셀로 비유 시, 엑셀파일 그 자체(xlsx)로 표현된다.

▫ 테이블(Table)
 ▪ 테이블은 반드시 스키마에 종속적이어야 한다.
 ▪ 테이블은 이 테이블이 담당하게 될 데이터의 규격에 맞는 열(Column)에 대한 정보를 포함한다.
 ▪ 테이블은 테이블이 가진 열 구조에 상응하는 레코드(데이터)를 포함하고 있다.
 ▪ 엑셀로 비유시, 엑셀파일 시트(Sheet)로 표현된다.
 
▫ 레코드(Record)
 ▪ 레코드는 다른 이름으로 행(Row) 혹은 데이터(Data)로 불리운다.
 ▪ 레코드는 반드시 어떤 테이블에 종속적이어야한다.
 ▪ 레코드 하나는 한 줄을 의미하고 실제 데이터이다.
 ▪ 엑셀로 비유시, 엑셀시트내의 행으로 표현된다.
 
스키마
▪ 만들기

 

 

◼ 쿼리(Query)
▫ 쿼리(Query)란 DBMS에서 사용하는 SQL(Structed Query Language)언어의구문이나 그 자체를 의미한다. '쿼리문' 혹은 'SQL문' 등으로 통용해서 부름.
▫ 모든 키워드(keyword)는 대소문자를 가리지 않지만 통일하는 것이 좋고, 주로 대문자로만 작성한다.
 ▪ (o) create schema ...
 ▪ (o) CREATE SCHEMA ...
 ▪ (X)
 ▪ (X)
 
▫ 모든 구성요소(그키마,테이블,열 등)의 이름은 백틱(Backtick,`)으로 감싼다. 구성요소의 이름이 키워드가 아닌 경우 생략가능.
▫ 모든 구성요소의 이름은 스네이크 케이스(Snake Case) 명명법을 따른다.
▫ 문자열 값은 홑따옴표(')로 감싼다.
▫ INSERT INTO `some_schema`.`some_table`(`som_colmn`)VALUES('어떤 문자값');
▫ 모든 구문은 끝에 세미콜론(;)을 적어준다.

◼ 사용자
▪ 사용자(User)는 DBMS에 접속하여 각종 쿼리를 실행할 수 있는 주제를 의미한다.
▪ DBMS 설치시에 최초로 생성되는 (사용가능한) 사용자는 root 이고, root계정은 최고 관리자 계정이며, 개발시에 사용하지 않는다.
▪ 만들기 (C)
 ▫ 사용자를 만들기 위해 아래 구문을 사용한다.
              ↓사용자이름 ↓ 호스트                  ↓비밀번호
 CREATE USER `study`@`localTest`IDENTIFIED BY 'test1234';
 (V)    (O)  
 ▫ 사용자 이름과 호스트는 구성요소이기때문에 백틱(`)으로 감싸고, 비밀번호는 문자열이기때문에 홑따옴표(')로 감쌂에 주의한다.
 ▫ 호스트는 해당 사용자 이름을 이용하여 접속할 수 있는 원격 호스트로, 도메인이나 IP주소를 이용하여, 별도로 제한을 두지 않고자 한다면 퍼센트(%)가 기호로 대체한다.
 ▪ 읽기(R)
 ▫ 일단 생략
 
▪ 수정하기(U)
▫ 만들어진 사용자는 그 어떠한 권한도 가지고있지 않음으로 유의한다.
▫ 존재하는 사용자에게 권한을 부여하기 위해 아래 구문을 사용한다.
                  
↓부여할 권한      ↓스키마         ↓테이블         ↓사용자이름 ↓ 호스트
GRANT ALL PRIVILEGES ON `some_schema`.`some_table` TO `study`@`localhost`;

▫ 부여할 권한은 콤마(,)로 구분하여 여러개 작성 가능하며 각 권한은 일부 키워드( CREATE, DROP, ALTER, INSERT , SELECT, UPDATE, DELETE, GRANT, REVOKE, DESK, NOW 등)이다. 혹은 모든 권한은 ALL PRIVATE혹은 ALL이라고 적을 수 있다.
▫ 존재하는 사용자로부터 권한을 철회하기 위해 아래 구문을 사용한다.
REVOKE All PRIVILEGES ON `some_schema`.`some_table`TO`study`@`localhost`;

▫ 대상이 되는 스키마와 테이블을 직접 명시하거나 존재하는 모든 스키마의 모든 테이블에 대한 명시는 *.*로 대체한다.
▫ 변경(추가 및 삭제)된 권한을 즉시 적용하기위해 아래 구문을 사용한다.
FLUSH PRIVILEGES;

▪ 삭제하기(D) 
 ▫ 존재하는 사용자를 삭제하기 위해 아래 구문을 사용한다.
                ↓사용자이름 ↓ 호스트       
 DROP USER `study`@`localhost`;
 ▫ 삭제된 사용자는 복구할 수 없음으로 유의한다.
 
 
◼ 스키마
▪ 스키마의 이름은 단수로 하는 것을 원칙으로 한다. 주로 [서비스이름]_[목적] 의 형태로 이루어져 있다. 
  가령, '쿠팡'이라는 서비스의 '회원'과 관련된 테이블을 담는 스키마의 이름은 cupang_member 로 짓는다.
▪ C: 만들기
 ▫ 스키마를 만들기 위해 아래 구문을 사용한다.
CREATE SCHEMA `some_schema`;
                ↑생성할 스키마 이름

이미 존재하는 경우 오류를 발생시키는 것이 아니라 아무것도 하지 않게 하기 위해 아래 구문을 사용한다.
CREATE SCHEMA IF NOT EXITS `some_schema`;
                               ↑생성할 스키마 이름
   
IF NOT EXITS는 해당 이름을 가진 스키마가 없다면 만들고, 있다면 아무것도 하지 말라는 의미이다.

▪ R: 조회하기
 ▫ DBMS에 존재하는 스키마들을 조회하기 위해 아래 구문을 사용한다.
SHOW SCHEMAS;

▪ U: 사용자 비밀번호 수정하기
 ▫ 존재하는 사용자의 비밀번호를 변경하기 위해 아래 구문을 사용한다.
ALTER USER `study`@`localhost`IDENTIFIED BY'newPassWard';

▪ D: 삭제하기
▫ 존재하는 스키마를 삭제하기 위해 아래 구문을 사용한다.
DROP SCHEMA `some_schema`;
                    ↑ 삭제할 스키마 이름
▫ 스키마를 삭제할 경우 이에 소속된 테이블 및 레코드가 모두 삭제되고 되돌릴 수 없음으로 유의한다.
▫ 존재하지 않는 스키마를 삭제하려 하였을때 오류가 발생하는 것을 방지하려면 아래구문을 사용한다.
DROP SCHEMA IF EXISTS `test`;
▫ 삭제하는 테이블 및 이가 가지고 있는 레코드는 복구할 수 없음으로 유의한다.


DROP SCHEMA IF EXISTS `test`;

◼ 주석
▫ 한 줄 주석: 대쉬 두 개를 이용하여 아래와 같이 작성한다.
 -- 대쉬 두개를 이용하여 한 줄 주석을 이용할 수 있음

▫ 여러줄 주석: /*...*/형식으로 작성한다.
 /*
 여러 줄 
 주석을 
 남길 수 
 있다.
 */

◼ 테이블
▪ 테이블(Table)은 반드시 스키마에 소속되어있어야 한다.
▪ 테이블의 이름은 복수형으로 짓는 것을 원칙으로 한다. 
  가령, 쿠팡이라는 서비스의 회원정보를 담는 테이블은 coupang_member 스키마 내게 users라는 이름으로 존재한다.
▪ 테이블은 실제 데이터(코드)를 담기 위한 용도로 사용된다.
▪ R: 특정 스키마 안에 있는 테이블 조회하기
 ▫ 어떤 스키마 안에 존재하는 테이블의 목록을 조회하기 위해 아래 구문을 사용한다.
                            ↓ 스키마 이름
       SHOW TABLES IN `some_schema`;
        +---------------------------------------+
        | Tables_in_information_schema          |
        +---------------------------------------+
        | ALL_PLUGINS                           |
        | APPLICABLE_ROLES                      |
        | CHARACTER_SETS                        |
        | CHECK_CONSTRAINTS                     |
        | COLLATIONS                            |
        ...
        | THREAD_POOL_STATS                     |
        +---------------------------------------+
        79 rows in set (0.000 sec)
  
▪ R: 해당 테이블의 정보 조회하기
 ▫ 해당 테이블이 가지고 있는 열들의 정보를 조회하기 위해 아래 구문을 사용한다.

                  ↓ 소속 스키마 이름
        DESC `some_schema`.`some_table`;
                               ↑ 조회할 테이블 이름
      
        MariaDB [(none)]> DESC `study`.`cities`;
        +-------+------------+------+-----+---------+-------+
        | Field | Type       | Null | Key | Default | Extra |
        +-------+------------+------+-----+---------+-------+
        | code  | varchar(3) | NO   |     | NULL    |       |
        | name  | varchar(2) | YES  |     | NULL    |       |
        +-------+------------+------+-----+---------+-------+
        2 rows in set (0.011 sec)
      ▫ DESC는 'Describe'의 줄임말로 '설명하다'의 의미를 가지고 있음.
  
 ▪ U: 테이블 이름 변경하기
  ▫ 스키마와 달리 테이블의 이름은 변경이 가능하다.
 
                      ↓ 스키마 이름                          ↓ 스키마 이름
      > ALTER TABLE `some_schema`.`some_table` RENAME TO `some_schema`.`target_table`;
                                     ↑ 테이블 이름                          ↑ 변경할 테이블 이름
      
RENAME TO 키워드 뒤의 스키마 이름을 달리하여 테이블이 소속한 스키마를 변경하는 것도 가능하다.
                ↓ 스키마 이름                          ↓ 이동할 스키마 이름
ALTER TABLE `some_schema`.`some_table` RENAME TO`other_schema`.`target_table`;
                             ↑ 테이블 이름                           ↑ 변경할 테이블 이름

1.'study` 스키마 날리기
2.`a`및 `b`라는 이름을 가진 스키마 만들기
3.`a`스키마 밑에 아무 열이나 (마음가는 대로)가진 테이블 `t` 만들기
4.`a`.`t`테이블을 `b`스키마 밑으로 옮기기.();

▪ U: 열 추가하기
 ▫ 존재하는 테이블에 새로운 열을 추가하기 위해 아래 구문을 사용한다. 
 단, 해당 테이블 내에서 이미 사용중인 열 이름은 다시 사용할 수 없음으로 유의한다.
 ALTER TABLE `some_schema`.`some_table` ADD COLMN[열구조...];
 
 가령, a 스키마의 t 테이블에, 정수인 ca,cb,cc 열 총 세개를 추가하려면 아래와 같이 한다.
 
 ALTER TABLE `a`.`t` ADD COLMN `ca` INT UNSIGNED NOT NULL,
 ADD COLMN `cb` INT UNSIGNED NOT NULL,
 ADD COLMN `cc` INT UNSIGNED NOT NULL;
 
 ▫ 열 추가시 순서를 명시하지 않으면 테이블의 열 가장 끝에 추가된다. 
   기존의 특정열 뒤에 추가하고 싶다면 아래와 같이 명령한다. 
   
                    ↓ 스키마 이름                         
      > ALTER TABLE `some_schema`.`some_table` [ADD COLUMN 열 구조,...];
                                       ↑ 테이블 이름
 
 ▫ BEFORE 라는 키워드는 없으며 테이블의 열 구조상 가장앞에 (첫번째에) 열을 추가하고자 한다면 아래와 같이 `FIRST` 키워드를 이용한다.
  
                        ↓ 스키마 이름                         
      > ALTER TABLE `some_schema`.`some_table` [ADD COLUMN 열 구조 FIRST,...];
                                     ↑ 테이블 이름                         
     
▪ U: 존재하는 열 삭제하기
 ▫ 존재하는 테이블에 존재하는 열을 삭제하기 위해 아래 구문을 사용한다.
  ALTER TABLE `some_schema`.`some_table` [DROP COLMN 열이름,...];
  
  가령, a 스키마의 t테이블에서 ca,cb,cc 열을 삭제하기 우해 아래와 같이 명령한다.
  
 ▫ 존재하는 열의 이름과 타입, 순서를 동시에 변경(`RENAME` + `MODIFY`)하기 위해 아래와 같이 명령한다.
   
                        ↓ 스키마 이름                         
        ALTER TABLE `some_schema`.`some_table` [CHANGE COLUMN `대상 열 이름` `새로운 이름` [새로운 열 구조] [FIRST|AFTER x]?,...];
                                        ↑ 테이블 이름                         
      
▪ U : 존재하는 열 수정하기
 ▫ 존재하는 열의 이름을 수정하기 위해 아래와 같이 명령한다.
 
ALTER TABLE `some_schema`.`some_table` [RENAME COLUMN`대상 열 이름` TO `새로운 열 이름`...];
 
 ▫ 어떤 테이블에 이미 존재하는 열의 타입이나 순서를 변경하기 위해 아래와 같이 명령한다.
  
  ALTER TABLE `some_schema`.`some_table`[MODIFY COLMN`대상 열 이름` [새로운 열 구조] [FIRST|AFTER x]?...];
▪ U: 복합수정
 ▫ 열을 추가하거나 삭제, 수정 하는 등의 명령은 쉼표(,)로 구분하여 ALTER TABLE 하나의 구문으로 처리할 수 있다.
 ▫ 가령, a 스키마의 t 테이블에 대해 정수인 타입인 ca 라는 열을 추가하고, cb 열을 삭제하며, 정수 타입인 cc열을 뒤로 옮기는 명령은 아래와 같다.

       ALTER TABLE `a`.`t` ADD COLUMN `ca` INT,
                           DROP COLUMN `cb`,
                           MODIFY COLUMN `cc` INT AFTER `cd`;
   
▪ D: 삭제하기
 ▫ 존재하는 테이블을 삭제하기 위해 아래 구문을 사용한다.
↓소속 스키마이름
DROP TABLE `some_schema`.`some_table`;
                              ↑ 삭제할 테이블 이름
  
 ▫ 삭제하고자 하는 테이블이 존재하지 않을때 오류가 발생하는 것을 막기 위해 아래와 같은 구문을 사용한다.
↓소속 스키마이름  ↓삭제할 테이블 이름
DROP TABLE IF EXISTS`some_schema`.`some_table`;


- 새로운 테이블을 만들기 위해 아래 구문을 사용한다.
      
                        ↓ 소속 스키마   ↓ 새로 만들 테이블 이름
        CREATE TABLE `some_schema`.`some_table`
        (
            [열 구조,...],
            [제약 조건,...]? 
        );
       
        - 열 구조
            - 테이블 생성시 열 구조를 명시해야하며 열은 쉼표(,)로 구분하여 여러개 작성 가능하다. 기본적인 열 구조는 아래와 같다.
              > ```sql
              > `열 이름` [데이터 타입] [NULL|NOT NULL]? [DEFAULT x]? [AUTO_INCREMENT]?
              > ``` 

▪ 데이터 타입
▪ 숫자형
▪ 모든 숫자형 타입은 매개변수(아래에서 n)를 통해 그 자리수를 제한할 수 있다.
▪ ❤모든 숫자형 타입은 그 타입뒤에 UNSIGNED 키워드를 붙여 음수부를 양수부로 전환, 양수부에서 약 두배의 범위를 이용할 수 있다.
  가령, TINYINT UNSIGNED타입은 0부터 255까지의 수를 이용할 수 있다. 여기서 UNSIGNED는 '부호가 없는'이라는 뜻이다.
▪ TINYINT 혹은 TINYINT(n) : (1Byte)-128부터 127까지의 정수. 단, 값 n을 명시할 경우 그 자리수를 제한한다.
▪ SMALLINT 혹은 SMALLINT(n): (`2Bytes)-32768부터 32767까지의 정수
▪ MEDIUMINT 혹은 MEDIUMINT(n):(3 Bytes)-8388608 부터 8388607까지의 정수
▪ INT 혹은 INT(n) : ( 4 Bytes)-2147483648부터 2147483647까지의 정수
▪ BIGINT 혹은 BIGINT(n) : (8 Bytes) 사실상 무제한 수.

▪실수형
▪ DOUBLE :  (8 Bytes) 소수를 담을수 있다. DOUBLE타입도 연산방식에 의해 극도로 높은 수준의 연산에서 오류나 누락이 발생할 수 있음으로 
  데이터가 정확하고 한치의 오차도 허용하지 않는 환경이라면 사용하지 않는다.
▪ FLOAT : (4 Bytes) 소수를 담을 수 있다. 계산방식에 의해 소숫점 끝 연산에 오류나 누락이 발생할 수 있음으로 사용하지 않는다.
▪ DECIMAL(t,n): (t+1Bytes) 전체길이가 t, 소수부의 길이가 n인 실수를 담을 수 있따. 단, 소수부를 포함한 전체길이가 t임에 유의해야한다.
 
▪문자형
▪ VARCHAR(n) :( n Byte 혹은 2n Byte) 최대길이가 n자인 문자를 담을 수 있다. 이떄 n은 최대 65,535이다.
▪ TINYTEXT : (최대 255 Bytes) 문자를 담을 수 있다.
▪ TEXT : (최대 65,535 Bytes) 문자를 담을 수 있다.
▪ MEDIUMTEXT : (최대 16,777,215 Bytes) 문자를 담을 수 있다.
▪ LONGTEXT : (최대 4,294,967,295 Bytes) 문자를 담을 수 있따.
▪ VARCHAR타입의 경우 하나의 테이블 내에 VARCHAR 열들이 가지는 길이의 총합이 65,535를 넘을 수 없다.
▪ VARCHAR타입은 인덱스에 캐싱되어 속도가 빠르지만(쉽게 얘기하면 메모리에 임시저장됨). TEXT 타입은 캐싱되지않고 항시 드라이브에서 읽어와야 함으로 비교적 속도가 느리다.
▪ 날짜와 시간
▪ DATE : (3 Bytes) 년,월,일을 포함하는 날짜를 받을 수 있다. 시간을 담을 수 없음에 유의한다.
▪ TIME 혹은 TIME(n) :(3 Bytes) 시, 분,초를 포함하는 시간을 받을 수 있다. 날짜를 담을 수 없음에 유의한다. 이때 n은 밀리초의 길이를 의미한다.
  명시하지 않으면 밀리초는 없는 것으로 한다.
▪DATETIME 혹은 DATETIME(n) : (8 Bytes)년,월,일의 날짜와 시,분,초의 시간을 함께 받는다. 이때 n은 밀리초의 길이를 의미한다.
  명시하지 않으면 밀리초는 없는 것으로 한다.
▪ TIMESTAMP : 생략

▪기타
▪BOOLEAN:(1 Byte): 참 혹은 거짓의 논리값을 받을 수 있다. 사실은  TINYINT(1)이며 0을 제외한 모든 값을 참으로, 0을 거짓으로 인식한다.

▪ 빈 값
▪ NULL :  해당 열의 값이 비어있을 수 있음.(기본값)
▪ NOT NULL :  해당 열의 값이 비어있을 수 없음.

CREATE TABLE `some_schema`.`people`(
`name` VARCHAR(3),
`age` TINYINT,
`gender` VARCHAR(1)
);

▪ 기본값(DEFAULT x)
▪ 해당 열의 빈값(NULL)을 삽입(INSERT) 할때 대신 사용할 기본값이다.
▪ 자동증가 (AUTO-INCREMENT)
▪ 자동증가는 해당 열이 기본키(PRIMARY KEY)이고, 정수 타입일때 값 생략시 1부터 시작하여 1씩 증가시킨 값을 대신 대입하기 위해 사용한다.

◼ 열
▪ 열(Column)은 테이블에 들어가게 되는 데이터의 타입이나 개수 등의 형태를 지정하기 위해 사용한다.
  테이블은 반드시 한 개 이상의 열을 가지고 있어야 한다.