SQL (Structured Query Language) 예제 2

2022. 12. 4. 17:01리눅스(Linux)

$ SQL 테이블 제약조건 활용
   - 불 필요한 데이터의 유입을 방지하기 위해 사용
   - 데이터베이스 관리자가 요구하는 데이터를 저장하기 위해 사용
   - 무결성 제공을 위해 사용

제약조건의 종류
   - not null NULL값을 허용하지 않는다.
   - unique 중복 된 값을 허용하지 않는다.
   - primary key(기본키) not null + unique
   - default 데이터를 지정하지 않았을 경우 자동으로 default값을 지정
   - check 조건에 맞는지 검사 ( CHECK를 이용한 Table 생성가능, 하지만 Mysql은 이를 무시하므로 의미없음(HTML에서 제어) 
   - foreign key(외래키) 참조키: 자신의 테이블에서 다른 테이블의 값을 참조하고있는 경우 상대방의 Primary Key와 연결

 

[ not null ]
MariaDB [Sample]> create table test1 (No int(10) not null, Name varchar(20));
Query OK, 0 rows affected (0.03 sec)

MariaDB [Sample]> desc test1;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| No    | int(10)     | NO   |     | NULL    |       |
| Name  | varchar(20) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

MariaDB [Sample]> insert into test1 value ( 1, "choi_1" );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> insert into test1 value ( null, "choi_2" );
ERROR 1048 (23000): Column 'No' cannot be null

- Null 값을 허용하지 않았으므로, null값 지정이 불가능 한것을 확인

MariaDB [Sample]> select * from test1;
+----+--------+
| No | Name   |
+----+--------+
|  1 | choi_1 |
+----+--------+
1 row in set (0.00 sec)



[ 참고 ]
MariaDB [Sample]> insert into test1 (name) value ( "choi_2" );
Query OK, 1 row affected, 1 warning (0.01 sec)

MariaDB [Sample]> insert into test1 (name) value ( "choi_3" );
Query OK, 1 row affected, 1 warning (0.00 sec)

MariaDB [Sample]> select * from test1;
+----+--------+
| No | Name   |
+----+--------+
|  1 | choi_1 |
|  0 | choi_2 |
|  0 | choi_3 |
+----+--------+
3 rows in set (0.00 sec)
- 만약 필드를 직접 지정 후 하나의 값만 지정하여 값을 입력할 경우 입력가능



[ unique ]
MariaDB [Sample]> create table test2 ( No int(10) unique, Name varchar(20) );
Query OK, 0 rows affected (0.00 sec)

MariaDB [Sample]> desc test2;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| No    | int(10)     | YES  | UNI | NULL    |       |
| Name  | varchar(20) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

MariaDB [Sample]> insert into test2 value ( 1, "Choi_1" );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> insert into test2 value ( 1, "Choi_2" );
ERROR 1062 (23000): Duplicate entry '1' for key 'No'
- Unique로 지정 된 필드에 값은 중복으로 저장 될 수 없다.

MariaDB [Sample]> select * from test2;
+------+--------+
| No   | Name   |
+------+--------+
|    1 | Choi_1 |
+------+--------+
1 row in set (0.00 sec)

primary key(기본키)
   - not null + unique
   - 테이블을 대표할수 있는 데이터가 있는 컬럼
   - 테이블당 하나만 설정가능
   - primary key가 설정되면 자동으로 고유 인덱스(UNIQUE INDEX)가 자동생성

MariaDB [Sample]> create table test3 ( No int(10) default '0' primary key,
    -> Name varchar(20) default NULL,
    -> Point int(50) default NULL);
Query OK, 0 rows affected (0.00 sec)

MariaDB [Sample]> desc test3;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| No    | int(10)     | NO   | PRI | 0       |       |
| Name  | varchar(20) | YES  |     | NULL    |       |
| Point | int(50)     | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

MariaDB [Sample]> insert into test3 value (1, "choi_1", 100);
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> insert into test3 value (null, "choi_2", 200);
ERROR 1048 (23000): Column 'No' cannot be null
- 기본키로 지정된 값은 Null 값을 갖을 수 없다.

MariaDB [Sample]> alter table test3 add primary key(Name);
ERROR 1068 (42000): Multiple primary key defined
- 기본키는 테이블당 반드시 하나만 지정이 가능하다.

MariaDB [Sample]> alter table test3 drop primary key;
Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0
- 기본키 제거 ( auto_increment등이 적용되어있을 경우 제거가 되지 않는 경우도 존재 )

MariaDB [Sample]> desc test3;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| No    | int(10)     | NO   |     | 0       |       |
| Name  | varchar(20) | YES  |     | NULL    |       |
| Point | int(50)     | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

MariaDB [Sample]> alter table test3 add primary key(Name);
Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0
- 기본키를 Name 필드로 변경

MariaDB [Sample]> desc test3;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| No    | int(10)     | NO   |     | 0       |       |
| Name  | varchar(20) | NO   | PRI |         |       |
| Point | int(50)     | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

MariaDB [Sample]> alter table test3 drop primary key;
MariaDB [Sample]> alter table test3 add constraint test3_PK primary key (No);
Query OK, 0 rows affected (1.41 sec)
Records: 0  Duplicates: 0  Warnings: 0
- No를 다시 기본키로 변경

MariaDB [Sample]> select * from information_schema.table_constraints;
+--------------------+-------------------+-----------------+--------------+---------------------------+-----------------+
| CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME | TABLE_SCHEMA | TABLE_NAME                | CONSTRAINT_TYPE |
+--------------------+-------------------+-----------------+--------------+---------------------------+-----------------+
| def                | Sample            | No              | Sample       | test2                     | UNIQUE          |
| def                | Sample            | PRIMARY         | Sample       | test3                     | PRIMARY KEY     |
| def                | mysql             | PRIMARY         | mysql        | columns_priv              | PRIMARY KEY     |
| def                | mysql             | PRIMARY         | mysql        | db                        | PRIMARY KEY     |
| def                | mysql             | PRIMARY         | mysql        | event                     | PRIMARY KEY     |
| def                | mysql             | PRIMARY         | mysql        | func                      | PRIMARY KEY     |
| def                | mysql             | PRIMARY         | mysql        | help_category             | PRIMARY KEY     |
| def                | mysql             | name            | mysql        | help_category             | UNIQUE          |
+--------------------+-------------------+-----------------+--------------+---------------------------+-----------------+
27 rows in set (0.00 sec)


MariaDB [Sample]> create table test4 ( No int(10) default '0',
    -> name varchar(20) not null,
    -> gender varchar(10) not null default 'M',
    -> constraint test4_PK primary key (No));
Query OK, 0 rows affected (0.00 sec)
- constraint를 이용하여 제약조건에 이름을 부여하여 사용 할 수 있다.
※ 기본키 지정은 문법상에 차이만 존재하고, 위에서 정의한 제약조건과 동일한 결과

MariaDB [Sample]> desc test4;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| No     | int(10)     | NO   | PRI | 0       |       |
| name   | varchar(20) | NO   |     | NULL    |       |
| gender | varchar(10) | NO   |     | M       |       |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

MariaDB [Sample]> insert into test4 (No,name) value ( 1, "choi_1" );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> select * from test4;
+----+--------+--------+
| No | name   | gender |
+----+--------+--------+
|  1 | choi_1 | M      |
+----+--------+--------+
1 row in set (0.00 sec)
- 기본값이 지정 된 gender의 경우 값을 설정하지 않을경우 자동으로 'M'값이 입력

 

Foreign key(외래키)
   - Primary key를 포함하는 테이블은 부모테이블
   - Foreign key를 포함하는 테이블은 자식테이블
   - 정의형식 : constraint [제약조건이름] [제약조건(필드이름)] references [참조테이블명(필드이름)]
   - 부모테이블은 반드시 존재해야 한다. ( 부모테이블 먼저 작업 진행 )
   - 부모테이블에 참조되는 필드에 값이 존재해야 한다.
   - 참조하는 필드의 데이터타입과 참조되는 필드의 데이터타입은 반드시 일치되어야 한다.
   - 기본적으로 부모테이블의 데이터는 자식테이블에서 삭제 할 수 없다.

MariaDB [Sample]> create table test5 ( No int(10) not null,
    -> ID varchar(20) primary key,
    -> Name varchar(20) not null,
    -> gender char(2) default 'M');
Query OK, 0 rows affected (0.00 sec)

MariaDB [Sample]> desc test5;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| No     | int(10)     | NO   |     | NULL    |       |
| ID     | varchar(20) | NO   | PRI | NULL    |       |
| Name   | varchar(20) | NO   |     | NULL    |       |
| gender | char(2)     | YES  |     | M       |       |
+--------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)

