전체 글 361

자주 사용하는 정규식 총 정리!

정규식 정규식(Regular expressions, Regex)는 문자열에서 문자열을 검색, 치환을 위한 용도로 사용합니다. 예를 들어, 어떤 문자열이 "name: {text} email: {text} address: {text} phone: {number}" 구조인지 확인해야 한다고 가정합니다. 심지어 name은 알파벳이어야 하고, email에서는 @와 .을 허용하고, phone은 숫자여야 하는 등을 구현하려면.. 구현하는 것도 일이고 알아보기도 힘들겁니다. 정규식을 사용하면 이를 간결한 코드로 해결할 수 있을 뿐 아니라, 정규식을 사용하면 생각보다 다양한 것을 할 수 있습니다. 예시 abc 간단한 문자열을 정규표현식으로 사용하면 해당 문자열들을 선택할 수 있습니다. abcaabcaaabc a.c '...

Language/Algorithm 2022.03.26

Javascript - DB 초성으로 검색하기! (+ Performance, 함수형, ...)

초성 검색 프로젝트를 진행하면서 DB에 저장된 name을 초성으로 검색하는 기능을 개발하게 되었습니다. 그런데, 관련 기능을 검색해봤는데 검색 결과가 전부 마음에 들지가 않더라구요.. 초성이라는 것 자체가 한글이니까 국내 자료밖에 없었고 구 시대 자료밖에 없었는데, 코드(또는 SQL)이 비효율적인 측면이 너무 많았고, 유지보수 측면에서도 너무 안좋아서 직접 구현했습니다. 비즈니스 로직은 아래와 같습니다. 입력 값이 전부 초성인지 확인한다. 초성으로 name을 DB에서 검색한다. 1. Map 정의 먼저 Javascript의 Map을 아래와 같이 정의합니다. 보통 배열을 사용해서 ㄱ,ㄴ,ㄷ,ㄹ,ㅁ 등을 저장하던데 하나씩 탐색하니까 시간 복잡도가 많이 낭비됩니다. Set이나 Map을 사용하는 것이 훨씬 유리합..

Sequelize - fn(), literal(), col(), where() 잘 사용하기!

Sequelize.fn()Sequelize.fn()을 사용하면 sql 함수를 쉽게 사용할 수 있습니다. 예시를 몇개 들겠습니다.// SUBSTR(str, pos);sequelize.fn("substr", str, pos);// IFNULL(a, b);sequelize.fn("ifnull", a, b);// SUM(a, b);sequelize.fn("sum", a, b);// CONCAT(a, b);sequelize.fn("concat", a, b);첫 번째 파라미터로는 함수명을, 두 번째 파라미터부터는 대상을 지정하면 됩니다.function fn(fn: string, ...args: unknown[]): Fn;SELECT에서 사용할 때는 아래와 같이 사용할 수 있습니다. attributes를 배열로 정의..

Server/Node.js 2022.03.25

Sequelize - SubQuery를 FROM 절에서 사용하기(?)

Sequelize - SubQuery in From clause SQL 함수를 SELECT 절에서 계산된 결과를 WHERE절 조건식에 넣고 싶은 경우가 간혹 있습니다. 예를 들면 아래의 경우 입니다. SELECT * FROM (SELECT CONCAT(first_name, ' ', last_name) AS fullName FROM user) WHERE full_name LIKE '%david%'; 그래서 공을 들여 관련 내용을 어떻게든 찾아봤는데... 결론부터 말씀드리면, 안타깝게도 할 수 없습니다! 아래 이슈를 보시면 많은 분들이 원함에도 불구하고, 해당 기능을 사용할 수 없습니다. https://github.com/sequelize/sequelize/issues/5354 따라서, 아래의 선택들이 있..

Server/Node.js 2022.03.25

MySQL - WHERE 절에서의 인덱스 사용 (+인덱스를 사용하지 않는 쿼리)

Index In Where clause SQL문 튜닝에 있어서 Where절은 중요합니다. SQL문은 Where절이 가장 먼저 실행되고 Where절을 어떻게 설계하냐에 따라 Index를 활용한 조회를 하지 않고, 무식한 Full Scan을 할 수도 있기 때문입니다. 개발자 분들이 흔히 놓칠 수 있는 인덱스를 안타는 Where절 예시와 튜닝에 대해 포스팅했습니다. LIKE '%_ ' 또는 LIKE '%_%' 문자열을 검색할 때 LIKE절을 많이 사용합니다. 그런데 인덱스를 타고 있지 않을 수도 있습니다. EXPLAIN SELECT * FROM employees WHERE first_name LIKE "David%" 이 경우에는 인덱스를 잘탑니다. 하지만 아래의 경우들에는 인덱스를 잘 타지 않습니다. EXPL..

Database/SQL 2022.03.20

