코드 가독성과 작성 규칙

Suhyeon Lee·2024년 10월 2일
0

가독성이 좋은 코드를 작성해야 하는 이유: 가독성 좋은 코드의 여러 가지 이점

  • 유지 보수 용이성
    • 가독성이 높은 코드는 코드를 수정하거나 유지보수하는 데 드는 시간과 노력이 훨신 적다.
    • 코드를 쉽게 이해할 수 있으므로 버그를 찾고 수정하는 것도 쉽다.
    • 어느 누가 코드를 봐도 기능을 한 눈에 파악할 수 있으면 기능 개선과 에러 수정을 쉽게 할 수 있음 → 가독성이 중요한 가장 강력한 이유!
  • 협업 용이성(의사소통의 원활)
    • 가독성이 좋은 코드는 여러 사람이 함께 작업할 때 협업하기 쉬움
      (다른 사람이 작성한 코드를 빠르게 이해하고 수정할 수 있기 때문)
    • 데이터 분석가는 협업을 많이 하니 특히 중요한 이점
    • 에러를 발견하기 쉽고, 결과를 예상하기 쉬움
    • 내가 발견하지 못해도 다른 사람이 쉽게 읽고 피드백해주기 좋음
    • 코드 가독성이 좋으면 일일히 코드를 설명하지 않아도 됨
  • 성능 개선
    • 가독성이 좋은 코드는 더 효율적이며 성능이 더 좋다.
      (코드를 더욱 간결하게 작성하고 불필요한 코드를 제거하기 때문)
  • 코딩 스타일 표준화
    • 가독성이 좋은 코드는 일관된 코딩 스타일을 유지하기 쉽다.
    • 표준화된 코딩 스타일은 코드의 가독성을 향상시키고, 일관성을 유지하며, 코드를 더 쉽게 이해할 수 있도록 한다.
  • 작업 시간 감소

클린 코드(Clean Code)

  • 읽기 쉽고 이해하기 쉬운 코드 작성
  • 프로그램의 동작을 보장하는 것뿐만 아니라, 코드 자체가 가독성이 뛰어나고 유지 보수가 쉽도록 작성되어야 한다는 원칙에 기반함

클린 코드가 중요한 이유

  • 코드의 품질로 인해 발생할 수 있는 다양한 문제 예방
  • 버그 수정, 유지 보수 작업 등을 생각하면 지저분한 코드, 스파게티 코드 피하고 품질을 높이는 게 더 비용이 적게 발생함
    • 나중에 수정하느라 훨씬 더 많은 비용이 발생할 수 있음
  • 간결하고 명확한 클린 코드는 버그를 찾기 쉽게 만듦
    • 복잡하고 난해한 코드는 오류 발생하기 쉽고 수정도 어려움
  • 가독성이 높고 유지 보수가 용이한 코드는 개발 속도를 향상시킴
    • 코드를 이해하고 수정하는 데 걸리는 시간이 줄어 새로운 기능을 빠르게 구현, 배포 가능

클린 코드 주요 원칙

  1. 의미 있는 변수와 함수 사용
  2. 가독성 좋은 코드 만들기
    • 의미 있는 변수명, 함수명, 클래스명 등을 사용해 코드의 의도를 명확하게 전달
    • 다른 사람이나 나중에 자신이 읽기 쉽게 작성
  3. 주석을 필요할 때 잘 활용하기
  4. 간결한 코드 유지하기

Good Practice of SQL

Avoid using Astarik(*)

  • 테이블에 컬럼 수가 많을 때 astarik를 쓰면 실제 쿼리에 필요 없는 컬럼까지 색인하게 되어 쿼리 성능이 떨어질 수 있음
  • 코드의 목적을 파악하기 어려움(어떤 컬럼을 확인하고자 추출하려 했는지 모르니까)
    • 쿼리를 수정해야 하는지, DTO(Data Transfer Object)을 손봐야 하는지 헷갈림

Table ALIAS

  • FROM절에 여러 테이블을 사용하는 경우 alias 선호
    • 가독성 좋음, 다른 테이블에 같은 컬럼명이 있을 경우 혼란 방지