MariaDB [Sample]> insert into test5 value ( 1, "s1", "choi_1", "M" );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> insert into test5 value ( 2, "s2", "choi_2", "M" );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> insert into test5 value ( 3, "s3", "choi_3", "M" );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> select * from test5;
+----+----+--------+--------+
| No | ID | Name   | gender |
+----+----+--------+--------+
|  1 | s1 | choi_1 | M      |
|  2 | s2 | choi_2 | M      |
|  3 | s3 | choi_3 | M      |
+----+----+--------+--------+
3 rows in set (0.00 sec)
- 기본키를 갖는 테이블 정의 후 데이터 입력까지 진행

MariaDB [Sample]> create table FK_test5 ( No int(10) not null,
    -> ID varchar(20),
    -> title varchar(50) not null,
    -> content varchar(200) not null,
    -> constraint test5_FK foreign key(ID) references test5(ID));
Query OK, 0 rows affected (0.00 sec)

MariaDB [Sample]> desc FK_test5;
+---------+--------------+------+-----+---------+-------+
| Field   | Type         | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| No      | int(10)      | NO   |     | NULL    |       |
| ID      | varchar(20)  | YES  | MUL | NULL    |       |
| title   | varchar(50)  | NO   |     | NULL    |       |
| content | varchar(200) | NO   |     | NULL    |       |
+---------+--------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
- 부모 테이블의 ID값을 참조하여 자식 테이블의 ID값을 참조키로 설정 후 Table 생성

MariaDB [Sample]> insert into FK_test5 value ( 1, "s1", "Hello", "MariaDB Test!" );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> insert into FK_test5 value ( 2, "s2", "Hello2", "MariaDB Test!2" );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> insert into FK_test5 value ( 3, "s3", "Hello3", "MariaDB Test!3" );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> insert into FK_test5 value ( 4, "s4", "Hello4", "MariaDB Test!4" );
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`Sample`.`FK_test5`, CONSTRAINT `test5_FK` FOREIGN KEY (`ID`) REFERENCES `test5` (`ID`))
- 부모 테이블에 존재하지 않는 ID값을 이용하여 데이터 입력시 Error가 발생하는 것을 확인
- 데이터의 무결성을 유지하기 위해 기본키와 참조키(외래키)를 사용한다.
- 존재하지 않는 ID를 이용하여 게시판 글 쓰기를 하는 것을 방지할 수 있다.

MariaDB [Sample]> select * from FK_test5;
+----+------+--------+----------------+
| No | ID   | title  | content        |
+----+------+--------+----------------+
|  1 | s1   | Hello  | MariaDB Test!  |
|  2 | s2   | Hello2 | MariaDB Test!2 |
|  3 | s3   | Hello3 | MariaDB Test!3 |
+----+------+--------+----------------+
3 rows in set (0.00 sec)



MariaDB [Sample]> drop table FK_test5;
Query OK, 0 rows affected (0.00 sec)
- 다음 테스트를 위해 반드시 삭제

MariaDB [Sample]> create table FK_test5 ( No int(10) not null,
    -> ID varchar(20),
    -> title varchar(50) not null,
    -> content varchar(200) not null,
    -> constraint test5_FK foreign key(ID) references test5(ID) on delete cascade);