MySQL - 쿼리 성능(실행 시간, CPU 사용량 등) 확인하는 방법 [Profiling]

MySQL Profiling MySQL에서 실행한 쿼리들이 각 수행 시간이 얼마가 걸렸는지 확인할 수 있는 기능으로 쿼리 프로파일링(Query Profiling)을 제공합니다. profiling 설정을 활성화하면 앞으로 실행되는 모든 쿼리문의 수행 시간을 기록합니다. profiling 속성은 적지 않은 부하를 생성하기 때문에, 기본값으로는 OFF로 되어있습니다. Profiling 옵션 확인 Profiling 옵션의 활성화 여부는 다음과 같이 확인합니다. SELECT @@profiling; 결과 값이 1이면 ON, 0이면 OFF 입니다. 활성화 쿼리 프로파일링을 다음과 같이 활성화합니다. SET profiling=1; 그리고 다시 SELECT @@profiling;으로 조회를 해보면 아래와 같이 활성화가 ..

Database/SQL 2022.03.20

SQL 튜닝 - SELECT 절과 WHERE 절에 동일한 함수가 사용될 때 [성능 비교]

1번? 여러번? SELECT 절에 있는 함수를 WHERE 절에도 사용하면서 그런 생각이 문득 들었습니다. "설마, 함수를 두 번 호출해서 계산하는건 아니겠지..? 그럼 낭비잖아!" SELECT emp_no, CONCAT(first_name, ' ', last_name) AS full_name FROM employees WHERE CONCAT(first_name, ' ', last_name) LIKE '%Robert%'; 찾아본 결과, 쿼리를 날리면 Oracle은 라이브러리 캐시, MySQL은 쿼리 캐시에 쿼리 결과를 캐싱해서 재사용한다고 합니다. (소프트 파싱) -> 하지만, 라이브러리 캐시, 쿼리 캐시는 1개의 완성된 쿼리 단위로 동작합니다. 즉, WHERE절에서 나온 결과를 SELECT절에서 재사용하..

Database/SQL 2022.03.17

Java 8 - 새로운 Date & Time 정리 (Zoda-Time) [Instant, LocalDate, Duration ...]

Joda-Time Java 8 이전에는 Date 관련 API들이 가지는 문제들을 해결하기 위해서, Joda-Time 이라는 라이브러리를 사용했습니다. 그래서 Java 8부터는 Joda-Time이 자바 표준 라이브러리로 들어왔습니다. Joda-Time는 다음과 같은 클래스를 지원합니다. Instance LocalDate & LocalTime DateTime Duration & Period ... 기존 Date 관련 API의 문제점 Java 8 이전에 사용하던 Date 관련 클래스는 Date, Calander, SimpleDateFormat 등이 있습니다. 하지만 많은 문제가 있어서, 자바 8 버전 이후 부터는 새로운 날짜 관련 API들을 제공합니다. 기존 클래스들의 문제입니다. 1. 부적절한 클래스, 메소..

Language/Java 2022.03.16

JPA - 영속성(persistence란) [+1차 캐시]

영속성 Spring JPA 로고를 보면 영속성(persistence)라는 단어가 크게 그려져 있습니다. 그만큼, 영속성 없이 Spring JPA를 얘기하기 힘듭니다. 영속성은 쉽게 말하면 지속을 의미합니다. 더 자세히 풀자면, 엔터티를 사용하고 바로 폐기하는 것이 아니라, 저장을 해서 지속적으로 사용하며 얻는 이점을 얻는 것을 말합니다. 예를 들어, JPA에서 repository.findOne을 동일한 데이터에 대해 조회를 5번 요청합니다. 하지만, DB의 쿼리 로그나 JPA가 기록한 로그를 보면, SELECT문이 1번만 실행됩니다. 그 이유가 영속성입니다. 첫번째 SELECT한 결과를 JPA의 1차 캐시에 보관하고 계속 재사용하기 때문입니다. 1차 캐시 JPA에서 1차 캐시는 EntityManager가..

Server/Spring JPA 2022.03.15

Java 8 - Optional이란?

Optional Optional은 Null 검사를 기존의 번거로운 방법에서 벗어나기 위해 Java 8 버전부터 제공하는 클래스입니다. Optional는 T타입의 객체를 포장합니다. Optional을 사용하면 T타입 객체가 null일때 결과를 핸들링하거나, null이 아니라 비어 있는 Optional을 반환해서 NullPointerException을 방지할 수 있습니다. 문제 (예시) ThreadLocal이라는 클래스가 있다고 가정합시다. public class ThreadLocal { DBInfo info; public DBInfo getDBInfo() { return info; } } 만약 아래 코드에서 ThreadLocal.getDBInfo()의 결과가 null이 되면 어떻게 될까요? 많이 발생하는 ..

Language/Java 2022.03.12