코드프레소 백엔드 개발자 양성 과정

삼진 논리

참인 값, 거짓인 값, 모르는 값을 연산하는 과정에 대해 알아보고 SQL에 응용해본다.

H Lee
5 min readMar 22, 2020
Image by Alexas_Fotos from Pixabay

수학 시간에 표면적으로나마 배웠던 논리 연산을 코드프레소 데이터베이스 수업 시간에 맞닥뜨렸다. 이론적으로는 흥미롭다고 생각했지만 쓸모는 없다고 생각했던 것이 알고 보니 중요한 것이었다. 진릿값이 세 개인 삼진 논리에 대해 알아보고 데이터베이스 조회에 논리 연산을 접목해본다.

삼진 논리란?

참이나 거짓 두 값만 존재하는 이진 논리 혹은 불 논리(Boolean logic)와는 달리, 삼진 논리 체계에는 참인 값, 거짓인 값, 그리고 미지의 값이 있다. 미지의 값이란 문자 그대로 알 수 없는 값이거나 표현할 수 없는 값을 말한다.

이 세 종류의 값을 가지고 AND, OR, NOT 연산을 하면 다음과 같은 진리표가 도출된다. 참은 T, 거짓은 F, 알 수 없음은 U로 표기한다.

T & T = T   T & U = U   T & F = F
U & T = U U & U = U U & F = F
F & T = F F & U = F F & F = F

T | T = T T | U = T T | F = T
U | T = T U | U = U U | F = U
F | T = T F | U = U F | F = F
!T = F !U = U !F = T

여기서 눈여겨 보아야 할 점은 두 미지의 값 사이에선 어떤 논리 연산을 적용해도 미지수가 나온다는 것이다. 우리가 알지 못하는 값이라도 알고 보면 같은 값일 수도 있지 않을까 생각할 수도 있지만, 결론적으로는 우리가 그 두 미지의 값이 같은지 알지 못한다. 그래서 결과는 다시 미지수이다. 마찬가지로 미지의 값에 부정 연산을 해도 다시 미지의 값이 나온다.

삼진 논리에서는 미지수라는 진릿값이 하나 더 추가됨으로써 이진 논리에 비해 도출 가능한 이항 연산 결과가 늘어났음을 볼 수 있다. 그래서 이진법의 0과 1만이 아닌 0, 1, 2로 정보를 처리하면 계산 속도도 빠르고 더욱 소형화된 삼진법 반도체도 개발할 수 있다고 한다.

논리 연산의 응용

하지만 내 수준에서 반도체 개발은 어렵고, 위의 삼진 논리를 SQL에서 재발견한 것만으로도 충분히 경이로웠다. SQL에서 저 논리 연산을 잘만 이용하면 동적 조회문을 사용하지 않고도 SQL을 동적으로 만들 수 있기 때문이다. 무슨 뜻인지 예시를 보자.

예를 들어, 아래와 같은 인터페이스에서 아무 조건을 선택하지 않고 조회를 요청했다고 하자. 직관적으로, 많은 사용자들이 검색할 때 전체 결과를 받겠다는 의미로 아무 조건을 적용하지 않고 검색한다.

강동구청 웹사이트

하지만 이런 조회문은 빈 값인 NULL로 처리되어 뒷단에 도달하면 일치하는 값이 없다고 뜨기 마련이다. 이런 경우, 개발자는 두 가지 대처를 할 수 있다.

첫째, 각 조건이 지정되거나 지정되지 않을 모든 경우의 수를 고려해 나올 수 있는 모든 조합의 조회문을 작성해둔다. 위의 경우처럼 조건 설정을 세 가지만 할 수 있을 때에도 사용자가 취할 수 있는 총 여덟 가지 조합(조건 1만 설정, 조건 2만 설정, 조건 3만 설정, 모두 설정, 모두 미설정, 조건 1과 2만 설정, 조건 1과 3만 설정, 조건 2와 3만 설정)을 손수 코딩해줘야 한다. 초기 작성 시나 유지 보수 시 이보다 더 비효율적일 수가 없다.

둘째, 위 같은 상황에 유연하게 대처하기 위해 동적 SQL을 이용하면 된다. 하지만 나는 동적 SQL을 모른다.

그렇다고 해서 포기해야만 하는 것은 아니다. SQL이 삼진 논리를 기반으로 하는 언어라는 것을 알고 이용한다면 동적 쿼리문 없이도 상황별 분기 처리를 해낼 수 있다.

table_1이라는 테이블에서 col_1이라는 열의 내용을 조회하는데, 사용자 측에서 검색어가 매개 변수로 전달되면 그것을 이용하고, 아무 단어도 전달되지 않고 NULL이 오면 열 전체를 조회하도록 해주는 예시를 보자.

SELECT *
FROM table_1
WHERE col_1 LIKE @Param_1 + '%'
OR @Param_1 IS NULL;

WHERE 절의 첫 부분에서는 LIKE 연산자로 들어온 키워드를 이용해 관련 있는 결과를 모두 조회한다. 여기까진 특별할 게 없다.

WHERE 절의 뒷부분에서는 매개 변수로 NULL이 들어오면 IS NULL을 이용해 NULL IS NULL, 즉 결과가 항상 참인 등호를 만들어준다. 그러면 선행하는 조회문SELECT * FROM table_1이 긍정되어 전체 조회가 이루어지는 것이다.

여기서 삼진 논리 연산의 요소는 두 가지가 있다.

첫째, 매개 변수로 들어온 NULL을 등호를 이용해 = NULL로 받지 않았다는 점이다. SQL에서 NULL은 미지수인데, 앞서 보았듯 두 미지수로 논리 연산을 했을 때 그 값이 참인지 거짓인지 알 수 없다. 마찬가지로 NULL = NULL이라는 공식도 성립하지 않는다. (이럴 때 등호의 역할을 하라고 있는 것이 IS NULL이다.)

둘째, WHERE 절의 앞부분과 뒷부분을 OR로 연결하여 둘 중 어느 항이라도 참이면 참이 반환되도록 했다는 점이다. 매개 변수로 검색 키워드가 들어오면 첫 항에서 참이 반환되어 뒤의 항의 결과와 무관하게 참이 반환된다. 뒤의 항만 참인 경우도 마찬가지이다. 위의 진리표와 일치하는 양상이다.

논리 연산 같은 걸 배워서 어디에 쓰나 했는데 이런 데 접목된다는 게 놀랍다. 삼진 논리도 더 깊게 파보고 싶다.

참고 : Stack Overflow, Modern SQL

--

--

No responses yet