Query OK, 0 rows affected (0.00 sec)
- on delete cascade ( 참조하는 부모테이블의 필드의 값이 삭제 될 경우 자식테이블 값을 함께 삭제 )

MariaDB [Sample]> insert into FK_test5 value ( 1, "s1", "Hello", "MariaDB Test!" );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> insert into FK_test5 value ( 2, "s2", "Hello2", "MariaDB Test!2" );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> insert into FK_test5 value ( 3, "s3", "Hello3", "MariaDB Test!3" );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> select * from test5;
+----+----+--------+--------+
| No | ID | Name   | gender |
+----+----+--------+--------+
|  1 | s1 | choi_1 | M      |
|  2 | s2 | choi_2 | M      |
|  3 | s3 | choi_3 | M      |
+----+----+--------+--------+
3 rows in set (0.00 sec)

MariaDB [Sample]> select * from FK_test5;
+----+------+--------+----------------+
| No | ID   | title  | content        |
+----+------+--------+----------------+
|  1 | s1   | Hello  | MariaDB Test!  |
|  2 | s2   | Hello2 | MariaDB Test!2 |
|  3 | s3   | Hello3 | MariaDB Test!3 |
+----+------+--------+----------------+
3 rows in set (0.00 sec)

MariaDB [Sample]> delete from test5 where ID = 's3';
Query OK, 1 row affected (0.01 sec)

MariaDB [Sample]> select * from test5;
+----+----+--------+--------+
| No | ID | Name   | gender |
+----+----+--------+--------+
|  1 | s1 | choi_1 | M      |
|  2 | s2 | choi_2 | M      |
+----+----+--------+--------+
2 rows in set (0.00 sec)

MariaDB [Sample]> select * from FK_test5;
+----+------+--------+----------------+
| No | ID   | title  | content        |
+----+------+--------+----------------+
|  1 | s1   | Hello  | MariaDB Test!  |
|  2 | s2   | Hello2 | MariaDB Test!2 |
+----+------+--------+----------------+
2 rows in set (0.00 sec)
- 참조하는 부모테이블의 데이터가 삭제되었으므로, 자식 테이블의 데이터가 함께 삭제



MariaDB [Sample]> drop table FK_test5;
Query OK, 0 rows affected (0.00 sec)
- 다음 테스트를 위해 반드시 삭제

MariaDB [Sample]> create table FK_test5 ( No int(10) not null,
    -> ID varchar(20),
    -> title varchar(50) not null,
    -> content varchar(200) not null,
    -> constraint test5_FK foreign key(ID) references test5(ID) on delete set null);
Query OK, 0 rows affected (0.00 sec)
- on delete set null ( 참조하는 부모테이블의 필드의 값이 삭제 될 경우 자식테이블 값을 NULL값으로 변경 )

MariaDB [Sample]> insert into FK_test5 value ( 1, "s1", "Hello", "MariaDB Test!" );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> insert into FK_test5 value ( 2, "s2", "Hello2", "MariaDB Test!2" );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> select * from test5;
+----+----+--------+--------+
| No | ID | Name   | gender |
+----+----+--------+--------+
|  1 | s1 | choi_1 | M      |
|  2 | s2 | choi_2 | M      |
+----+----+--------+--------+
2 rows in set (0.00 sec)

MariaDB [Sample]> select * from FK_test5;
+----+------+--------+----------------+
| No | ID   | title  | content        |
+----+------+--------+----------------+
|  1 | s1   | Hello  | MariaDB Test!  |
|  2 | s2   | Hello2 | MariaDB Test!2 |
+----+------+--------+----------------+
2 rows in set (0.00 sec)

MariaDB [Sample]> delete from test5 where ID = "s1";
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> select * from test5;
+----+----+--------+--------+
| No | ID | Name   | gender |
+----+----+--------+--------+
|  2 | s2 | choi_2 | M      |
+----+----+--------+--------+
1 row in set (0.00 sec)

MariaDB [Sample]> select * from FK_test5;
+----+------+--------+----------------+
| No | ID   | title  | content        |
+----+------+--------+----------------+
|  1 | NULL | Hello  | MariaDB Test!  |
|  2 | s2   | Hello2 | MariaDB Test!2 |
+----+------+--------+----------------+
2 rows in set (0.00 sec)
- 참조하는 부모테이블의 데이터가 삭제되었으므로, 자식 테이블의 데이터가 Null 값으로 변경된 것을 확인



참고 : [ auto_increment ]
- 자동으로 번호값이 증가하며, 데이터입력 ( 1 -> 2 -> 3 ... )
- 기본키로 지정되어야 해당 필드에 대한 auto_increment 설정을 진행 할 수 있다.
- 특정 데이터의 순서번호등을 정의할때 사용

MariaDB [Sample]> create table test6 ( No int(10) not null auto_increment primary key,
    -> ID varchar(20) not null,
    -> Name varchar(20) not null,
    -> gender char(2) default 'M');
Query OK, 0 rows affected (0.01 sec)

MariaDB [Sample]> desc test6;
+--------+-------------+------+-----+---------+----------------+
| Field  | Type        | Null | Key | Default | Extra          |
+--------+-------------+------+-----+---------+----------------+
| No     | int(10)     | NO   | PRI | NULL    | auto_increment |
| ID     | varchar(20) | NO   |     | NULL    |                |
| Name   | varchar(20) | NO   |     | NULL    |                |
| gender | char(2)     | YES  |     | M       |                |
+--------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

MariaDB [Sample]> insert into test6 (ID, Name, gender) value ("s1", "choi_1", "M");
MariaDB [Sample]> insert into test6 (ID, Name, gender) value ("s2", "choi_2", "M");
MariaDB [Sample]> insert into test6 (ID, Name, gender) value ("s3", "choi_3", "M");
MariaDB [Sample]> insert into test6 (ID, Name, gender) value ("s4", "choi_4", "M");

