[SQL] : CRUD

채록·2021년 3월 19일
0

Database

목록 보기
3/11
post-thumbnail

Django의 ORF은 정말 소중한 기능이었다.. 이번에 브랜디로 기업협업을 나가게 되었는데 일단 Django 대신 Flask를 사용해야 했고, ORM 을 사용하지 말라 하셨다!

이제까지 ORM을 통해 CRUD 하던것을 SQL문으로 작성해 주어야 한다.

개념자체는 어려워 보이진 안히만 더 꼼꼼하고, 뭔가 글이 더 길다! 파악해보자



0. TABLE 생성 : 예제로 실습

참고한 문서는 PyMySQL 공식문서 이다. 참고로 해당 문서는 쪽수가 그렇게 길지 않다! 핵심만? 혹은 아주 간단한 이론만 설명한듯 하다.
추가적으로 SQL 첫걸음 책을 통해 공부할 예정이다.

mysql> show tables;
Empty set (0.00 sec)

mysql> CREATE TABLE `users` (
    ->     `id` int(11) NOT NULL AUTO_INCREMENT,
    ->     `email` varchar(255) COLLATE utf8_bin NOT NULL,
    ->     `password` varchar(255) COLLATE utf8_bin NOT NULL,
    ->     PRIMARY KEY (`id`)
    -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
    -> AUTO_INCREMENT=1 ;
Query OK, 0 rows affected, 3 warnings (0.06 sec)

mysql> show tables;
+---------------------+
| Tables_in_brandi_pr |
+---------------------+
| users               |
+---------------------+
1 row in set (0.01 sec)

mysql> DESC users;
+----------+--------------+------+-----+---------+----------------+
| Field    | Type         | Null | Key | Default | Extra          |
+----------+--------------+------+-----+---------+----------------+
| id       | int          | NO   | PRI | NULL    | auto_increment |
| email    | varchar(255) | NO   |     | NULL    |                |
| password | varchar(255) | NO   |     | NULL    |                |
+----------+--------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)

SQL문을 통해 table을 생성한 모습이다. (MySQL 사용)

각 줄 설명

  • CRAETE TABLE 'users' : 'users'라는 table을 생성한다.
  • 'id' int(11) NOT NULL AUTO_INCREMENT : 아직 int(11)이 의미하는 바를 알지 못한다. 11자리 숫자까지 가능하다는것 같은데 임의로 조절해 줘도 되나 싶다 / null을 허용하지 않고 값은 자동증가
  • 'email' varchar(255) COLLATE utf8_bin NOT NULL : varchar제한길이 255자의 utf8_bin형태로 값을 입력하게 하며 null을 허용하지 않는다.
  • 'password' varchar(255) COLLATE utf8_bin NOT NULL : 위와 동일
  • PRIMARY KEY ('id') : 이 table의 PK는 'id' field로 지정한다.
  • ENGINE=InnoB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin : 파악중... / 기본값으로 입력 문자 형태를 지정한다.
  • AUTO_INCREMENT=1 자동증가는 값1씩 한다
  • ; 생성 명령문 끝!

위 코드를 통해 users 라는 table이 생성되었고 DESC users; 를 통해 table의 field 속성을 살펴보니 설정한 대로 잘 생성되었다.!


Django를 사용할땐 그냥 models.py 에 작성하고 makemigrations / migrate 하면 자동으로 생성됐었는데.. 그립다 Django



I. CREATE : INSERT - 행 추가하기

mysql> INSERT INTO users VALUES(1, 'a@gmail.com', '1234');
Query OK, 1 row affected (0.02 sec)

mysql> SELECT * from users;
+----+-------------+----------+
| id | email       | password |
+----+-------------+----------+
|  1 | a@gmail.com | 1234     |
+----+-------------+----------+
1 row in set (0.00 sec)

행 추가후 결과 확인하기
SELECT명령과 달리 INSERT명령은 결과를 출력하지 않는다.
=> INSERT명령은 데이터가 클라이언트에서 서버로 전송되기 때문!

ID(PK) 입력 ?
"id" 라는 field가 primary keyAuto Increment로써 행 생성 시 입력하지 않아도 되는줄 알았다. 하지만 id를 빼로 INSERT 하려고 하니

mysql> INSERT INTO users VALUES('a@gmail.com', '1234');
ERROR 1136 (21S01): Column count doesn't match value count at row 1

위와 같은 에러가 발생했다.



1) 지정한 열에 행 추가하기

지정되지 않은 열은 NULL값이 들어간다. 때문에 null=false 인 열이 지정되지 않으면 안된다

mysql> INSERT INTO users(email, password) VALUES('b@gmail.com', '1234');
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * from users;
+----+-------------+----------+
| id | email       | password |
+----+-------------+----------+
|  1 | a@gmail.com | 1234     |
|  2 | b@gmail.com | 1234     |
+----+-------------+----------+
2 rows in set (0.00 sec)

ID(PK) 입력 X
열을 지정하여 행을 추가할 경우 AI/PK 값인 'id' 열은 입력하지 않아도 된다!