별칭(ALIAS) 사용 방법, 규칙

  • Alias == 별칭

    • 컬럼, 테이블, 함수, 서브쿼리의 이름을 다른 이름(별칭)으로 표시해 주는 것
    • 복잡하거나 긴 이름과 형식을 쉽게 바꿔 표현할 때 사용하거나 눈에 띄게 표현해야 할 때 사용
  • Alias 사용 방법

    • 예약어: AS
      • 띄어쓰기 혹은 큰따옴표(")로도 대체 가능
-- Column(열), 함수, 서브쿼리
SELECT 컬럼명 AS 별칭
FROM 테이블명
;
 
SELECT 컬럼명 별칭
FROM 테이블명
;
 
SELECT 컬럼명 "별칭"
FROM 테이블명
;
 
-- 테이블
SELECT 컬럼명
FROM 테이블명 AS 별칭
;
 
SELECT 컬럼명
FROM 테이블명 별칭
;
 
SELECT 컬럼명
FROM 테이블명 "별칭"
;
  • 규칙
    • 현재 사용하는 SELECT문에서만 적용된다.
    • AS, 띄어쓰기, 큰따옴표 혼용 가능
    • 특수문자, 공백 가용 여부
      • 큰따옴표 안에 넣으면 특수문자, 공백 사용 가능
  • 이름 변경과의 차이점
    • 이름 변경은 새로운 이름으로 바꿔서 저장하지만 별칭은 해당 SELECT문에서만 표시됨

EXISTS, NOT EXISTS than IN, NOT IN

  • EXISTS는 해당 서브쿼리에 해당하는 값이 하나라도 있으면 검색을 멈추지만 IN은 모든 인덱스를 검색하기 때문에 성능 상 차이가 있음
  • 동일한 맥락으로 검색하는 경우가 아니라면 LIKE 보다는 항등연산자(=) 사용이 바람직하다는 의견 → 큰 차이가 없다는 의견도 있음(LIKE vs Equal(=))
    • LIKE 연산자는 문자 하나씩 비교하는 형태로 작동하고, 이로 인해 등호 연산자와는 완전히 다른 결과가 나올 수 있다고 함(MySQL 공식 문서)

가독성 있는 쿼리 작성하기

  1. 예약어
  • SELECT, FROM 등은 따로 정의하지 않은 예약어는 모두 대문자로 작성
  • 함수도 대문자로 작성
# Good
SELECT
  col1,
  col2
FROM 
  Table
WHERE 
  condition
;
  1. 변수 이름
  • 소문자와 언더바를 사용하는 snake_case 사용
  • WITH 문의 CTE도 마찬가지로 snake_case를 사용
# Good
WITH base AS (
  SELECT
    first_name,
    second_name
  FROM 
    Table
)

SELECT
  first_name,
  CONCAT(first_name, second_name) AS full_name
FROM 
  base
;
  1. 명시적인 표현
  • AS
    • 변수나 테이블 이름에 별칭을 지정할 경우 AS를 생략할 수 있지만, AS를 적는 편이 명시적으로 읽기 좋음
  • GROUP BY, ORDER BY 1
    • GROUP BY와 ORDER BY 뒤에 컬럼 이름을 작성하지 않고 1, 2, 3 등을 사용하면 빠르게 작성할 때는 유용하지만 명시적이지 않음
  1. 코드 블럭
  • 쿼리문의 한 줄마다 하나의 컬럼만 존재하는 것이 좋음
  • 다만 요소가 하나인 경우엔 한 줄에 작성해도 어느 정도 받아들일 수 있음
# Good
WITH base AS (
  SELECT
    first_name,
    second_name
  FROM 
    Table
  WHERE
    first_name = "Byeon"
    AND user_id = 123
)

SELECT
  first_name,
  CONCAT(first_name, second_name) AS full_name
FROM 
  base
;
  
# Acceptable
WITH base AS (
  SELECT
    first_name,
    second_name
  FROM Table
  WHERE
    first_name = "Byeon"
    AND user_id = 123
)

SELECT
  first_name,
  CONCAT(first_name, second_name) AS full_name
FROM base
;
  1. 콤마
  • 콤마를 앞에 두는 경우 : Leading Comma
    • 주석 처리가 한번에 된다는 장점
  • 콤마를 뒤에 두는 경우 : Trailing Comma
    • 컬럼의 마지막에 콤마가 있으면 에러가 발생하는 경우가 있어 주의 요망
  1. 들여쓰기(Indent)
  • 탭 한번(띄어쓰기 기준 2번)을 사용
  • 쿼리문이 중첩되는 경우, 전체적으로 한번 들여써주기
WITH base AS (
  SELECT
    id,
    first_name,
    second_name
  FROM user
), favorite_food AS (
  SELECT
    user_id,
    food_id,
    food_name
  FROM food
)

SELECT
  base.id AS user_id,
  food.food_id AS food_id,
  food.food_name AS food_name
FROM 
  base 
LEFT JOIN favorite_food AS food
ON base.id = favorite_food.user_id
;
  1. WITH
  • WITH 문을 사용하면 가독성 있는 쿼리를 작성할 수 있음

SQL 작성 규칙

  • SQL에서 가장 중요한 것
    1. 유지보수가 좋게 작성
    2. 누구나 알아볼 수 있어야 함
  • 나중에 보기 편하게 하려면 표준 SQL 작성 규칙을 정해야 함

1. 적용 순서

  • 작성 순서와 작동 순서가 다르니 주의: 아래 순서와 같이 작성, 숫자 순대로 작동
SELECT 5
FROM 1
WHERE 2
GROUP BY 3
HAVING 4
ORDER BY 6
LIMIT 7
OFFSET 8
  1. FROM절에서 어느 테이블에서 가져오는지 확인 및 JOIN 처리
  2. WHERE절에서 조건에 맞게 설정
  3. GROUP BY절에서 어느 항목으로 묶을 것인지 설정
  4. HAVING절은 GROUP BY 사용 시 조건을 거는 것(GROUP BY로 묶인 뒤 조건 설정)
  5. SELECT절은 조건에 맞게 가져올 컬럼(필요한 컬럼)들을 적음
  6. ORDER BY절은 조건에 맞게 가져온 SELECT문을 정렬
  7. LIMIT는 처리된 SQL문에서 몇 개만 가져올 것인지 설정
  8. OFFSET은 어디서부터 가져올 것인지 설정

2. 작성 규칙

기초 작성 규칙

  • 대문자를 기본으로 하며 알아보기 쉽게 각 단을 내려 작성
SELECT
  USER_ID
FROM
  TB_USER
WHERE
  USER_ID = 1;

주석 작성 규칙

  • 유지 보수를 위해 어떤 사람이 작성하였고 어느 용도로 SQL문이 작성 되었는지 작성
/*사용자, 사용자 정보 조회, 홍길동*/
/*SELECT.TB_USER.USER_INFO.001*/
  • 상단에는 업무 정보에 대한 주석, 하단에는 SQL문에 대한 설명을 넣음
  • 업무정보 주석 예시
업무 파트서비스하고자 하는 로직작성한 개발자 명
업무 영억을 식별할 수 있는 구체적 용어얻고자 하는 결과를 입력작성한 개발자
예시 : 사용자, 주문, 지불, 배송예시 : 사용자 정보 조회예시 : 홍길동
X : 지불사용자X : 주문구매자공통조회
  • SQL 설명 주석 예시
SQL 명렁어사용하는 테이블SQL 용도
SQL 명령어사용하는 주 테이블SQL의 용도
예시 : SELECT예시 : TB_USER예시 : USER_INFO

공통 작성 규칙

  • 옵티마이저(Optimizer)가 실수하지 않도록 하고 다른 사용자가 알아보기 쉽게 하기 위함
  1. 문자는 대문자로 사용
  2. TAB 사용 지양
  3. Alias 항상 작성
  4. 유지보수가 용이하게 ,를 앞에 붙이기

옵티마이저(Optimizer)
→ SQL의 실행 계획을 수립하고 SQL을 실행하는 데이터베이스 관리 시스템의 소프트웨어
→ SQL을 어떻게 실행할 것인지 SQL 실행 계획(Execution Plan)을 수립하고 SQL을 실행
→ 동일한 결과가 나오는 SQL도 어떻게 실행하느냐에 따라서 성능이 달라지기에,
SQL 성능에 있어 옵티마이저는 아주 중요한 역할을 함

Alias 작성 규칙

  • FROM절에서 기술한 테이블에 알파벳 순서대로 부여
  • SELECT절에 사용된 스칼라 서브쿼리의 경우 L,M,N,..... 순서대로 부여
  • WHERE절에 사용된 상관 서브쿼리의 경우 X,Y,Z 순서대로 부여
  • FROM절에 사용한 인라인 뷰의 경우 알파벳 순서대로 부여

스칼라 서브쿼리? 상관 서브쿼리? 인라인 뷰?
→ 사용된 위치에 따라 서브쿼리 명칭을 다르게 부르는 것
→ SELECT절의 경우 스칼라 서브쿼리, FROM절의 경우 인라인 뷰, WHERE절에 경우 상관 서브쿼리라 부름

3. 작성 예시

/*사용자, 사용자 구매정보 조회, 홍길동*/
/*SELECT.TB_USER.USER_INFO.001*/            
SELECT
   A.USER_ID
   , A.USER_EMAIL
   , (
       SELECT
          L.IMG_URL
       FROM
          TB_IMG L
       WHERE
          L.USER_ID = A.USER_ID
   ) AS USER_IMG
   , CASE
       WHEN B.PAID_YN = 'Y' THEN '지불'
       ELSE '미납'
     END AS PAID
FROM
   TB_USER A /* 회원 */
   INNER JOIN TB_ORDER B /* 구매 */
WHERE
   A.DEL_YN = 'N'
   AND A.USER_ID = 1
   AND NOT EXISTS (
                SELECT
                   1
                FROM
                   TB_REFUND X /* 환불 */
                WHERE
                   A.USER_ID = X.USER_ID
                  ) /* 환불 여부 체크 */;
profile
2 B R 0 2 B

0개의 댓글