MariaDB [Sample]> select * from test6;
+----+----+--------+--------+
| No | ID | Name   | gender |
+----+----+--------+--------+
|  1 | s1 | choi_1 | M      |
|  2 | s2 | choi_2 | M      |
|  3 | s3 | choi_3 | M      |
|  4 | s4 | choi_4 | M      |
+----+----+--------+--------+
4 rows in set (0.00 sec)

- 기본 키값으로 지정 된 No의 값을 별도로 명시하지 않고 자동입력 되는것을 확인 할 수 있다.

$ Join, Group by, View 활용

JOIN 
   - 하나 이상의 테이블에 있는 데이터를 조회하기위해 사용 ( where 절에 기술 )
   - Primary Key를 중심으로 Forign Key와 일치하는 컬럼들에 대한 경우의 수를 만들어 사용하는 것이 일반적인 방법
   - 똑같은 열 이름이 하나 이상의 테이블에 존재 할 경우 모호성을 없애기 위해 컬럼앞에 테이블명을 명시한다.
   - 일반적으로 별명을 붙여 사용하며, 최대한 단순한 이름구조를 부여하여 사용
   - 데이터의 위치를 정확히 표현하여 DB의 성능향상에 도움을 줄 수 있다.
   - JOIN의 형태에 따라 키워드를 명시하고, 키워드는 테이블 사이에 명시한다.

[ 테이블 생성 ]

MariaDB [Sample]> create table student (
    -> student_id int primary key auto_increment,
    -> student_name varchar(50) not null,
    -> student_point varchar(10),
    -> student_in_class int
    -> );
Query OK, 0 rows affected (0.00 sec)

MariaDB [Sample]> create table subject (
    -> subject_id int primary key auto_increment,
    -> subject_name varchar(50) not null,
    -> subject_price varchar(50) not null
    -> );
Query OK, 0 rows affected (0.00 sec)


[ SUBJECT 데이터 입력 ]
MariaDB [Sample]> insert into subject (subject_id, subject_name, subject_price ) value ( 101, "Linux", "100,000" );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> insert into subject (subject_name, subject_price ) value ( "Windows", "100,000" );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> insert into subject (subject_name, subject_price ) value ( "Network", "100,000" );
Query OK, 1 row affected (0.01 sec)

MariaDB [Sample]> select * from subject;
+------------+--------------+---------------+
| subject_id | subject_name | subject_price |
+------------+--------------+---------------+
|        101 | Linux        | 100,000       |
|        102 | Windows      | 100,000       |
|        103 | Network      | 100,000       |
+------------+--------------+---------------+
3 rows in set (0.00 sec)


[ STUDENT 데이터 입력 ]

MariaDB [Sample]> insert into student ( student_id, student_name, student_point, student_in_class ) value ( 1000, "Choi", "1,000,000P", 101 );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> insert into student ( student_name, student_point, student_in_class ) value ( "LEE", "700,000P", 101 );
Query OK, 1 row affected (0.01 sec)

MariaDB [Sample]> insert into student ( student_name, student_point, student_in_class ) value ( "Kim", "500,000P", 102 );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> insert into student ( student_name, student_point, student_in_class ) value ( "Park", null, null );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> select * from student;
+------------+--------------+---------------+------------------+
| student_id | student_name | student_point | student_in_class |
+------------+--------------+---------------+------------------+
|       1000 | Choi         | 1,000,000P    |              101 |
|       1001 | LEE          | 700,000P      |              101 |
|       1002 | Kim          | 500,000P      |              102 |
|       1003 | Park         | NULL          |             NULL |
+------------+--------------+---------------+------------------+
4 rows in set (0.00 sec)

Cross Join
   - 조인되는 두 테이블에서 곱집합을 반환하는 join
   - N행을 가진 테이블과 M행을 가지는 테이블이 교차하며 최종결과로 N * M개의 결과를 표현
   - join의 별 다른 조건은 없다.

MariaDB [Sample]> select * from subject cross join student;
+------------+--------------+---------------+------------+--------------+---------------+------------------+
| subject_id | subject_name | subject_price | student_id | student_name | student_point | student_in_class |
+------------+--------------+---------------+------------+--------------+---------------+------------------+
|        101 | Linux        | 100,000       |       1000 | Choi         | 1,000,000P    |              101 |
|        102 | Windows      | 100,000       |       1000 | Choi         | 1,000,000P    |              101 |
|        103 | Network      | 100,000       |       1000 | Choi         | 1,000,000P    |              101 |
|        101 | Linux        | 100,000       |       1001 | LEE          | 700,000P      |              101 |
|        102 | Windows      | 100,000       |       1001 | LEE          | 700,000P      |              101 |
|        103 | Network      | 100,000       |       1001 | LEE          | 700,000P      |              101 |
|        101 | Linux        | 100,000       |       1002 | Kim          | 500,000P      |              102 |
|        102 | Windows      | 100,000       |       1002 | Kim          | 500,000P      |              102 |
|        103 | Network      | 100,000       |       1002 | Kim          | 500,000P      |              102 |
|        101 | Linux        | 100,000       |       1003 | Park         | NULL          |             NULL |
|        102 | Windows      | 100,000       |       1003 | Park         | NULL          |             NULL |
|        103 | Network      | 100,000       |       1003 | Park         | NULL          |             NULL |
+------------+--------------+---------------+------------+--------------+---------------+------------------+
12 rows in set (0.00 sec)
- subject 3행 * student 4행 = 총 12행이 출력되는것을 확인