null=True도 아니고 default값도 없는 열 미입력

mysql> INSERT INTO users(email, password) VALUES('b@gmail.com', '1234');
ERROR 1364 (HY000): Field 'password' doesn't have a default value

다음과 같이 default값이 없다고 에러가 뜬다.

1) NOT NULL 제약조건

지정한 열이 NULL=true가 아니더라도 NULL값으로 추가해 주면 된다? 싶지만 되지 않는다

mysql> INSERT INTO users(email, password) values('b@gmail.com', NULL);
ERROR 1048 (23000): Column 'password' cannot be null


+) 추가 연습

Null=True일때와 default값이 설정되어 있을때 열을 지정하여 행을 추가하는 상황을 연습하기 위해 다음과 같은 table을 생성해 주었다.

mysql> CREATE TABLE nonusers (
    ->idint(11) NOT NULL AUTO_INCREMENT,
    ->     ‘email’ varchar(10) COLLATE utf8_bin,
    ->     ‘password’ varchar(8) COLLATE utf8_bin,
    ->     ‘name’ varchar(10) COLLATE utf8_bin default 1,
    ->     PRIMARY KEY (id)
    -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
    -> AUTO_INCREMENT=1;
Query OK, 0 rows affected, 4 warnings (0.02 sec)

mysql> DESC nonusers;
+----------------+-------------+------+-----+---------+----------------+
| Field          | Type        | Null | Key | Default | Extra          |
+----------------+-------------+------+-----+---------+----------------+
|id| int         | NO   | PRI | NULL    | auto_increment |
| ‘email’        | varchar(10) | YES  |     | NULL    |                |
| ‘password’     | varchar(8)  | YES  |     | NULL    |                |
| ‘name’         | varchar(10) | YES  |     | 1       |                |
+----------------+-------------+------+-----+---------+----------------+
4 rows in set (0.01 sec)

email 값만 입력하기

mysql> INSERT INTO nonusers(‘email’) values('b');
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * from nonusers;
+----------+-------------+----------------+------------+
|id| ‘email’     | ‘password’     | ‘name’     |
+----------+-------------+----------------+------------+
|        1 | b           | NULL           | 1          |
+----------+-------------+----------------+------------+
1 row in set (0.00 sec)

table 형태 잘못됨
field이름을 지을때 따옴표까지 같이 문자열로 인식될줄 몰랐다. 잘못 입력했다..

=> Null=True설정인 password는 그대로 NULL 값이 입력되었고, default=1로 설정되었던 name에는 기본값인 1이 입력되었다.




II. DELETE : 행 삭제하기

DELETE FROM 테이블명 WHERE 조건식

이 명령어는 지난 프로젝트기간동안 많이 사용해 봤다...

delete from postings where id >5;

이런식으로?


1) 여러 조건의 행 삭제하기

AND

DELETE FROM 테이블명 WHERE 조건1(height>170) AND 조건2(age=20)

OR

DELETE FROM 테이블명 WHERE 조건1(id=1) OR 조건2(id=2)

주의!!!

어떤행부터 삭제할 것인지는 중요하지도 않고 의미도 없다! 때문에 DELETE 하는데에 ORDER_BY는 사용할 수 없다.





III. UPDATE : 갱신하기

UPDATE 테이블명 SET 열1=1,2=2, ... WHERE 조건식

조건식에 일치하는 모든 행을 갱신한다 => 실수 주의! (like DELETE)

1) WHERE 생략하고 UPDATE

mysql> select * from users;
+----+-------------+----------+
| id | email       | password |
+----+-------------+----------+
|  1 | a@gmail.com | 1234     |
|  2 | b@gmail.com | 1234     |
+----+-------------+----------+
2 rows in set (0.00 sec)

mysql> UPDATE users SET email='ss';
Query OK, 2 rows affected (0.01 sec)
Rows matched: 2  Changed: 2  Warnings: 0

mysql> select * from users;
+----+-------+----------+
| id | email | password |
+----+-------+----------+
|  1 | ss    | 1234     |
|  2 | ss    | 1234     |
+----+-------+----------+
2 rows in set (0.00 sec)

2) 특정 조건의 값만 UPDATE (WHERE)

mysql> UPDATE users SET email='a@gmail.com' WHERE id=1;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from users;
+----+-------------+----------+
| id | email       | password |
+----+-------------+----------+
|  1 | a@gmail.com | 1234     |
|  2 | ss          | 1234     |
+----+-------------+----------+
2 rows in set (0.00 sec)

3) 두 구문을 한번에 UPDATE 하기

mysql> UPDATE users SET email='hello@gmail.com', password='777' WHERE id=2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from users;
+----+-----------------+----------+
| id | email           | password |
+----+-----------------+----------+
|  1 | a@gmail.com     | 1234     |
|  2 | hello@gmail.com | 777      |
+----+-----------------+----------+
2 rows in set (0.00 sec)

profile
🍎 🍊 🍋 🍏 🍇

2개의 댓글

comment-user-thumbnail
2021년 3월 20일

화이팅!!!

1개의 답글