MariaDB [Sample]> select * from subject,student;
+------------+--------------+---------------+------------+--------------+---------------+------------------+
| subject_id | subject_name | subject_price | student_id | student_name | student_point | student_in_class |
+------------+--------------+---------------+------------+--------------+---------------+------------------+
|        101 | Linux        | 100,000       |       1000 | Choi         | 1,000,000P    |              101 |
|        102 | Windows      | 100,000       |       1000 | Choi         | 1,000,000P    |              101 |
|        103 | Network      | 100,000       |       1000 | Choi         | 1,000,000P    |              101 |
|        101 | Linux        | 100,000       |       1001 | LEE          | 700,000P      |              101 |
|        102 | Windows      | 100,000       |       1001 | LEE          | 700,000P      |              101 |
|        103 | Network      | 100,000       |       1001 | LEE          | 700,000P      |              101 |
|        101 | Linux        | 100,000       |       1002 | Kim          | 500,000P      |              102 |
|        102 | Windows      | 100,000       |       1002 | Kim          | 500,000P      |              102 |
|        103 | Network      | 100,000       |       1002 | Kim          | 500,000P      |              102 |
|        101 | Linux        | 100,000       |       1003 | Park         | NULL          |             NULL |
|        102 | Windows      | 100,000       |       1003 | Park         | NULL          |             NULL |
|        103 | Network      | 100,000       |       1003 | Park         | NULL          |             NULL |
+------------+--------------+---------------+------------+--------------+---------------+------------------+
12 rows in set (0.00 sec)
- 크로스 조인의 경우 단순히 테이블이름을 여러개 명시하여 작업이 가능하다.

Inner Join 
   - 가장 기본이되고, 많이 사용되는 결합방식의 조인
   - 조인 구문에 2개의 테이블의 컬럼값을 결합함으로써 새로운 결과 테이블을 생성한다.
   - 내부 조인은 2개의 테이블에서 NULL값을 갖는 열들은 조인에서 제외 된다.

MariaDB [Sample]> select student.student_name, subject.subject_id, subject.subject_name from subject inner join student on subject.subject_id = student.student_in_class;
+--------------+------------+--------------+
| student_name | subject_id | subject_name |
+--------------+------------+--------------+
| Choi         |        101 | Linux        |
| LEE          |        101 | Linux        |
| Kim          |        102 | Windows      |
+--------------+------------+--------------+
3 rows in set (0.00 sec)
- 특정 학생이 어떠한 수업을 듣고있는지 검색하기 위해 INNER JOIN을 사용
- 서로 다른 테이블의 정보를 가져와 새로운 테이블형식으로 내용을 출력

Outer JOIN 
   - join조건을 만족하지 않는 나머지 데이터를 확인하기 위해 사용 
   - Null값을 갖는 데이터를 함께 출력하기 위해 사용
   - left, right의 차이점은 Null값이 존재하는 테이블이 왼쪽인지 오른쪽인지를 구분하는 용도

[ Left Join ]
MariaDB [Sample]> select student.student_name, student.student_point, subject.subject_id, subject.subject_name from student left join subject on subject.subject_id = student.student_in_class;
+--------------+---------------+------------+--------------+
| student_name | student_point | subject_id | subject_name |
+--------------+---------------+------------+--------------+
| Choi         | 1,000,000P    |        101 | Linux        |
| LEE          | 700,000P      |        101 | Linux        |
| Kim          | 500,000P      |        102 | Windows      |
| Park         | NULL          |       NULL | NULL         |
+--------------+---------------+------------+--------------+
4 rows in set (0.00 sec)
- left join 기준 왼쪽에 Student 테이블이 지정되어 있으므로, Student Table의 Null값이 함께 포함되어 출력

[ Right Join ]
MariaDB [Sample]> select student.student_name, student.student_point, subject.subject_id, subject.subject_name from subject right join student on subject.subject_id = student.student_in_class;
+--------------+---------------+------------+--------------+
| student_name | student_point | subject_id | subject_name |
+--------------+---------------+------------+--------------+
| Choi         | 1,000,000P    |        101 | Linux        |
| LEE          | 700,000P      |        101 | Linux        |
| Kim          | 500,000P      |        102 | Windows      |
| Park         | NULL          |       NULL | NULL         |
+--------------+---------------+------------+--------------+
4 rows in set (0.00 sec)
- right join 기준 오른쪽에 Student 테이블이 지정되어 있으므로, Student Table의 Null값이 함께 포함되어 출력

Full Join
   - MariaDB, Mysql에서는 사용 불가 비슷한 형식의 UNION을 사용 할 수 있음
   - Query 작성은 따로 진행하지 않는다. ( 조건을 만족하는 부분을 제외 한 나머지 출력 )

Self Join 
   - 자기 자신의 데이터를 이용 한 Join 작업

[ 테이블 생성 ]
MariaDB [Sample]> create table sub (
    -> sub_id int primary key auto_increment,
    -> sub_name varchar(50) not null,
    -> sub_parent int
    -> );
Query OK, 0 rows affected (0.04 sec)

[ 데이터 입력 ]
MariaDB [Sample]> insert into sub (sub_id, sub_name, sub_parent ) value ( 101, "OpenStack", null );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> insert into sub (sub_name, sub_parent ) value ( "Linux", 101 );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> insert into sub (sub_name, sub_parent ) value ( "Window", 101 );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> insert into sub (sub_name, sub_parent ) value ( "Network", 101 );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> select * from sub;
+--------+-----------+------------+
| sub_id | sub_name  | sub_parent |
+--------+-----------+------------+
|    101 | OpenStack |       NULL |
|    102 | Linux     |        101 |
|    103 | Window    |        101 |
|    104 | Network   |        101 |
+--------+-----------+------------+
4 rows in set (0.00 sec)

MariaDB [Sample]> select p.sub_name AS Parent, c.sub_name AS Child from sub as p join sub as c on p.sub_id = c.sub_parent;
+-----------+---------+
| Parent    | Child   |
+-----------+---------+
| OpenStack | Linux   |
| OpenStack | Window  |
| OpenStack | Network |
+-----------+---------+
3 rows in set (0.00 sec)
- OpenStack 과목을 수강하기위해 하위 과목인 Linux, Window, Network를 함께 출력하는 Self Join 구성

 

GROUP BY ~ HAVING
   - 데이터들을 원하는 그룹으로 나눌 때 사용

# select [GROUP BY 절에 지정 된 컬럼] [GROUP BY별로 집계 할 값] from 테이블명 GROUP BY [그룹으로 묶을 컴럼]
   - 사용 예시

 

MariaDB [Sample]> create table mem (
    -> mem_id int primary key auto_increment,
    -> mem_name varchar(50) not null,
    -> mem_pay int not null
    -> );
Query OK, 0 rows affected (0.00 sec)

MariaDB [Sample]> insert into mem ( mem_id, mem_name, mem_pay ) value ( 1001, "S1", 4000000 );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> insert into mem ( mem_name, mem_pay ) value ( "S2", 3500000 );
Query OK, 1 row affected (0.01 sec)

MariaDB [Sample]> insert into mem ( mem_name, mem_pay ) value ( "S3", 3000000 );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> insert into mem ( mem_name, mem_pay ) value ( "S4", 2700000 );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> insert into mem ( mem_name, mem_pay ) value ( "S5", 5000000 );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> insert into mem ( mem_name, mem_pay ) value ( "S6", 5500000 );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> insert into mem ( mem_name, mem_pay ) value ( "S7", 2900000 );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> insert into mem ( mem_name, mem_pay ) value ( "S8", 4300000 );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> insert into mem ( mem_name, mem_pay ) value ( "S9", 4500000 );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> insert into mem ( mem_name, mem_pay ) value ( "S10", 2500000 );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> select * from mem;
+--------+----------+---------+
| mem_id | mem_name | mem_pay |
+--------+----------+---------+
|   1001 | S1       | 4000000 |
|   1002 | S2       | 3500000 |
|   1003 | S3       | 3000000 |
|   1004 | S4       | 2700000 |
|   1005 | S5       | 5000000 |
|   1006 | S6       | 5500000 |
|   1007 | S7       | 2900000 |
|   1008 | S8       | 4300000 |
|   1009 | S9       | 4500000 |
|   1010 | S10      | 2500000 |
+--------+----------+---------+
10 rows in set (0.00 sec)

[ select 문을 사용하여 간단한 수식 처리 ]

MariaDB [Sample]> select count(*) from mem;
+----------+
| count(*) |
+----------+
|       10 |
+----------+
1 row in set (0.00 sec)
- 전체 행의 수 출력 ( count : 행의 수 )

MariaDB [Sample]> select sum(mem_pay) from mem;
+--------------+
| sum(mem_pay) |
+--------------+
|     37900000 |
+--------------+
1 row in set (0.00 sec)
- Member 전체의 급여을 더한 후 출력 ( sum : 합 )

MariaDB [Sample]> select max(mem_pay), min(mem_pay) from mem;
+--------------+--------------+
| max(mem_pay) | min(mem_pay) |
+--------------+--------------+
|      5500000 |      2500000 |
+--------------+--------------+
1 row in set (0.01 sec)
- 급여의 최대값, 최소값 출력 ( max : 최대값, min : 최소값 )

MariaDB [Sample]> select * from mem order by mem_pay desc limit 1;
+--------+----------+---------+
| mem_id | mem_name | mem_pay |
+--------+----------+---------+
|   1005 | S6       | 5500000 |
+--------+----------+---------+
1 row in set (0.00 sec)

MariaDB [Sample]> select * from mem order by mem_pay asc limit 1;
+--------+----------+---------+
| mem_id | mem_name | mem_pay |
+--------+----------+---------+
|   1009 | S10      | 2500000 |
+--------+----------+---------+
1 row in set (0.00 sec)
- MAX, MIN 함수가 아닌 mem_pay를 기준으로 정렬 후 데이터를 limit을 이용하여 1개씩만 출력하도록 지정도 가능


MariaDB [Sample]> select round(avg(mem_pay)) from mem;
+---------------------+
| round(avg(mem_pay)) |
+---------------------+
|             3790000 |
+---------------------+
1 row in set (0.00 sec)
- Member의 평균 급여을 계산 후 출력 ( round : 소수점 제거, avg : 평균 )


MariaDB [Sample]> select mem_name, mem_pay from mem group by mem_pay;
+----------+---------+
| mem_name | mem_pay |
+----------+---------+
| S10      | 2500000 |
| S4       | 2700000 |
| S7       | 2900000 |
| S3       | 3000000 |
| S2       | 3500000 |
| S1       | 4000000 |
| S8       | 4300000 |
| S9       | 4500000 |
| S5       | 5000000 |
| S6       | 5500000 |
+----------+---------+
10 rows in set (0.00 sec)
- mem 테이블의 각 Member들의 급여를 그룹하여 출력 
- HAVING의 경우 그룹화 된 데이터에 대한 조건을 정의하기 위해 사용 ( 필수 X )
- 기본적으로 오름차순 정렬되어 출력된다.

MariaDB [Sample]> select mem_name, mem_pay from mem group by mem_pay order by mem_pay desc;
+----------+---------+
| mem_name | mem_pay |
+----------+---------+
| S6       | 5500000 |
| S5       | 5000000 |
| S9       | 4500000 |
| S8       | 4300000 |
| S1       | 4000000 |
| S2       | 3500000 |
| S3       | 3000000 |
| S7       | 2900000 |
| S4       | 2700000 |
| S10      | 2500000 |
+----------+---------+
10 rows in set (0.00 sec)
- 내림차순 정렬 후 데이터 출력

MariaDB [Sample]> select mem_name, mem_pay from mem group by mem_pay HAVING mem_name = "S1";
+----------+---------+
| mem_name | mem_pay |
+----------+---------+
| S1       | 4000000 |
+----------+---------+
1 row in set (0.00 sec)
- 그룹화가 진행 된 데이터 중 S1 이름을 갖는 Member만 출력

MariaDB [Sample]> select mem_name, mem_pay from mem group by mem_pay HAVING mem_pay > 3000000 order by mem_pay asc;
+----------+---------+
| mem_name | mem_pay |
+----------+---------+
| S2       | 3500000 |
| S1       | 4000000 |
| S8       | 4300000 |
| S9       | 4500000 |
| S5       | 5000000 |
| S6       | 5500000 |
+----------+---------+
6 rows in set (0.00 sec)
- 그룹화가 진행 된 데이터 중 급여가 300만보다 큰 값을 갖는 Member만 출력

MariaDB [Sample]> select mem_name, mem_pay from mem group by mem_pay having mem_pay > (select round(avg(mem_pay)) from mem) order by mem_pay asc; 
+----------+---------+
| mem_name | mem_pay |
+----------+---------+
| S1       | 4000000 |
| S8       | 4300000 |
| S9       | 4500000 |
| S5       | 5000000 |
| S6       | 5500000 |
+----------+---------+
5 rows in set (0.00 sec)
- 전체 Member중 평균 급여보다 많은 급여를 받는 사용자를 출력

MariaDB [Sample]> select mem_name, mem_pay from mem group by mem_pay having mem_pay = ( select max(mem_pay) from mem ) or mem_pay = ( select min(mem_pay) from mem );
+----------+---------+
| mem_name | mem_pay |
+----------+---------+
| S10      | 2500000 |
| S6       | 5500000 |
+----------+---------+
2 rows in set (0.00 sec)
- 전체 Member중 급여가 가장 높은 Member와 급여가 가장 작은 Member의 이름을 급여정보와 함께 출력

 

 

VIEW 
   - 자주 사용하는 SQL문을 미리 정의해 놓은 SQL문
   - 테이블과 유사한 구조를 갖지만 실제 데이터 저장과 같은 작업을 수행하지 않으므로 물리적인 저장공간이 따로 필요하지 않다.
   - Data를 물리적으로 저장하는 것이 아닌, 논리적으로 연결되어있는 형태 ( Link )
   - View의 경우 "Select"만 사용이 가능하며, 데이터의 변경사항을 줄 수 있는 "insert, delete, update"등은 사용이 불가능하다.
   - View를 조회 할 경우 Dictionary에 저장되어있는 해당 View의 SQL문장을 실행 후 해당 테이블로 접근
 

# create [ OR REPLACE ] [ FORCE | NOFORCE ] view [view name] ( View 필드, View 필드, ... ) as [SQL]
   - 사용 예시
MariaDB [Sample]> use mysql;
- 기존 Sample DB에서 mysql DB로 변경 

MariaDB [mysql]> create view test_view ( user, host, password ) as select host,user,password from user;
Query OK, 0 rows affected (0.00 sec)

MariaDB [mysql]> select * from test_view;
+-----------+--------+-------------------------------------------+
| user      | host   | password                                  |
+-----------+--------+-------------------------------------------+
| localhost | root   | *E1B74369B47EB3AD8EF858144E1A0364E3259329 |
| localhost | itbank | *E1B74369B47EB3AD8EF858144E1A0364E3259329 |
| 127.0.0.1 | root   | *E1B74369B47EB3AD8EF858144E1A0364E3259329 |
| ::1       | root   | *E1B74369B47EB3AD8EF858144E1A0364E3259329 |
+-----------+--------+-------------------------------------------+
4 rows in set (0.00 sec)
- 새로운 View 생성 후 select 문의 조회결과를 연결하여 저장
- select 문을 이용하여 해당 View 내용 확인

MariaDB [mysql]> drop view test_view;
Query OK, 0 rows affected (0.00 sec)
- View 삭제

MariaDB [Sample]> use Sample;
- 기존 mysql DB에서 Sample DB로 변경 

MariaDB [Sample]> create view sub_parent ( Parent, Child ) as select p.sub_name AS Parent, c.sub_name AS Child from sub as p join sub as c on p.sub_id = c.sub_parent;
Query OK, 0 rows affected (0.01 sec)

MariaDB [Sample]> select * from sub_parent;
+-----------+---------+
| Parent    | Child   |
+-----------+---------+
| OpenStack | Linux   |
| OpenStack | Window  |
| OpenStack | Network |
+-----------+---------+
3 rows in set (0.00 sec)
- 이전에 사용 한 Self Join Quer를 View로 정의

MariaDB [Sample]> insert into sub (sub_name, sub_parent ) value ( "Python", 101 );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> select * from sub_parent;
+-----------+---------+
| Parent    | Child   |
+-----------+---------+
| OpenStack | Linux   |
| OpenStack | Window  |
| OpenStack | Network |
| OpenStack | Python  |
+-----------+---------+
4 rows in set (0.00 sec)
- 새로운 데이터를 테이블에 정의 후 View 확인
- 논리적인 연결 구조를 갖게 되므로, 변경사항을 바로 확인 할 수 있다.

$ Transaction
   - 여러 단계의 작업과정을 마치 하나의 작업과정으로 처리하는 것
   - 트랜잭션의 작업결과 반영( Commit )
   - 이전 상태로 되돌리는 것( Roll-Back )
   - MariaDB의 경우 자동 Commit이 활성화 되어있으므로, 입력 된 SQL문을 즉시 반영하게 된다.
   - DB 저장 엔진에 따라 트랜잭션을 지원하지 않을 수 도 있다.

1. MyISAM Engine ( 마이아이삼 )

[장점]
   - ISAM의 경우 별다른 큰 기능을 지원하지 않고 단순하므로 전체적인 속도는 innoDB보다 빠르다. 
   - 읽기(select) 위주의 처리는 빠른 속도를 자랑한다, Full-text 인덱싱이 가능하다.

[단점]
   - Table 단위의 Locking을 진행하여 쓰기 작업에는 속도가 느리다. 
   - transaction 기능을 제공하지 않아 작업 중 문제 발생 시 잘못 된 데이터가 DB에 그대로 입력되게 된다.
   - 데이터의 무결성(Integrity)을 제공하지 않아, 관리자가 직접 무결성 작업을 해야 한다.

[사용예시]
   - 개인 Blog, 개인 Site ( 작성자는 적고, 조회는 빈번한 곳 )

2. InnoDB Engine ( 이노디비 ) 

[장점]
   - 데이터의 무결성(Integrity)을 보장 [ 무결성 규약, 무결성 제약조건, 참조 무결성 (외래키) ]
   - Transaction 기능을 제공( Commit, Rollback )
   - Row단위의 Locking을 지원하므로 쓰기 작업의 속도가 빠르다.

[단점] 
   - 시스템 자원을 많이 사용하며, 구조가 복잡하여 전체적인 속도가 ISAM보다 느리다.
   - Full-text 인덱싱이 불가능하다.

[사용예시]
   - 대규모 Site, 변경처리가 많은 곳

MariaDB [Sample]> show create table test1;
+-----------------------------------------------------+
| Table | Create Table                                |
+-----------------------------------------------------+
| test1 | CREATE TABLE `test1` (
  `No` int(10) NOT NULL,
  `Name` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1                |
+-------+---------------------------------------------+
1 row in set (0.00 sec)
- 기존에 생성하였던 TEST1 테이블을 show create를 이용하여 ENGINE의 종류를 확인

MariaDB [Sample]> alter table test1 engine=myisam;
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

MariaDB [Sample]> show create table test1;
+-----------------------------------------------------+
| Table | Create Table                                |
+-----------------------------------------------------+
| test1 | CREATE TABLE `test1` (
  `No` int(10) NOT NULL,
  `Name` varchar(20) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1                |
+-------+---------------------------------------------+
1 row in set (0.00 sec)
- 저장 엔진의 종류를 변경할 수 있으며, alter를 사용하여 작업

MariaDB [Sample]> alter table test1 engine=InnoDB;
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

MariaDB [Sample]> show create table test1;
+-----------------------------------------------------+
| Table | Create Table                                |
+-----------------------------------------------------+
| test1 | CREATE TABLE `test1` (
  `No` int(10) NOT NULL,
  `Name` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1                |
+-------+---------------------------------------------+
1 row in set (0.00 sec)
- 다시 기본 Engine인 InnoDB로 변경

MariaDB [Sample]> select * from sub;
+--------+-----------+------------+
| sub_id | sub_name  | sub_parent |
+--------+-----------+------------+
|    101 | OpenStack |       NULL |
|    102 | Linux     |        101 |
|    103 | Window    |        101 |
|    104 | Network   |        101 |
|    105 | Python    |        101 |
+--------+-----------+------------+
5 rows in set (0.00 sec)

MariaDB [Sample]> start transaction;
Query OK, 0 rows affected (0.00 sec)
- 트랜잭션 시작 지점

MariaDB [Sample]> delete from sub;
Query OK, 5 rows affected (0.00 sec)

MariaDB [Sample]> select * from sub;
Empty set (0.00 sec)
- 기존에 생성해두었던 sub 테이블의 모든 데이터를 삭제 후 조회
- 조건 설정이 없으므로, 전체 데이터가 삭제 된 것을 확인 할 수 있다.

MariaDB [Sample]> rollback;
Query OK, 0 rows affected (0.00 sec)
- rollback 작업을 통한 복구

MariaDB [Sample]> select * from sub;
+--------+-----------+------------+
| sub_id | sub_name  | sub_parent |
+--------+-----------+------------+
|    101 | OpenStack |       NULL |
|    102 | Linux     |        101 |
|    103 | Window    |        101 |
|    104 | Network   |        101 |
|    105 | Python    |        101 |
+--------+-----------+------------+
5 rows in set (0.00 sec)
- 기존에 저장 되어있던 데이터가 다시 표시되는 것을 확인

MariaDB [Sample]> commit;
Query OK, 0 rows affected (0.00 sec)
- 트랜잭션 작업 종료 지점 

MariaDB [Sample]> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
|            1 |
+--------------+
1 row in set (0.00 sec)
- 현재 기본값으로 Auto Commit이 설정되어있는 것을 확인

MariaDB [Sample]> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)

MariaDB [Sample]> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
|            0 |
+--------------+
1 row in set (0.00 sec)
- Auto Commit 기능을 비 활성화

MariaDB [Sample]> insert into sub (sub_name, sub_parent ) value ( "MariaDB", 101 );
Query OK, 1 row affected (0.00 sec)

MariaDB [Sample]> select * from sub;
+--------+-----------+------------+
| sub_id | sub_name  | sub_parent |
+--------+-----------+------------+
|    101 | OpenStack |       NULL |
|    102 | Linux     |        101 |
|    103 | Window    |        101 |
|    104 | Network   |        101 |
|    105 | Python    |        101 |
|    106 | MariaDB   |        101 |
+--------+-----------+------------+
6 rows in set (0.00 sec)
- 새로운 데이터 입력 후 내용확인 정상적으로 입력되어있는 것을 확인 할 수 있다.

MariaDB [Sample]> rollback;
Query OK, 0 rows affected (0.00 sec)

MariaDB [Sample]> select * from sub;
+--------+-----------+------------+
| sub_id | sub_name  | sub_parent |
+--------+-----------+------------+
|    101 | OpenStack |       NULL |
|    102 | Linux     |        101 |
|    103 | Window    |        101 |
|    104 | Network   |        101 |
|    105 | Python    |        101 |
+--------+-----------+------------+
5 rows in set (0.00 sec)
- rollback 입력 후 다시 확인 할 경우 새로 입력한 데이터가 사라진 것을 확인

MariaDB [Sample]> commit;
Query OK, 0 rows affected (0.00 sec)
- 하나의 작업 단위의 끝지점을 지정하기 위해서는 반드시 commit을 진행

MariaDB [Sample]> set autocommit=1;
Query OK, 0 rows affected (0.00 sec)

MariaDB [Sample]> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
|            1 |
+--------------+
1 row in set (0.00 sec)
- 다시 Auto Commit 기능을 활성화

※ [ 주의할점 ]
- Auto Commit이 비활성화 상태여도 즉시 적용되는 SQL문은 항상 조심해서 작업을 진행
- DROP, ALTER등이 대표적이다.